Enemy help (SOLVED)

Does anyone have any resources or can give me any tips to implement enemy movement. i have an enemy but have no idea where to start

First thing is to ask: what do you want to do?

i want the enemy to walk from one side of the screen and when it reaches the one side of the screen it switches direction and walks to the other side

Then I’d say the first step is to learn how to move an object.
What tutorials have you completed so far?

We have a number of tutorials here

2 Likes

I looked through the tutorials and i get how to make the character move if its player controlled through input but i dont know how i would make a character that isnt controlled by inputs to move

How to get a position of a game object:

How to set a position of a game object:

The lifecycle functions are described below, and the one you are interested in is update(self, dt). Like the name implies, this updates every frame. dt is the time taken since the last frame. Since the enemy is always supposed to be moving, it makes sense to use a function that updates every frame (as opposed to on input, which makes sense for a player controlled object).

A direction might be defined like this (this would be movement to the right):

self.direction = vmath.vector3(1,0,0)

A speed is a scalar (i.e. just a number, like 12, as opposed to a direction which is a vector). So that might be:

self.speed = 100

If you’ve found out the position of the game object, you could add to it like so:

position = position + self.direction * self.speed * dt

Multiplying self.speed by dt means that your speed variable represents pixels per second. If you don’t multiply, it means pixels per frame. That would be bad, because frames can take different amounts of time.

You would then use go.set_position() to apply the new position to the game object.

Finally, you need to do something about the boundaries. For example, if the game object is to move between 0 and 500, then you could check the right boundary like this:

if position.x > 500 then

end

What would you do with that information? Well, you would ensure that the x value in self.direction is -1 instead of 1, so that the enemy moves to the left instead of to the right. You would of course have to do a similar thing for the left boundary.

These are the tools you need to make one type of very basic movement. Spend some time experimenting and see if you can get it to work!

5 Likes

Have you checked the movement examples?

And others in the same category.

1 Like
move_speed = 90

function init(self)
	position = go.get_position() 
	self.direction = vmath.vector3(0, 0, 0)
	
end


function update(self, dt)
	pos = position + self.direction * move_speed * dt 
	if pos.x > 900 then
		position = position + vmath.vector3(-1, 0, 0)
	elseif pos.x < 70 then
		position = position - vmath.vector3(1, 0, 0)
	end
	go.set_position(pos)
end


Thanks @Alex_8BitSkull your comment really helped, but i was stuck on the fact that i cant get my enemy moving without having a 1 in vmath in the init function and when i do put a 1 the rest of the code just messes up

So, there are a few issues here, but the main one is to do with the direction and boundary checking.

You do need a 1 in the direction vector. By setting it to 0, you’re basically multiplying speed by 0 in your first line in update. So that line doesn’t do anything.

In your boundary checking conditionals, you should be changing the direction, not modifying the position. By that I mean setting the x value of self.direction to 1 or -1.

I would change move_speed to be a self variable like self.direction. The way you’ve defined move_speed means it’s a global variable. If you have a move_speed in any other script in your game, one of the values will overwrite the other.

I suggest you read this manual on scoping and try to start using local variables where appropriate:

In a similar vein, you’ve actually created a global position variable in init. I would get rid of that. Instead, create a local position variable in update and get the game object’s position each frame. Get rid of the pos variable altogether.

4 Likes

What do you mean get rid of pos

You have two variables for the position: pos and position. You only need one. Create a local variable in update and use that, rather than two different variables.

3 Likes

I did the changes and it worked until it reahed the right side of the screen then the enemy just disappeared


function init(self)
	self.direction = vmath.vector3(1, 0, 0)
end


function update(self, dt)
	self.Espeed = 90
	position = go.get_position() 
	position = position + self.direction * self.Espeed * dt 
	if position.x > 900 then
		position = self.direction + vmath.vector3(-1, 0, 0)
	elseif position.x <70  then
		position = self.direction - vmath.vector3(1, 0, 0)
	end
	go.set_position(position)
end

I suggest just flipping the sign (i.e. direction) of the self.direction:

if condition_is_true then
    self.direction =  -self.direction 
end
2 Likes

Each line of code means something. When you write code that doesn’t work, try and understand exactly what each line is doing. I have done this for you below.

function init(self)
	--set an initial enemy direction, in this case to the right
	self.direction = vmath.vector3(1, 0, 0)
end


function update(self, dt)

	--set the enemy speed: 90 pixels per second
	self.Espeed = 90

	--get the enemy position at the beginning of this frame
	position = go.get_position() 

	--change this position, by adding the direction multiplied by the speed per second, multiplied by the time taken for this frame
	position = position + self.direction * self.Espeed * dt 

	--if the enemy is beyond 900 pixels to the right, then...
	if position.x > 900 then

		--set the position to the direction (???) and add -1 to the x position (???)
		position = self.direction + vmath.vector3(-1, 0, 0)

	--if the enemy is beyond 70 pixels to the left, then...
	elseif position.x <70  then

		--set the position to the direction (???) and add 1 to the x position (???)
		position = self.direction - vmath.vector3(1, 0, 0)

	end

	--apply the new calculated position
	go.set_position(position)
end

Do you understand what each line does? Do you see the issue with the lines that have ??? in them? Instead of changing the direction of the enemy when it crosses a boundary (900 or 70), you actually set the position of the enemy to the direction, which doesn’t make sense. I bet the enemy just teleports away, right?

Try and really think logically about what your script does!

5 Likes

I did some debugging so self.direction variable vmath stays at 1 then after 501 the vmath = -1,0,0 but it doesnt change the direction of the character. Am i not passing the variable or something?

function update(self, dt)
	self.direction = vmath.vector3(1, 0, 0)
	self.Espeed = 90
	position = go.get_position() 
	position = position + self.direction * self.Espeed * dt 
	
	if position.x > 501 then
		self.direction = vmath.vector3(-1, 0, 0)

You’ve moved the initialisation of self.direction from init (happens once, when the script is loaded) to update (happens every frame). Why did you do that, and what effect do you think it has on your script?

4 Likes

just changed it and my code is working!. Thanks for your help it was really well thoughout advice and made me think in a way that i wouldnt of normally

I’m glad to hear it! I’m not the best teacher, but I hope I got you to think a bit with my annoying answers :slight_smile:

5 Likes

Big fan of the videos just wanted to say thank you!