I am working on a game and for some reason when I try to call the hit_check() function it won't animate the sprite. all of the other animations have worked perfectly which is why I'm confused.
Heres my script:
extends KinematicBody2D
var motion = Vector2(0,0)
const SPEED = 130
const GRAVITY = 15
const UP = Vector2(0,-1)
const JUMP_SPEED = 350
func _physics_process(delta):
apply_gravity()
hit_check()
jump_check()
move_check()
move_and_slide(motion, UP)
func apply_gravity():
if not is_on_floor():
motion.y += GRAVITY
else:
motion.y = 0
func jump_check():
if Input.is_action_pressed("jump") and is_on_floor():
motion.y -= JUMP_SPEED
func move_check():
if Input.is_action_pressed('left'):
$PlayerAnimation.flip_h = true
$PlayerAnimation.play("walk")
motion.x = -SPEED
elif Input.is_action_pressed('right'):
$PlayerAnimation.flip_h = false
$PlayerAnimation.play("walk")
motion.x = SPEED
else:
motion.x = 0
$PlayerAnimation.play("idle")
func hit_check():
if Input.is_action_pressed("hit"):
$PlayerAnimation.play("hit")
jump_check and move_check functions are called after hit_check function, and move_check function always overrides the current animation of the node because there is an animation specified in both if and else blocks.
Related
im trying to make a 3d fighting game, when i start it the player can move around like normal, but after a few seconds the player just freezes, the animations work fine, but the player will just freeze in place.
i looked through the code a bunch of times but i cant find what's causing it, plz help
Code:
extends KinematicBody
onready var anim = $PlayerANIM/AnimationPlayer
export var speed = 10
const ACCEL = 15.0
const AIR_ACCEL = 9.0
const JUMP_SPEED = 15
var velocity = Vector3.ZERO
var velocity_info = Vector3.ZERO
var current_vel = Vector3.ZERO
var snap = Vector3.ZERO
var gravity = -40
var can_run = true
var dir = Vector3.ZERO
func play_anim(dir):
if anim.is_playing() == false:
anim.play("IDLE")
if Input.is_action_just_pressed("a") or Input.is_action_just_pressed("d") and can_run:
anim.stop()
anim.play("RUN")
if Input.is_action_just_released("a") or Input.is_action_just_released("d") and can_run:
anim.stop()
func _physics_process(delta):
#MOVEMENT
dir = Vector3.ZERO
if Input.is_action_pressed("d") and can_run:
rotation_degrees = Vector3(0,0,0)
if anim.is_playing() == false:
anim.play("RUN")
dir += global_transform.basis.x
if Input.is_action_pressed("a") and can_run:
rotation_degrees = Vector3(0,180,0)
if anim.is_playing() == false:
anim.play("RUN")
dir += global_transform.basis.x
if Input.is_action_just_pressed("Punch") and $PunchTimer.is_stopped():
anim.stop()
anim.play("PUNCH")
$PunchTimer.start()
can_run = false
if Input.is_action_just_pressed("Kick") and $KickTimer.is_stopped():
anim.stop()
anim.play("KICK")
$KickTimer.start()
can_run = false
if Input.is_action_just_released("a") or Input.is_action_just_released("d"):
anim.stop()
if Input.is_action_just_pressed("space") and is_on_floor():
#velocity.y = 15
anim.play("ROLL")
$RollTimer.start()
var target_vel = dir * speed
var accel = ACCEL if is_on_floor() else AIR_ACCEL
current_vel = current_vel.linear_interpolate(target_vel, accel * delta)
velocity.x = current_vel.x
velocity.z = current_vel.z
velocity.y += gravity *delta
move_and_slide_with_snap(velocity, snap, Vector3.UP, true, 4, deg2rad(45))
play_anim(dir)
func _on_PunchTimer_timeout():
can_run = true
func _on_KickTimer_timeout():
can_run = true
func _on_RollTimer_timeout():
pass
I guess you need to change Input.is_action_just_pressed("action_name") to Input_is_actions_pressed("action_name").
The difference is that first functions returns 'true' only once while you pressing the button (which is good, for example, when you make pistol shooting), and second one returns 'true' all the time you pressing the button.
So, the code I have for a dash function is not working correctly even though im positive the logic is correct. I suspected the problem was with the variable isdashing so I printed out the value for it and comes back false no matter what I do. Can anyone tell me what im doing wrong?
extends KinematicBody2D
export(int) var Jump_Height = -100
export(int) var Jump_Realese = -60
export(int) var gravity = 4
var velocity = Vector2.ZERO
var move_speed = 50
#Jump Stuff
var max_jump = 2
var jump_count = 0
# Dash Stuff
var dash_direction = Vector2(1,0)
var dashable = false
var isdashing = false
# Movement
func _physics_process(delta):
dash()
gravity_control()
if Input.is_action_pressed("ui_right"):
velocity.x = move_speed
elif Input.is_action_pressed("ui_left"):
velocity.x = -move_speed
else:
velocity.x = 0
if is_on_floor() and jump_count != 0:
jump_count = 0
if jump_count<max_jump:
if Input.is_action_just_pressed("ui_up"):
velocity.y = Jump_Height
jump_count += 1
else:
if Input.is_action_just_released("ui_up") and velocity.y < Jump_Realese:
velocity.y = Jump_Realese
velocity = move_and_slide(velocity, Vector2.UP)
func dash():
if is_on_floor():
dashable = true
if Input.is_action_pressed("ui_left"):
dash_direction = Vector2(-1,0)
if Input.is_action_pressed("ui_right"):
dash_direction = Vector2(1,0)
if Input.is_action_just_pressed("ui_Dash") and dashable:
velocity = dash_direction.normalized() * 7000
dashable = false
isdashing = true
yield(get_tree().create_timer(0.2), "timeout")
isdashing = false
It's likely that Input.is_action_just_pressed("ui_Dash") is false because dash() is being called in the physics_process function which doesn't run every frame (it runs 60 times a second).
What currently happens is -
During a game frame, the user presses the dash button. At this point Input.is_action_just_pressed("ui_Dash") is true but nothing has checked it.
A frame or two (or more) later, the dash function is called in the physics_process. This polls if the dash button was just pressed - but now it's false because it was "just pressed" a few frames ago, not on this frame.
The only way your current logic works is if the dash button was pressed in the EXACT frame that the physics_process runs.
You can get around this by using Input.is_action_pressed("ui_Dash") to capture the button press, setting a flag to prevent it being captured on the next physics frame and then enabling it again sometime later. E.g.
var can_dash: boolean = true
func dash():
if is_on_floor():
dashable = true
if Input.is_action_pressed("ui_left"):
dash_direction = Vector2(-1,0)
if Input.is_action_pressed("ui_right"):
dash_direction = Vector2(1,0)
if can_dash and Input.is_action_pressed("ui_Dash") and dashable:
can_dash = false;
velocity = dash_direction.normalized() * 7000
dashable = false
isdashing = true
yield(get_tree().create_timer(0.2), "timeout")
isdashing = false
can_dash = true
You are resetting your variables (especially velocity) before calling move_and_slide().
Solution: Call dash() immediately before calling move_and_slide().
This is the reset I'm referring to:
if Input.is_action_pressed("ui_right"):
velocity.x = move_speed
elif Input.is_action_pressed("ui_left"):
velocity.x = -move_speed
else:
velocity.x = 0
Im making a simple platformer. I have 3 movements that the player can do, run, jump and walk. The walking and jumping functions run fine but I have a problem with the run function, it seems to work but the animation only plays the first frame, which does not happen for any other animation.
extends KinematicBody2D
var speed : int = 200
var jumpforce: int = 500
var gravity: int = 1000
var vel: Vector2 = Vector2()
onready var sprite: Sprite = get_node("Sprite")
onready var anim = get_node("AnimationPlayer").get_animation("walk")
onready var anim2 = get_node("AnimationPlayer").get_animation("run")
func _physics_process(delta):
vel.x = 0
#movement
if Input.is_action_pressed("move_left"):
vel.x -= speed
anim.set_loop(true)
get_node("AnimationPlayer").play("walk")
if Input.is_action_pressed("move_right"):
vel.x += speed
anim.set_loop(true)
get_node("AnimationPlayer").play("walk")
#return to idle
if Input.is_action_just_released("move_right") or Input.is_action_just_released("move_left"):
$AnimationPlayer.play("idle")
#run
if Input.is_action_pressed("move_left") and Input.is_action_pressed("shift"):
vel.x -= speed
anim2.set_loop(true)
get_node("AnimationPlayer").play("run")
if Input.is_action_pressed("move_right") and Input.is_action_pressed("shift"):
vel.x += speed
anim2.set_loop(true)
get_node("AnimationPlayer").play("run")
#physic and jump
vel.y += gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y -= jumpforce
vel = move_and_slide(vel, Vector2.UP)
if vel.x < 0:
sprite.flip_h = true
elif vel.x > 0:
sprite.flip_h = false
Hi Man i am not sure if you still need Help but here is my solution:
extends KinematicBody2D
var speed : int = 200
var jumpforce: int = 500
var gravity: int = 1000
var vel: Vector2 = Vector2()
onready var sprite: Sprite = get_node("Sprite")
func _physics_process(delta):
vel.x = 0
#movement
#run
if Input.is_action_pressed("move_left") and Input.is_action_pressed("shift"):
vel.x -= speed
$AnimationPlayer.play("run")
elif Input.is_action_pressed("move_right") and Input.is_action_pressed("shift"):
vel.x += speed
$AnimationPlayer.play("run")
elif Input.is_action_pressed("move_left"):
vel.x -= speed
$AnimationPlayer.play("walk")
elif Input.is_action_pressed("move_right"):
vel.x += speed
$AnimationPlayer.play("walk")
#return to idle
else:
$AnimationPlayer.play("idle")
#physic and jump
vel.y += gravity * delta
if Input.is_action_pressed("jump") and is_on_floor():
vel.y -= jumpforce
vel = move_and_slide(vel, Vector2.UP)
if vel.x < 0:
sprite.flip_h = true
elif vel.x > 0:
sprite.flip_h = false
The problem was that you had a bunch of if statements and every tick both the run and walk if statements were true. So for example you press left and shift. The walk left if statement is true and the animation gets set to walk. Then the run if statement is also true and your animation gets set to run. The next frame the walk animation if statement is true again which means it gets set to the walk animation again. Then the run animation is true which sets the animation to the run animation but because we are switching the animation it sets the frame to 0 and starts the animation again.
I'm trying to make a 2d platformer in godot with help from one of the the videos. video link: https://www.youtube.com/watch?v=PG0tfoPraE4. I have very little experience working with Godot.
I'm stuck and am not sure what to do, I've tried looking at some more videos as a last resort but all of them use another way of movement.
Here is the code
GDSCRIPT
extends KinematicBody2D
const MOVESPEED = 70
const JUMPFORCE = -200
const GRAVITY = 600
var motion = Vector2()
func _physics_process(delta):
if is_on_floor():
if Input.is_action_just_pressed("ui_up"):
motion.y = JUMPFORCE
if Input.is_action_pressed("ui_left"):
motion.x = -MOVESPEED
$Sprite.flip_h = true
$AnimationPlayer.play("walk")
if Input.is_action_pressed("ui_right"):
motion.x = MOVESPEED
$Sprite.flip_h = false
$AnimationPlayer.play("walk")
else:
motion.x = 0
$AnimationPlayer.stop()
motion.y += GRAVITY * delta
motion = move_and_slide(motion, Vector2(0,-1))
Your code path is falling into the else clause of the right movement. So preventing it to move.
Just add and else to the right if, like:
if Input.is_action_pressed("ui_left"):
motion.x = -MOVESPEED
$Sprite.flip_h = true
$AnimationPlayer.play("walk")
elif Input.is_action_pressed("ui_right"):
motion.x = MOVESPEED
$Sprite.flip_h = false
$AnimationPlayer.play("walk")
else:
motion.x = 0
$AnimationPlayer.stop()
# changed switch statement setup by creating a new variable and using "." operator
# removed extra delta in move_and_slide function
# left off attempting to add gravity to the game
# 2/26/2019
# removed FSM and will replace it with tutorial video code, for sake of completion
extends Node2D
const FLOOR = Vector2(0,-1)
const GRAVITY = 5
const DESCEND = 0.6
var speed = 100
var jump_height = -250
var motion = Vector2()
var jump_count = 0
var currentState = PlayerStates.STATE_RUNNING
var grounded = false
enum PlayerStates {STATE_RUNNING, STATE_JUMPING, STATE_DOUBLE_JUMPING, STATE_GLIDING}
func _ready():
var currentState = PlayerStates.STATE_RUNNING
pass
func jump():
motion.y = jump_height
func glide():
if motion.y < 500:
motion.y += DESCEND
func _process(delta):
var jump_pressed = Input.is_action_pressed('jump')
var glide_pressed = Input.is_action_pressed('glide')
* the code below is where I attempted to count the jumps in order to keep them from surpassing two jumps. My goal is to create a double
jump and so I used the less than operator to control that number*
if jump_pressed:
if jump_count < 2:
jump_count += 1
jump()
grounded = false <-- I had to copy paste this code again, below, so I don't get an error in my question.
if jump_pressed:
if jump_count < 2:
jump_count += 1
jump()
grounded = false
if grounded == false:
if glide_pressed:
glide()
motion.x = speed
motion.y += GRAVITY
motion = move_and_slide(motion, FLOOR)
if is_on_floor():
grounded = true
jump_count = 0
else:
grounded = false
First of all, I think you need to use a KinematicBody2D and perform your logic in _physics_process if you would like to use move_and_slide, other than that, your code was almost working:
extends KinematicBody2D
const FLOOR = Vector2(0,-1)
const GRAVITY = 3000
const DESCEND = 0.6
var speed = 100
var jump_height = 250
var motion = Vector2()
var jump_count = 0
func jump():
motion.y = -jump_height
func glide():
if motion.y < 500:
motion.y += DESCEND
func _physics_process(delta):
var jump_pressed = Input.is_action_pressed('jump')
var glide_pressed = Input.is_action_pressed('glide')
motion.y += delta * GRAVITY
var target_speed = Vector2(speed, motion.y)
if is_on_floor():
jump_count = 0
if glide_pressed:
glide()
if jump_pressed and jump_count < 2:
jump_count += 1
jump()
motion = lerp(motion, target_speed, 0.1)
motion = move_and_slide(motion, FLOOR)
You also need to change the node type to KinematicBody2D in the Godot editor (right click on the node and then on change type).