I'm working on a 2d side scrolling game and i ran into a problem when trying to implement the shooting into the player character, it used to be when shooting while jumping it does not shoot but now whenever I press the jump key the player jumps towards the right even when I'm not activating the direction keys
here is the code
extends KinematicBody2D
const GRAVITY = 20
const SPEED = 200
const JUMP_HIGHT = -550
const UP = Vector2(0,-1)
const SHOOT = preload("res://shoot.tscn")
var motion = Vector2()
var on_ground = false
var is_attacking = false
# warning-ignore:unused_argument
func _physics_process(delta: float) -> void:
motion.y += GRAVITY
if Input.is_action_pressed("right") || is_on_floor() == false:
if is_attacking == false:
motion.x = SPEED
if is_attacking == false:
$Sprite.flip_h = false
$Sprite.play("run")
if sign($Position2D.position.x) == -1:
$Position2D.position.x *= -1
elif Input.is_action_pressed("left") || is_on_floor() == false:
if is_attacking == false :
motion.x = -SPEED
if is_attacking == false:
$Sprite.flip_h = true
$Sprite.play("run")
if sign($Position2D.position.x) == 1:
$Position2D.position.x *= -1
else :
if on_ground == true && is_attacking == false :
$Sprite.play("idle")
motion.x = 0
if Input.is_action_just_pressed("jump"):
if is_attacking == false :
if on_ground == true :
motion.y = JUMP_HIGHT
on_ground = false
if is_on_floor():
if on_ground == false :
is_attacking = false
on_ground = true
else :
if is_attacking == false :
on_ground = false
if motion.y < 0 :
$Sprite.play("jump")
else :
$Sprite.play("fall")
if Input.is_action_just_pressed("shoot") && is_attacking == false:
if is_on_floor() :
motion.x = 0
is_attacking = true
$Sprite.play("attack")
var shoot = SHOOT.instance()
if sign($Position2D.position.x) == 1 :
shoot.set_shoot_direction(1)
else:
shoot.set_shoot_direction(-1)
get_parent().add_child(shoot)
shoot.position = $Position2D.global_position
motion = move_and_slide(motion,UP)
func _on_Sprite_animation_finished() -> void:
is_attacking = false
I think you are going in the wrong direction from the start and I haven't seen anyone in tutorials doing this. You have input checks together with state checks and movement repeatedly. Since you are new you need to write platformer code from scratch many times to experiment and have a feel how code should flow. Do it separately:
# don't use $ for nodes you call often save reference in variable (I'm guessing it's AnimatedSprite)
var sprite:AnimatedSprite = $Sprite
var dir:float = 0.0 #used for movement and sprite flipping
#Limit your code to physics process only for physics related logic
func _physics_process(delta:float)->void:
# get direction input
# math trick to get value -1 to 1 to know how strong go which direction
dir = Input.get_action_strength("move_right") -
Input.get_action_strength("move_left")
#ground check - call function once and use variable
is_grounded = is_on_floor()
# apply speed(use dir to give direction)
motion.x = SPEED * dir
# apply gravity
if !is_grounded:
motion.y += GRAVITY * delta
elif Input.is_action_just_pressed("jump"):
motion.y = JUMP_HIGHT
# apply movement
motion = move_and_slide(motion, Vector2.UP)
# use process for sprites
func _process(delta:float)->void:
#check if direction is not close to 0
if abs(dir) > 0.001:
if dir > 0:
sprite.h_flip = false
else:
sprite.h_flip = true
#state check for sprites
if is_grounded:
if abs(dir) > 0.001:
sprite.play("run")
else:
sprite.play("idle")
else:
if motion.y < 0.0:
sprite.play("jump")
else:
sprite.play("fall")
This will be a better starting ground to implement shooting. seems like you have stopped movement on shooting, so you can interrupt dir before applying speed.
if is_shooting && is_grounded:
dir = 0.0