Problems with object rotation (moving bullets)

As a simple test code, I have a “gun” that rotates clockwise and should fire a bullet every 500 Milliseconds. The bullet should fly into the direction where the gun (displayed as a simple arrow) points.

However, something weird happens here -the bullet directions do not fit to the gun rotation, but what really confuses me is why the bullets alternate their movement direction between backward and forward with every shot. The code below demonstrates the problem (just use any small image named “gfx.png”).

I don’t know why this happens. Could anyone give me a hint please what I am doing wrong here…?
Simple sample code:

[lua]local gunX = 100
local gunY = 200

local shotSpeed = 5
local lastShot = system.getTimer()
local Shots = {}
local numShots = 0

local Gun = display.newLine(0,0, 16,0)
Gun:setColor (255,255,255)
Gun:append (8,-24, 0,0)
Gun.x = gunX
Gun.y = gunY
Gun.xOrigin = gunX-8
Gun.xReference = 8
Gun.width = 1
Gun.rotation = 45
function CreateShots()

Gun.rotation = Gun.rotation + 1

– CREATE NEW SHOT
if (system.getTimer()-lastShot > 500) then
numShots = numShots + 1

Shots[numShots] = display.newImageRect(“gfx.png”,16,16) – SIMPLE SMALL BULLET IMAGE
Shots[numShots].x = Gun.x
Shots[numShots].y = Gun.y
Shots[numShots].xSpeed = math.cos(Gun.rotation) * shotSpeed
Shots[numShots].ySpeed = math.sin(Gun.rotation) * shotSpeed

lastShot = system.getTimer()
end

– MOVE SHOTS
for i = 1, numShots do
Shots[i].x = Shots[i].x + Shots[i].xSpeed
Shots[i].y = Shots[i].y + Shots[i].ySpeed
end

end

Runtime:addEventListener(“enterFrame”, CreateShots)[/lua]
[import]uid: 9644 topic_id: 2715 reply_id: 302715[/import]

Arghhh, had a nice answer done and was kicked out by ANSCA’s stupid login mechanism when I wanted to post.

@Carlos, I know you guys want a forum with the same theme like the website. Then for gods sake, fix it and make it behave like a normal forum. Jesus!!! :frowning: Typing a lengthy answer only to find out that the my login session was over during that time and lose my post is not nice.
Now to Mau Mau,

you are given the angle in degree to math.cos and math.sin, but they expect a angle in radian.

http://lua-users.org/wiki/MathLibraryTutorial

This should do the trick:

[lua]local rotation = math.rad(Gun.rotation - 90)
Shots[numShots].xSpeed = math.cos(rotation) * shotSpeed
Shots[numShots].ySpeed = math.sin(rotation) * shotSpeed[/lua]

Cheers
Michael Hartlef

http://www.whiteskygames.com
http://www.twitter.com/mhartlef
[import]uid: 5712 topic_id: 2715 reply_id: 8078[/import]

Thanks for the hint, Mike.

In the meantime, I solved it like this:
[lua]local PI = 4*math.atan(1)

function MoveShots()

local rotation = PI-Gun.rotation/360*2*PI
Shots[numShot].xSpeed = math.sin(rotation)
Shots[numShot].ySpeed = math.cos(rotation)

end[/lua]

Both methods work -while this one is not as elegant, it seems faster than calling math.rad each frame.

And yeah, the forum really needs to be improved… ASAP :-/ [import]uid: 9644 topic_id: 2715 reply_id: 8126[/import]

You can speed up the math calls by predefining them as local. It makes a differents:

[lua]local mAtan = math.atan
local mRadian = math.rad
local mCos = math.cos
local mSin = math.sin
.
.
.
local rotation = mRadian(Gun.rotation - 90)
Shots[numShots].xSpeed = mCos(rotation) * shotSpeed
Shots[numShots].ySpeed = mSin(rotation) * shotSpeed[/lua]

I wonder if your method is still being faster. [import]uid: 5712 topic_id: 2715 reply_id: 8149[/import]

Just gave it a simple test -my method seems a bit faster in this example:

[lua]local start = system.getTimer()
local PI = 4*math.atan(1)
local angle = 123
local rotation

function doTest()
local mRad = math.rad
local mCos = math.cos
local mSin = math.sin

for i=1,500000 do
– METHOD 1
–rotation = PI-angle/360*2*PI
–local xSpeed = mSin(rotation)
–local ySpeed = mCos(rotation)

– METHOD 2
rotation = mRad(angle - 90)
local xSpeed = mCos(rotation)
local ySpeed = mSin(rotation)
end
end

doTest()

print(“DONE IN “…system.getTimer() - start…” MILLISECONDS”)[/lua]

METHOD 1: 193 ms
METHOD 2: 216 ms

I never trusted built-in math functions too much when it comes to performance… [import]uid: 9644 topic_id: 2715 reply_id: 8176[/import]

Do the test on the device. The 23 ms difference with 500.000 on a desktop means nothing. Unless you do this every frame. :slight_smile: Could be an interupt on the machine also that caused it. But it seems they are close, so choose what you like the best. [import]uid: 5712 topic_id: 2715 reply_id: 8182[/import]

I have adapted a combination of the codes on this thread to a flying ship shooter. Everything works except for the bullet doesn’t fly. Can you see what I’m doing wrong?

[code]

local Shots = {}
local numShots = 0
local lastShot = system.getTimer()
local shotSpeed = 5
local mAtan = math.atan
local mRadian = math.rad
local mCos = math.cos
local mSin = math.sin
function fire:touch()

local rotation = mRadian(ship.rotation - 90)

if (system.getTimer()-lastShot > 100) then
numShots = numShots + 1

Shots[numShots] = display.newImage(“bullet.png”)
Shots[numShots].x = ship.x
Shots[numShots].y = ship.y
Shots[numShots].rotation = ship.rotation
Shots[numShots].xSpeed = mSin(rotation)
Shots[numShots].ySpeed = mCos(rotation)

lastShot = system.getTimer()
end
end

for i = 1, numShots do
Shots[i].x = Shots[i].x + Shots[i].xSpeed
Shots[i].y = Shots[i].y + Shots[i].ySpeed
end

fire:addEventListener(“touch”, fire)
[import]uid: 31005 topic_id: 2715 reply_id: 25566[/import]