-1

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

2 Answers2

1

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
NeZvers
  • 110
  • 7
0

Not sure if this will help, but for my code I had to add and ev.pressed and !ev.is_echo() to all of my if Input statements. Not really sure why, but it prevented the program randomly thinking I was trying to press keys that I didn't want pressed.