About Monkey 2 › Forums › Monkey 2 Programming Help › Trigonometry Fail! Help!
This topic contains 5 replies, has 3 voices, and was last updated by
therevills 1 year, 4 months ago.
-
AuthorPosts
-
November 25, 2017 at 6:05 am #11960
I’m trying to shoot a bullet out of hard point which is an offset of the main ship, but my trig is failing
Here is some cut down runnable code, I would like the bullet to come out of the red square:
W = Move forward
S = Move Backward
A = Rotate Left
D = Rotate Right
Space = ShootMonkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Const Size:=New Vec2i( 640,480 )Class MyWindow Extends WindowConst FPS:Int = 60Field player:PlayerField timer:TimerMethod New()Super.New( "My Window",640,480,WindowFlags.Resizable )ClearColor = Color.BlackLayout="letterbox"player = New Player(100, 100)timer = New Timer(FPS, OnUpdate)EndMethod OnRender( canvas:Canvas ) Overrideplayer.Render(canvas)Bullet.RenderAll(canvas)EndMethod OnUpdate()RequestRender()player.Update()Bullet.UpdateAll()EndMethod OnMeasure:Vec2i() OverrideReturn SizeEndEndClass SpriteField x:FloatField y:FloatField r:Float = Pi / 2Field sizeW:FloatField sizeH:FloatField colour:ColorField velocity:Vec2f = New Vec2f(0, 0)Property RotationDisplay:Float()Return r - Pi / 2EndEndClass Player Extends SpriteMethod New(x:Float ,y:Float)Self.x = xSelf.y = ySelf.sizeW = 100Self.sizeH = 50Self.colour = Color.GreenEndMethod Render(canvas:Canvas )canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x ,y ).Rotate( RotationDisplay )canvas.DrawRect(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Color = Color.Redcanvas.DrawRect((sizeW/2)-10, (sizeH/2)-10, 10, 10)canvas.Matrix=matrixcanvas.DrawText("r = " +r, 0, 0)EndMethod Update()Local s:Float = 2Local am:Float = 0.08Local factor:Float = 1.5If Keyboard.KeyDown(Key.W)velocity.x += (1 * factor - velocity.x) * amElseif Keyboard.KeyDown(Key.S)velocity.x += (-1 * factor - velocity.x) * amElsevelocity.x *= .99EndIf Keyboard.KeyDown(Key.A)r += .1EndIf Keyboard.KeyDown(Key.D)r -= .1Endx += velocity.xIf Keyboard.KeyHit(Key.Space)New Bullet(x, y, r)EndEndEndClass Bullet Extends SpriteGlobal list := New List<Bullet>Field timeToLive:IntField speed:Float = 5Method New(x:Float, y: Float, r:Float)Self.x = xSelf.y = ySelf.r = rLocal ofx:Int = 100Local ofy:Int = 50Local gunPosX:Float = x + ofx * Cos(r) - ofy * Sin(r)Local gunPosY:Float = y + ofy * Sin(r) + ofy * Cos(r)Self.x = gunPosXSelf.y = gunPosYSelf.timeToLive = 20Self.sizeW = 40Self.sizeH = 15Self.colour = Color.RedSelf.list.AddLast(Self)EndFunction UpdateAll()If Not list ReturnLocal it := list.All()While Not it.AtEndLocal b:Bullet = it.Currentb.Update()If b.timeToLive <= 0it.Erase()Elseit.Bump()EndEndEndMethod Update()Local dx:Float = Sin(r) * speedLocal dy:Float = Cos(r) * speedx += dxy += dytimeToLive -= 1EndFunction RenderAll:Void(canvas:Canvas)If Not list ReturnFor Local c:Bullet = Eachin listc.Render(canvas)NextEndMethod Render(canvas:Canvas)canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x,y ).Rotate( RotationDisplay )canvas.DrawOval(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Matrix=matrixEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndCould someone please let me know where I am going wrong?
November 25, 2017 at 8:01 am #11964Here you go…
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193[crayon-5cba159db2435965715919 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Const Size:=New Vec2i( 640,480 )Class MyWindow Extends WindowConst FPS:Int = 60Field player:PlayerField timer:TimerMethod New()Super.New( "My Window", Size.X, Size.Y, WindowFlags.Resizable )ClearColor = Color.BlackLayout="letterbox"player = New Player(100, 100)timer = New Timer(FPS, OnUpdate)EndMethod OnRender( canvas:Canvas ) Overrideplayer.Render(canvas)Bullet.RenderAll(canvas)EndMethod OnUpdate()RequestRender()player.Update()Bullet.UpdateAll()EndMethod OnMeasure:Vec2i() OverrideReturn SizeEndEndClass SpriteField x:FloatField y:FloatField r:Float = Pi / 2Field sizeW:FloatField sizeH:FloatField colour:ColorField velocity:Vec2f = New Vec2f(0, 0)Property RotationDisplay:Float()Return r - Pi / 2EndEndClass Player Extends SpriteMethod New(x:Float ,y:Float)Self.x = xSelf.y = ySelf.sizeW = 100Self.sizeH = 50Self.colour = Color.GreenEndMethod Render(canvas:Canvas )canvas.Color = Self.colourLocal xr:float = x + (Sin(r) * 100)Local yr:float = y + (Cos(r) * 100)canvas.DrawLine( x, y, xr, yr )canvas.Color = Color.Bluecanvas.DrawRect(x-5, y-5, 10, 10)' Local matrix:=canvas.Matrix' canvas.Matrix=matrix.Translate( x ,y ).Rotate( RotationDisplay )' canvas.DrawRect(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)' canvas.Color = Color.Blue' canvas.DrawRect(-5, -5, 10, 10)' canvas.Color = Color.Red' canvas.DrawRect((sizeW/2)-10, (sizeH/2)-10, 10, 10)' canvas.Matrix=matrixcanvas.DrawText("r = " +r, 0, 0)EndMethod Update()Local s:Float = 2Local am:Float = 0.08Local factor:Float = 1.5If Keyboard.KeyDown(Key.Up)velocity.x += (Sin(r) * factor - velocity.x) * amvelocity.y += (Cos(r) * factor - velocity.y) * amElseif Keyboard.KeyDown(Key.Down)velocity.x += (-Sin(r) * factor - velocity.x) * amvelocity.y += (-Cos(r) * factor - velocity.y) * amElsevelocity.x *= .99velocity.y *= .99EndIf Keyboard.KeyDown(Key.Left)r += .1EndIf Keyboard.KeyDown(Key.Right)r -= .1Endx += velocity.xy += velocity.yIf Keyboard.KeyDown(Key.Space)thenNew Bullet(x, y, r)EndEndEndClass Bullet Extends SpriteGlobal list := New List<Bullet>Field timeToLive:IntField speed:Float = 5Method New(x:Float, y: Float, r:Float)Self.x = xSelf.y = ySelf.r = r' Print x+" "+y+" "+rLocal gunPosX:Float = x + (Sin(r) * 100)Local gunPosY:Float = y + (Cos(r) * 100)Self.x = gunPosXSelf.y = gunPosYSelf.timeToLive = 40Self.sizeW = 10Self.sizeH = 10Self.colour = Color.RedSelf.list.AddLast(Self)EndFunction UpdateAll()If Not list ReturnLocal it := list.All()While Not it.AtEndLocal b:Bullet = it.Currentb.Update()If b.timeToLive <= 0it.Erase()Elseit.Bump()EndEndEndMethod Update()Local dx:Float = Sin(r) * speedLocal dy:Float = Cos(r) * speedx += dxy += dytimeToLive -= 1EndFunction RenderAll:Void(canvas:Canvas)If Not list ReturnFor Local c:Bullet = Eachin listc.Render(canvas)NextEndMethod Render(canvas:Canvas)canvas.Color = Self.colourcanvas.DrawRect(x-5, y-5, 10, 10)' Local matrix:=canvas.Matrix' canvas.Matrix=matrix.Translate( x,y ).Rotate( RotationDisplay )' canvas.DrawOval(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)' canvas.Color = Color.Blue' canvas.DrawRect(-5, -5, 10, 10)' canvas.Matrix=matrixEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndThe matrix stuff was making things hard for you, so I took it out so you can see the trig in operation. You can add the matrix stuff back once you get familiar with it
November 25, 2017 at 3:58 pm #11972Is this what you wanted?
I marked everything I modified.
the rotation formula was wrong.[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178[crayon-5cba159dbb1db546113295 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Const Size:=New Vec2i( 640,480 )Class MyWindow Extends WindowConst FPS:Int = 60Field player:PlayerField timer:TimerMethod New()Super.New( "My Window",640,480,WindowFlags.Resizable )ClearColor = Color.BlackLayout="letterbox"player = New Player(100, 100)timer = New Timer(FPS, OnUpdate)EndMethod OnRender( canvas:Canvas ) Overrideplayer.Render(canvas)Bullet.RenderAll(canvas)EndMethod OnUpdate()RequestRender()player.Update()Bullet.UpdateAll()EndMethod OnMeasure:Vec2i() OverrideReturn SizeEndEndClass SpriteField x:FloatField y:FloatField r:Float = Pi / 2Field sizeW:FloatField sizeH:FloatField colour:ColorField velocity:Vec2f = New Vec2f(0, 0)Property RotationDisplay:Float()Return r - Pi / 2EndEndClass Player Extends SpriteMethod New(x:Float ,y:Float)Self.x = xSelf.y = ySelf.sizeW = 100Self.sizeH = 50Self.colour = Color.GreenEndMethod Render(canvas:Canvas )canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x ,y ).Rotate( RotationDisplay )canvas.DrawRect(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Color = Color.Redcanvas.DrawRect((sizeW/2)-10, (sizeH/2)-10, 10, 10)canvas.Matrix=matrixcanvas.DrawText("r = " +r, 0, 0)EndMethod Update()Local s:Float = 2Local am:Float = 0.08Local factor:Float = 1.5If Keyboard.KeyDown(Key.W)velocity.x += (1 * factor - velocity.x) * amElseif Keyboard.KeyDown(Key.S)velocity.x += (-1 * factor - velocity.x) * amElsevelocity.x *= .99EndIf Keyboard.KeyDown(Key.A)r += .1EndIf Keyboard.KeyDown(Key.D)r -= .1Endx += velocity.xIf Keyboard.KeyHit(Key.Space)New Bullet(x, y, r)EndEndEndClass Bullet Extends SpriteGlobal list := New List<Bullet>Field timeToLive:IntField speed:Float = 5Method New(x:Float, y: Float, r:Float)Self.x = xSelf.y = ySelf.r = -rLocal ofx:Int = 50 '**************************Local ofy:Int = 25 '**************************Local gunPosX:Float = ofx * Cos(-r+Pi/2) - ofy * Sin(-r+Pi/2) '********************Local gunPosY:Float = ofx * Sin(-r+Pi/2) + ofy * Cos(-r+Pi/2) '********************Self.x = x+gunPosX ' ********************Self.y = y+gunPosY ' ********************Self.timeToLive = 20Self.sizeW = 40Self.sizeH = 15Self.colour = Color.RedSelf.list.AddLast(Self)EndFunction UpdateAll()If Not list ReturnLocal it := list.All()While Not it.AtEndLocal b:Bullet = it.Currentb.Update()If b.timeToLive <= 0it.Erase()Elseit.Bump()EndEndEndMethod Update()Local dx:Float = Sin(-r) * speed '************************Local dy:Float = Cos(-r) * speed '************************x += dxy += dytimeToLive -= 1EndFunction RenderAll:Void(canvas:Canvas)If Not list ReturnFor Local c:Bullet = Eachin listc.Render(canvas)NextEndMethod Render(canvas:Canvas)canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x,y ).Rotate( -RotationDisplay ) '****************************canvas.DrawOval(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Matrix=matrixEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndNovember 25, 2017 at 11:24 pm #11978Thanks Guys
Yep that looks perfect Jesse – I’ve done this sort of thing before in BlitzMax but couldnt work it out! Looks like I was doing everything clockwise instead of anticlockwise, not sure about the 90 degree turn though you do (Pi / 2)?
November 26, 2017 at 2:21 am #11982Yea, I got kind of lazy and was just doing some quick modifications because of the results I was getting. I am sure you can figure out the proper way to do it. Basically the problem was in the rotation formula.
[/crayon]Monkey1234[crayon-5cba159dd54ad072593788 inline="true" ]Local gunPosX:Float = ofx * Cos(-r+Pi/2) - ofy * Sin(-r+Pi/2) '********************Local gunPosY:Float = ofx * Sin(-r+Pi/2) + ofy * Cos(-r+Pi/2) '********************you didn’t have offy on the second line you had ofx on both sides of the formula.
Also, you forgot to add the position(x,y) of the bullet to the direction(dx,dy). about the -Pi/2, the Pi/2 is what you started off in the sprite. I am not sure I can explain it to you but you start with the sprite “Field r:Float = Pi/2” and then your RotationDisplay has an offset angle of 90 degrees. so thats why the adjustment of -Pi/2, at least that’s what I got out of it.[EDIT]
This is more like it:
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175[crayon-5cba159dd54b7002949779 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Const Size:=New Vec2i( 640,480 )Class MyWindow Extends WindowConst FPS:Int = 60Field player:PlayerField timer:TimerMethod New()Super.New( "My Window",640,480,WindowFlags.Resizable )ClearColor = Color.BlackLayout="letterbox"player = New Player(100, 100)timer = New Timer(FPS, OnUpdate)EndMethod OnRender( canvas:Canvas ) Overrideplayer.Render(canvas)Bullet.RenderAll(canvas)EndMethod OnUpdate()RequestRender()player.Update()Bullet.UpdateAll()EndMethod OnMeasure:Vec2i() OverrideReturn SizeEndEndClass SpriteField x:FloatField y:FloatField r:Float = 0Field sizeW:FloatField sizeH:FloatField colour:ColorField velocity:Vec2f = New Vec2f(0, 0)EndClass Player Extends SpriteMethod New(x:Float ,y:Float)Self.x = xSelf.y = ySelf.sizeW = 100Self.sizeH = 50Self.colour = Color.GreenEndMethod Render(canvas:Canvas )canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x ,y ).Rotate( r)canvas.DrawRect(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Color = Color.Redcanvas.DrawRect((sizeW/2)-10, (sizeH/2)-10, 10, 10)canvas.Matrix=matrixcanvas.DrawText("r = " +r, 0, 0)EndMethod Update()Local s:Float = 2Local am:Float = 0.08Local factor:Float = 1.5If Keyboard.KeyDown(Key.W)velocity.x += (1 * factor - velocity.x) * amElseif Keyboard.KeyDown(Key.S)velocity.x += (-1 * factor - velocity.x) * amElsevelocity.x *= .99EndIf Keyboard.KeyDown(Key.A)r += .1EndIf Keyboard.KeyDown(Key.D)r -= .1Endx += velocity.xIf Keyboard.KeyHit(Key.Space)New Bullet(x, y, r)EndEndEndClass Bullet Extends SpriteGlobal list := New List<Bullet>Field timeToLive:IntField speed:Float = 5Method New(x:Float, y: Float, r:Float)Self.x = xSelf.y = ySelf.r = -rLocal ofx:Int = 50Local ofy:Int = 25Local gunPosX:Float = ofx * Cos(-r) - ofy * Sin(-r) '********************Local gunPosY:Float = ofx * Sin(-r) + ofy * Cos(-r) '********************Self.x = x+gunPosXSelf.y = y+gunPosYSelf.timeToLive = 20Self.sizeW = 40Self.sizeH = 15Self.colour = Color.RedSelf.list.AddLast(Self)EndFunction UpdateAll()If Not list ReturnLocal it := list.All()While Not it.AtEndLocal b:Bullet = it.Currentb.Update()If b.timeToLive <= 0it.Erase()Elseit.Bump()EndEndEndMethod Update()Local dx:Float = Sin(-r+Pi/2) * speed '************************Local dy:Float = Cos(-r+Pi/2) * speed '************************x += dxy += dytimeToLive -= 1EndFunction RenderAll:Void(canvas:Canvas)If Not list ReturnFor Local c:Bullet = Eachin listc.Render(canvas)NextEndMethod Render(canvas:Canvas)canvas.Color = Self.colourLocal matrix:=canvas.Matrixcanvas.Matrix=matrix.Translate( x,y ).Rotate(-r)canvas.DrawOval(- sizeW / 2.0, - sizeH / 2.0, sizeW, sizeH)canvas.Color = Color.Bluecanvas.DrawRect(-5, -5, 10, 10)canvas.Matrix=matrixEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()Endstill have to do the Pi/2 to the shoot direction. but this time its because its shooting 90 degrees from the direction it was created.
November 26, 2017 at 3:07 am #11983Ah thanks Jesse! Yeah that makes sense!
-
AuthorPosts
You must be logged in to reply to this topic.