как запретить моему персонажу прыгать вправо, когда я просто прыгаю?

Я работаю над 2-мерной игрой с прокруткой, и я столкнулся с проблемой при попытке реализовать стрельбу в персонажа игрока, раньше это было при стрельбе во время прыжка, он не стреляет, но теперь, когда я нажимаю клавишу прыжка, игрок прыгает вправо, даже если я не нажимаю клавиши направления

вот код

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

person Ahmed Nasser    schedule 16.01.2021    source источник


Ответы (2)


Я думаю, что вы с самого начала идете в неправильном направлении, и я не видел, чтобы кто-нибудь в руководствах делал это. У вас есть проверки ввода вместе с проверками состояния и многократным перемещением. Поскольку вы новичок, вам нужно много раз писать код платформера с нуля, чтобы поэкспериментировать и почувствовать, как код должен течь. Сделайте это отдельно:

# 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")

Это будет лучшая стартовая площадка для стрельбы. похоже, что вы остановили движение при стрельбе, поэтому вы можете прервать управление перед применением скорости.

   if is_shooting && is_grounded:
       dir = 0.0
person NeZvers    schedule 18.01.2021

Не уверен, что это поможет, но для моего кода мне пришлось добавить and ev.pressed and !ev.is_echo() ко всем моим if Input операторам. Не совсем уверен, почему, но это помешало программе случайно подумать, что я пытаюсь нажимать клавиши, которые я не хотел нажимать.

person that_javascript_girl    schedule 17.01.2021