0 votes

I'm working on a 2d platformer. You can shoot projectiles in it. When the player is on a wall I want the player to shoot the projectiles in the opposite direction than normal, but I can't get it to work right. Can you help me?

This is the code

extends KinematicBody2D

var motion = Vector2()
var airjump = 0.2
var airtime = 0.2
var cutjumpheight = 0
var aim = 1
var whereaim = -1
var gravity = 60
const WJX = 100
const MOE = 0.2
const CTIME = 0.2
const SPEED = 300
const WALLJUMPHEIGHT = -1125
const JUMPHEIGHT = -750
const UP = Vector2(0,-1)
const LIGHTING = preload("res://LightingAttack.tscn")

#move right and left whenthe arrow keys are presed
func _physics_process(delta):
    #explains self
    motion.y += gravity
    if Input.is_action_pressed("ui_right"):
        motion.x = SPEED
        if sign($Position2D.position.x) == -1:
            $Position2D.position.x *= -1 
    elif Input.is_action_pressed("ui_left"):
        motion.x = -SPEED
        if sign($Position2D.position.x) == 1:
            $Position2D.position.x *= -1
    else:
        motion.x = 0

    # this reverses the position the lighting comes out when on a wall unless the player is on the floor
    if is_on_wall():
        $Position2D.position.x *= whereaim

    #Timer to dimtermine if the player inputed the jump button recently
    airjump -= get_process_delta_time()
    if Input.is_action_just_pressed("ui_up"):
        airjump = CTIME
    #Timer to see if the player was on the floor or wall recently
    airtime -= get_process_delta_time()
    if is_on_floor():
        airtime = MOE

    #slows decent if player is on a wall
    if is_on_wall() && motion.y > 0 &&! is_on_floor():
        gravity = 30
        whereaim = 1
    else:
        gravity = 60
        whereaim = -1

    #Tells the game to jump
    if airtime > 0 && airjump > 0:
        motion.y = JUMPHEIGHT
    if Input.is_action_pressed("ui_up"):
        cutjumpheight -= 0
        if cutjumpheight > 0:
            cutjumpheight = 0
    if Input.is_action_just_released("ui_up"):
        motion.y += cutjumpheight
    if is_on_wall() && Input.is_action_just_pressed("ui_up"):
        if sign($Position2D.position.x) == 1:
            motion.y = WALLJUMPHEIGHT
            motion.x = WJX
        elif sign ($Position2D.position.x) == -1:
            motion.y = WALLJUMPHEIGHT
            motion.x == -WJX

    motion = move_and_slide(motion, UP)
    pass

    if Input.is_action_just_pressed("ui_focus_next"):
        var lighting = LIGHTING.instance()
        if sign($Position2D.position.x) == 1:
            lighting.set_lighting_direction(1)
        else:
            lighting.set_lighting_direction(-1)
        get_parent().add_child(lighting)
        lighting.position = $Position2D.global_position

Thanks!

asked Nov 26, 2018 in Engine by TheAsker (27 points)

2 Answers

0 votes
Best answer

You can conditionaly negate some value without branching with this function:

static func condNegate(x, negate): return (x ^ -negate) + negate

as it works only with integers you need to pass it your bool value and your direction as integers (I guessing that for direction of shooting float is not necessary, but either way):

$Position2D.position.x = condNegate( int( $Position2D.position.x ), int( is_on_wall ) )
answered Dec 3, 2018 by pospathos (236 points)
selected Dec 16, 2018 by TheAsker

Where would I put this?
Thank you!

As in where do I put both of these?

Place this static funcition as separate function in player script (same level of indentation as _process and ready), and call it when you need to conditionaly flip some value. Instead of if is_on_wall(): $Position2D.position.x *= whereaim call condNegate( int( $Position2D.position.x ), int( is_on_wall ) )

extends KinematicBody2D
...
func _physics_process(delta):
...
    $Position2D.position.x = condNegate( int( $Position2D.position.x ), int( is_on_wall ) )
...

static func condNegate(x, negate): return (x ^ -negate) + negate

Thank you very much!

0 votes

Hello,
did you try reflect?
otherwise you can avoid using "if" using this kind of formulation :

var_to_flip *=  -sign( var_something_is_true? ) 
#return -1 if bool = 1, 0 if 0

sorry, this is not a complete answer but got little time.

answered Nov 27, 2018 by Asoth (111 points)

It seems to me that Godot 3.+ does not allows for sing of bool, bool is not anymore equal to integer 1 or 0. But it's not big deal. For people who encounter similar problem just convert bool to int: var_to_flip *= -sign( int( var_something_is_true? ) )

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.