[Resolved]A car that stops when another has collided with it from the back

Basically, I have a line of cars that all move along the y axis, with the same x coordinates. They all have different speeds. Say we have two cars, car A and car B. Car B is in front (so, below car A, as the cars move from top to bottom) and car A is behind car B (so, it has a smaller y coordinate). Car A is going faster than car B and it is supposed to slow down to car B’s speed when it reaches it (basically, when it collides with it) and carry on going at that speed.

Both cars are supposed to ‘reset’ when they reach a y value of some pixels greater than the screen’s bottom.

Problem is, I want the cars (or the collision detection code, if you prefer) to be able to tell the difference between a collision at the back of the car, and at any other part (because in the game, if a car collides with another head-on or at the sides, you are supposed to lose the game).

So far my options are a sensor object at the back of every car, which I’d rather not implement as it is a lot of code to add (I will be spawning more than 20 cars) and preCollision detection which I don’t know why it doesn’t work (sample code below).

car.lua
[lua]function new(params)
local newCar
newCar = display.newImage(“car.png”)
newCar.x = params.x
newCar.y = params.y

local OriginalX = newCar.x
local OriginalY = - 20
local moveCar
local moveOrderTime = 0
local moveOrderX = 0
local moveOrderY = 0

function newCar.resetCar()
newCar.x = OriginalX
newCar.y = OriginalY
setup.score = setup.score + 1
newCar.moveCar({time = moveOrderTime, x = moveOrderX, y = moveOrderY})
end

function newCar.moveCar(params)
moveOrderTime = params.time
moveOrderX = params.x
moveOrderY = params.y
transition.to(newCar,{time = moveOrderTime, x = moveOrderX, y = moveOrderY, onComplete = newCar.resetCar})
end

function newCar.onLocalPreCollision(event)
if event.phase==“began” then transition.pause(newCar) end
if event.phase==“ended” then transition.resume(newCar) end
end

return newCar

end[/lua]

main.lua:
[lua]local car1 = car.new( {x = 160, y = -80} )
cars[#cars + 1] = car1
physics.addBody(car1)
car1.isFixedRotation = true
car1.isSensor = true
car1.moveCar({time = 7000, x = car1.x, y = screenBottom})
car1:addEventListener(“preCollision”, car1.onLocalPreCollision)[/lua]

Any ideas on how to do this? I am swamped, stuck with this problem for days :frowning: [import]uid: 106739 topic_id: 19356 reply_id: 319356[/import]

why not just listen for the collision as usual, then upon collision, do a check to see where the actual collision took place (just check the x/y values of both objects, and compare them).

I’m doing something similar in my game and it is working fine. Here is a small snippet:

[lua]onCollision = function(self, event)
if self.name == “obstacle” and event.other.name == “enemy” then

if(event.other.x < self.x)then
event.other:changeDirection()
end

end
end[/lua] [import]uid: 49447 topic_id: 19356 reply_id: 74733[/import]

the simple answer is to try programming the movement and collisions yourself without (over)relying on the transition.to - take control it’s worth it
[import]uid: 3093 topic_id: 19356 reply_id: 74897[/import]

Yes but how would I tell it to stop the car? I can’t have transition.pause(newCar) anymore, cause every car is listening to that collision detection. What must I replace NewCar with?

Also, I tried
[lua]function onLocalCollision(self, event)
if event.other.y > self.y then
transition.pause(self)
end
end[/lua]
but it complains: attempt to index local ‘event’ (a nil value) [import]uid: 106739 topic_id: 19356 reply_id: 74895[/import]

I was always told, don’t try to reinvent the wheel.

Why try to remake something that’s already there? If the functionality is there and I can use it, I want to.

Not to mention, I don’t have time to write my own movement-collision code. [import]uid: 106739 topic_id: 19356 reply_id: 74899[/import]

I’m a bit confused why you are using both transitions and physics. If you just use physics and :translate for placing the cars, it will be a lot easier to control and keep track of them.

something like this would stop carA after it’s been hit by carB

[lua]onCollision = function(self, event)
if self.name == “carA” and event.other.name == “carB” then

if(event.other.y < self.y)then
– carA was rear-ended by carB
self:setLinearVelocity( 0, 0 )
end

end
end[/lua] [import]uid: 49447 topic_id: 19356 reply_id: 74947[/import]

I have, so far:

car.lua
[lua]function onLocalCollision(self, event)
if self.name == “car1” and event.other.name == “car2” then
if(event.other.y < self.y)then
– carA was rear-ended by carB
self:setLinearVelocity( 0, 0 )
end
end
end[/lua]

main.lua:
[lua]local car1 = car.new( {x = 160, y = -80} )
cars[#cars + 1] = car1
physics.addBody(car1)
car1.name = “car1”
car1.isFixedRotation = true
car1.isSensor = true
car1.moveCar({time = 7000, x = 0, y = 55})
car1:addEventListener(“collision”, car.onLocalCollision)

local car2 = car.new({x=160, y = -20})
cars[#cars + 1] = car2
physics.addBody(car2)
car2.name = “car2”
car2.isFixedRotation = true
car2.isSensor = true
car2.moveCar({time = 7200, x = 0, y = 50})
car2:addEventListener(“collision”, car.onLocalCollision)[/lua]

The code doesn’t go into the if statement in the collision function for some reason. Any idea why?

Also, I can’t use setLinearVelocity, really, until I can pause and resume it, like I do with transition.to

EDIT: Nevermind, I solved it with some help. I use the code you first suggested and instead of self.y I have event.target.y [import]uid: 106739 topic_id: 19356 reply_id: 75057[/import]