0 votes

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.

Godot version 3.4.4
in Engine by (78 points)

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. :D

Hope this helps.

2 Answers

+1 vote

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 objecttomove part and just do position.x

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

by (418 points)
edited by
+1 vote

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)

by (434 points)
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 Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.