for i=1, #enemies do
if not CheckCollision(player, enemies[i]) then
-- the vector from enemy to the player
local vx = player.x - enemies[i].x
local vy = player.y - enemies[i].y
-- normalize it, i.e. divide it by it's length
local length = math.sqrt(vx * vx + vy * vy)
vx = vx / length
vy = vy / length
-- move the zombie towards the player
enemies[i].x = enemies[i].x + vx * enemies[i].speed * dt
enemies[i].y = enemies[i].y + vy * enemies[i].speed * dt
end
end
Last edited by thelinx on Sat Nov 13, 2010 11:01 pm, edited 1 time in total.
Reason:fify
Ahh, now I see what I was doing wrong. I actually had my function worded EXACTLY like you have it, though I didn't add the iterator, thinking it wasn't needed. Thanks again!
EDIT: Holy Awesome! it works perfectly. I'm going to fix up a lot of my code and actually submit a playable demo. Thanks Ninwa!
Alright so everything worked great for multiple enemies FOLLOWING the player. The only issue now is that when I try to use the same method to change player direction it only works for the last enemy drawn. Here is my function to change "enemies.dir" depending on where the enemy is in relation to the player.
function CheckDirection(obj1, obj2)
if obj1.x > obj2.x + obj2.w - 1 then
for i=1, #enemies do
enemies[i].dir = "right"
end
elseif obj1.y > obj2.y + obj2.h - 1 then
for i=1, #enemies do
enemies[i].dir = "down"
end
elseif obj2.x > obj1.x + obj1.w - 1 then
for i=1, #enemies do
enemies[i].dir = "left"
end
elseif obj2.y > obj1.y + obj1.h - 1 then
for i=1, #enemies do
enemies[i].dir = "up"
end
end
end
Ryne wrote:Alright so everything worked great for multiple enemies FOLLOWING the player. The only issue now is that when I try to use the same method to change player direction it only works for the last enemy drawn. Here is my function to change "enemies.dir" depending on where the enemy is in relation to the player.
Any ideas?
This is because you are doing it for each zombie in the list, therefore only the last zombie direction is kept for the draw. He can't possibly face them all at the same time if they are different unit vectors from the player.
What you need to do is iterate over the zombies to find the nearest one, and then face that one. Sorry, in advance for psuedo-code
closestZombie = zombies[1]
for i,v in zombies do
if v.distanceFromPlayer() < closestZombie.distanceFromPlayer() then
closestZombie = v
end
--now set your player facing closestZombie
When you exit that for loop, closestZombie should be assigned to the closest one. Just make sure you catch cases where there are no zombies, or if the zombies aren't yet close enough to bother making the player turn around.
Thanks for the reply but I don't think you understand my question. I don't want the player to face the zombie. The player has nothing to do with my question.
Right now each enemy spawned has a "dir" variable for direction. It can be up, down, left, or right. I have a function that SHOULD change each of the enemies "dir" value depending on their position in relevance to the player. Right now it only changes that value for the LAST enemy thats spawned.
Also I have to use player.x = player.x + 50 * dt, in order to get it to the same speed as "1" without DT. This seems to make the player lag/jitter.
Ryne wrote:Also I have to use player.x = player.x + 50 * dt, in order to get it to the same speed as "1" without DT. This seems to make the player lag/jitter.
That's because dt is the time passed since the last update. Usually it's a very small number. So if you multiply dt by 50, that means your player will move 50px in one second. If you just put 1 (without multiplying it by dt) it's going to move much faster on a fast machine than it will on a slow one.
Ryne wrote:Also I have to use player.x = player.x + 50 * dt, in order to get it to the same speed as "1" without DT. This seems to make the player lag/jitter.
That's because dt is the time passed since the last update. Usually it's a very small number. So if you multiply dt by 50, that means your player will move 50px in one second. If you just put 1 (without multiplying it by dt) it's going to move much faster on a fast machine than it will on a slow one.
Ahh, I've set it to 60, which is my refresh rate and it is back to perfectly smooth. Anything besides 60 looks fine but its a little jittery.
Ryne wrote:Ahh, I've set it to 60, which is my refresh rate and it is back to perfectly smooth. Anything besides 60 looks fine but its a little jittery.
Possibly try math.floor'ing the x and y draw position values.
Alright my thread is being diverted. I still need help with this:
Ryne wrote:Thanks for the reply but I don't think you understand my question. I don't want the player to face the zombie. The player has nothing to do with my question.
Right now each enemy spawned has a "dir" variable for direction. It can be up, down, left, or right. I have a function that SHOULD change each of the enemies "dir" value depending on their position in relevance to the player. Right now it only changes that value for the LAST enemy thats spawned.
function CheckDirection(obj1, obj2)
if obj1.x > obj2.x + obj2.w - 1 then
for i=1, #enemies do
enemies[i].dir = "right"
end
elseif obj1.y > obj2.y + obj2.h - 1 then
for i=1, #enemies do
enemies[i].dir = "down"
end
elseif obj2.x > obj1.x + obj1.w - 1 then
for i=1, #enemies do
enemies[i].dir = "left"
end
elseif obj2.y > obj1.y + obj1.h - 1 then
for i=1, #enemies do
enemies[i].dir = "up"
end
end
end
function CheckDirection(obj1, obj2)
if obj1.x > obj2.x + obj2.w - 1 then
for i=1, #enemies do
enemies[i].dir = "right"
end
....
If you are checking between obj1 and obj2, then why are you invoking every zombie in the table and changing their direction?
Seems like it should be something more like:
function CheckDirection(obj1, obj2)
if obj1.x > obj2.x + obj2.w - 1 then
obj2.dir = "right"
....
And you NEED dt (or some way to time frames). The guy moves at the speed of light on my computer because it is computation based instead of time based.