Enemy Sprite Horizontal Patrol Help

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

Hi,

I’m looking for a simple method to move an enemy sprite right so many pixels, then once reached, go back (left) the same amount… and so on.

All the tutorials I’ve seen appear to use raycasts to determine when the enemy has reached the end of a platform, for me though not all my enemies will reach the end of a platfrom before switching direction.

If I have the distance varible exposed in the Inspector it will allow me to change the length the enemy travels on each instance.

I’m thinking the enemy should be a Kinematicbody2D. But I’m just not sure the best method for moving the enemy a certain distance.

I’ve used Tweening for my moving platforms, but I don’t like the easing in and out and I can’t seem to work out how to get a sprite to move consistantly instead with Tweens.

If you could show some code, it would help my visualise things a lot better.

Thanks.

For one of my games, I used a hack. I didn’t have enough time to program my enemies to use RayCasts and do stuff like that, so I programmed them to flip when they reached a certain Area2D. Since they were going to be in a certain spot anyway, the hack worked. :smiley:

Hope this helps.

Ertain | 2022-06-23 23:29

:bust_in_silhouette: Reply From: Pomelo

if you just want to move something, you just have to change its position (asuming it inherits from Node2d). Lets say you want to move it to the right, then you just go:

var speed = 100

func _procces(delta):
     object_to_move.position.x += speed * delta

Now if you want to do something at a given spot, say at pixel 400 you just make a var amount_to_move = 400 and check:
if object_to_move.position.x == ammount_to_move: do_something()
In do_something you could just change the speed value to -100 for example.

There are many ways to do it, like using Path2D and PathFollow2D, for example, but I gave you a simple awnser to get you going (not that Path2D are difficult to implement) (in fact there are lots of tutorials you can look into)

Hope it helps!

P.D. This is obvious but if the script is on the object you want to move, you just ignore the object_to_move part and just do position.x

edit: use global_position instead of position if you see it fit (depends on your game)

:bust_in_silhouette: Reply From: godot_dev_

I implemented what you wanted to do. Below is the enemy’s script (a kinematicbody2d)

    extends KinematicBody2D

#maximum travel distance before enemy turns aroudn
export (float) var maxTravelDistance = 500

export (float) var horizontalSpeed = 50

var gravityAccel = 150

var floor_normal = Vector2(0, -1) #floor is downward

var facingRight = true

var gravityVelocity = gravityAccel
#keeps track of how much enemy travelled
var distanceTravled = 0

var leftFloorDetect = null
var rightFloorDetect = null
func _ready():
	
	#don't move by default
	set_physics_process(false)
	
	leftFloorDetect = $"left-floor-detector"
	rightFloorDetect = $"right-floor-detector"
	
	#illustrate using the enenmy script's api to start moving
	startMoving()

#returns true when the enemy is at the end of a platform
func reachedEndOfPlatform():
	#the ray casts are on both sides of enemy, so one of them won't be touching the floor when the enemy
	#reaches the edge of a platform
	return  not leftFloorDetect.is_colliding() or not rightFloorDetect.is_colliding()
func startMoving():
	facingRight=true
	set_physics_process(true)
	distanceTravled = 0
	gravityVelocity = gravityAccel #reset gravity 
func _physics_process(delta):
	
	if distanceTravled >= maxTravelDistance or reachedEndOfPlatform():
		#enemy turns around, we reached limit
		distanceTravled = 0
		facingRight = not facingRight
	
	gravityVelocity = gravityVelocity + delta*	gravityAccel #aplpy gravty acceleration
	var velocity = Vector2(horizontalSpeed,gravityVelocity)
	
	distanceTravled =  distanceTravled + velocity.x*delta
	#make sure to mirror horizontal velocity when traveling left
	if not facingRight:
		velocity.x = -1 *velocity.x
	move_and_slide(velocity,floor_normal)

And below is the scene tree setup I used
stage (node2d)

floor (staticbody2d)

CollisionShaped2d

Enemy (Kinematicbody2d)

Sprite
collisionshape2d
left-floor-detector(RayCast2D)
right-floor-detector(RayCast2D)