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)

#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)
lighting.position = \$Position2D.global_position
``````

Thanks!

in Engine

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 ) )
``````
by (244 points)
selected by

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!

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.

by (114 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? ) )`