Topic was automatically imported from the old Question2Answer platform.
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.
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:
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)
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)