pointing into a circle. help please

BlitzMax Forums/BlitzMax Programming/pointing into a circle. help please

peltazoid(Posted 2007) [#1]
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


GfK(Posted 2007) [#2]
Just a quick observation - you have the ATan2 parameters back to front - it should be Y,X.


CoderLaureate(Posted 2007) [#3]
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




peltazoid(Posted 2007) [#4]
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.


bradford6(Posted 2007) [#5]
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.


peltazoid(Posted 2007) [#6]
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.


ImaginaryHuman(Posted 2007) [#7]
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.