pointing into a circle. help please
BlitzMax Forums/BlitzMax Programming/pointing into a circle. help please
| ||
I'm trying to suss how to do the following for an idea for a shooter. The player will be locked to moving in an arc of an ellipse or circle. I need the player to point toward the centre of the circle at all times and bullets fired travel toward the center the out of the edge of the game area. I'm having trouble with getting the ship to point inwards and the bullets to fire at the correct angle. (although I suspect the two are linked.) the code I have is dead basic and was knocked up for testing the ship rotation. The second bit of code is what I have for the bullet path, but it does not take the correct path. I know some correction needs to take place, but I'm not sure how to detect which quadrant the player is in to correct the angle. My maths is quite shakey and does need a in depth refresh. ' test rotation, ship should point into the circle. Graphics 800 , 600 image = LoadImage("D:\Program Files\BlitzMax\samples\digesteroids\graphics\ship.png") SetImageHandle(image , 10 , 11) For i = 0 To 360 x = 400 + Sin(i) * 200 y = 300 + Cos(i) * 200 ang = ATan2(x-400,y-300) If ang < 0 Then ang:+360 SetRotation(ang+180) DrawImage(image,x,y) Print i + " " + x +" " + y + " " + ATan2(x-400,y-300) Flip Next WaitKey ' test firing code should always fire into the center and beyond Graphics 800 , 600 While Not KeyDown(KEY_ESCAPE) Cls mx = MouseX() px = 400 + Cos(mx) * 300 py = 300 + Sin(mx) * 200 DrawRect(px, py, 5 ,5) If MouseDown(1) And fire = False fire = True bx = px by = py ang = ATan2(bx-400,by-300) End If If fire = True DrawRect(bx, by, 2 ,2) bx :+ Cos(ang) * 10 by :+ Sin(ang) * 10 End If Flip Wend End Thanks Andy |
| ||
Just a quick observation - you have the ATan2 parameters back to front - it should be Y,X. |
| ||
Here's a basic TSprite class that I created for the use in my 2D games. It has some advanced features. For example... GetDistanceToXY - Returns the distance between the sprite and any X/Y location on the screen. TurnToXY - Sets the sprites heading in the direction of any X/Y coordinates. (The sprite can move toward the coords by setting the StepSize property to a number higher than 0). PointATXY - Turns the sprite to point at any X/Y coordinates on the screen. Global SpriteIndex:Int = -1 Global SpriteGroupIndex:Int = -1 Function GetNextSpriteIndex:Int() SpriteIndex:+ 1 Return SpriteIndex End Function Function GetNextSpriteGroupIndex:Int() SpriteGroupIndex:+ 1 Return SpriteGroupIndex End Function 'Basic Sprite Graphics Object Type TSprite Extends TLink 'Public Properties Field zOrder:Int = GetNextSpriteIndex() Field x:Float, y:Float Field Rot:Float = 0.0 Field alpha:Float = 1.0 Field Blend:Int = GetBlend() Field ScaleX:Float = 1.0 Field ScaleY:Float = 1.0 Field MaskRed:Int = 255, MaskGreen:Int = 255, MaskBlue:Int = 255 Field Solid:Int = True Field Heading:Float = 0.0 Field StepSize:Float = 0.0 'Private Properties ***I Wish*** Field Img:TImage Field tRot:Float, tAlpha:Int, tBlend:Int, tScaleX:Float, tScaleY:Float Field tRed:Int, tGreen:Int, tBlue:Int Field _CurrentFrame:Int = 0 Method New() x = 0.0; y = 0.0 Img = Null End Method Method Load(FileStream:Object, flags:Int = MASKEDIMAGE) Img = LoadImage(FileStream, flags) End Method Method Position(xpos:Float, ypos:Float) x = xpos; y = ypos End Method Method GetState() tRot = GetRotation() tAlpha = GetAlpha() tBlend = GetBlend() GetScale(tScaleX, tScaleY) GetColor(tRed, tGreen, tBlue) End Method Method SetState() SetRotation(Rot) SetAlpha(alpha) SetBlend(Blend) SetScale(ScaleX, ScaleY) SetColor(MaskRed, MaskGreen, MaskBlue) End Method Method RestoreState() SetRotation(tRot) SetAlpha(tAlpha) SetBlend(tBlend) SetScale(tScaleX, tScaleY) SetColor(tRed, tGreen, tBlue) End Method Method Render() GetState() SetState() If StepSize <> 0 Then Local dx:Float = Sin(Heading) * StepSize Local dy:Float = -Cos(Heading) * StepSize x:+ dx; y:+ dy End If DrawImage(Img, x, y, _CurrentFrame) RestoreState() End Method Method Compare(Other:Object) spr:TSprite = TSprite(Other) If Not spr Then Return -1 Return zOrder - spr.zOrder End Method Method GetDistanceToXY:Float(x1:Float, y1:Float) Local dx:Float = Abs(x - x1) Local dy:Float = Abs(y - y1) Return Sqr(dx ^ 2 + dy ^ 2) End Method Method TurnToXY:Float(x1:Float, y1:Float) Heading = Float(ATan2(x1 - x, y1 - y)) * -1 End Method Method PointAtXY:Float(x1:Float, y1:Float) Rot = Float(ATan2(x1 - x, y1 - y)) * -1 End Method End Type Type TSpriteGroup Extends TList Field Priority:Int = GetNextSpriteGroupIndex() Method Render() For Local obj:Object = EachIn Self Local sg:TSpriteGroup = TSpriteGroup(obj) If sg Then sg.Render() Local spr:TSprite = TSprite(obj) If spr Then spr.Render() Next End Method End Type Here's an animated TSprite class (Extends the TSprite class shown above). 'A little less basic sprite object. 'Automatically does animation on a Frame by Frame basis. Type TAnimSprite Extends TSprite 'Additional Properties Field FrameCount:Int, StartFrame:Int, FrameDelay:Int Field _NextTick:Int Field Animate:Int Method New() X = 0.0; Y = 0.0; Img = Null FrameCount = 0; StartFrame = 0; FrameDelay = 0 _CurrentFrame = 1; Animate = False _NextTick = 0 End Method Method LoadAnim(FileStream:Object, Width:Int, Height:Int, Cell1:Int, CellCount:Int, FrameDuration:Int, Flags:Int = MASKEDIMAGE) Img = LoadAnimImage(FileStream,Width, Height, Cell1, CellCount, Flags) FrameCount = CellCount; StartFrame = Cell1 FrameDelay = FrameDuration Animate = False End Method Method Render() Super.Render() If Animate Then If MilliSecs() > _NextTick Then _NextTick = MilliSecs() + FrameDelay _CurrentFrame:+ 1 If _CurrentFrame => FrameCount Then _CurrentFrame = StartFrame End If End If End Method End Type |
| ||
Ah those pesky coords :D swapped them about and adjust the angle, yay. firing now occours with in the circle and and ship faces inside the circle. :D the only thing is, the bullets do not pass though the very center of the circle which is what i am after. any suggestions? Cheers. |
| ||
the bullets will not pass through if they are programmed to always 'point' to the center. I suggest that you learn about Vectors and put together a Vector Type. There are a few of these in the Code Archives to get you started. (Chroma's is very good) every moving entity could have a velocity vector. |
| ||
Thanks. I have suss'd it now anyhow :D The reason the shots were off is due to the fact I was not using floats, but ints instead and errors were creeping in :) Cheers. |
| ||
I was going to say it sounds like you were using integers. Of course that's easy to say now, after the fact ;-D There was a small game on the Amiga along these lines, where you moved around the circle shooting at stuff that expand outward from the center. |