How to flip a value only if something is true?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By TheAsker

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!

:bust_in_silhouette: Reply From: Asoth

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.

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? ) )

pospathos | 2018-12-03 11:41

:bust_in_silhouette: Reply From: pospathos

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

Where would I put this?
Thank you!

TheAsker | 2018-12-16 22:24

As in where do I put both of these?

TheAsker | 2018-12-16 22:31

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

pospathos | 2018-12-16 23:04

Thank you very much!

TheAsker | 2018-12-28 05:12