2D Vector fun

BlitzMax Forums/BlitzMax Programming/2D Vector fun

Yahfree(Posted 2008) [#1]
Hey guys. I'm messing with vectors for the first time(in game programming).

What can I do to get this ball from sinking when it runs out of energy??


Sorry, my TVect2 object is pretty overdone(lots of code) for my simple needs, figured I get most of the maths of vectors done early, though i'm still missing things like reflect and dot product.


Thanks!


AlexO(Posted 2008) [#2]
This is more or less a 'hack' but atleast it works:


SuperStrict
Type TVect2
	Field x:Float, y:Float
	
	Method Create:TVect2(_x:Float,_y:Float) 
		Local v:TVect2 = New TVect2
		v.x = _x
		v.y = _y
		Return v
	End Method
	
	Method GetX:Float() 
		Return x
	End Method
	
	Method GetY:Float()
		Return y
	End Method
	
	Method SetX(_x:Float) 
		x = _x
	End Method
	
	Method SetY(_y:Float) 
		y = _y
	End Method
	
	Method GetAngle:Float()
		Return ATan2(y,x)
	End Method
	
	Method Rotate(ang:Float)
		Local xprime:Float=Cos(ang)*x - Sin(ang)*y 
		Local yprime:Float=Sin(ang)*x + Cos(ang)*y
		x=xprime
		y=yprime
	End Method
	
	Method Add(_x:Float,_y:Float)
		x:+_x
		y:+_y
	End Method
	
	Method AddVec(Vec:TVect2)
		If Vec=Null Return
		x:+Vec.x
		y:+Vec.y
	End Method

	Method Subtract(_x:Float,_y:Float)
		x:-_x
		y:-_y
	End Method
	
	Method SubtractVec(Vec:TVect2)
		If Vec=Null Return
		x:-Vec.x
		y:-Vec.y
	EndMethod
	
	Method Multiply(_x:Float,_y:Float)
		x:*_x
		y:*_y
	EndMethod

	Method MultiplyVec(Vec:TVect2)
		If Vec=Null Return
		x:*Vec.x
		y:*Vec.y
	EndMethod
	
	Method Divide(_x:Float,_y:Float)
		If _x = 0 Or _y = 0 Return
		x:/_x
		y:/_y
	EndMethod

	Method DivideVec(Vec:TVect2)
		If Vec=Null Return
		x:/Vec.x
		y:/Vec.y
	EndMethod
End Type

AppTitle = "Ball Vector example"
Graphics 800 , 600

Local ballx:Float = 400
Local bally:Float = 550
Local ballvector:TVect2 = New TVect2.Create(1 , - 8) 
Local gravity:TVect2 = New TVect2.Create(0 , .1) 
Local bounceloss:TVect2 = New TVect2.Create(0 , 1)

While Not KeyHit(KEY_ESCAPE) 
	Cls
	If bally > 580 Then
		bally = 580	' once it's past this point just set it to the floor.
		ballvector.Rotate(180) 
		Local mag:Float = (ballVector.x * ballVector.x + ballVector.y * ballVector.y)
		If mag < 1.5 * 1.5 Then	' if the ball's velocity hits a certain minimum point just set it to zero to avoid 'vibrations'
			ballvector.x = 0
			ballvector.y = 0
		End If	
		ballvector.AddVec(bounceloss)
	End If
	
	ballvector.AddVec(gravity) 
	ballx:+ ballvector.GetX() 
	bally:+ ballvector.GetY()
	
	DrawOval ballx,bally,10,10
	
	
	Flip 1
Wend


A more 'proper' way would be to check for collisions before you move the ball's x/y position. You'd basically:
1. find the point of collision from the ball's position + ball's vector. 2. Set the ball there, and the 'remainder' of what ever the ball's vector is, you set it as the 'reflection. i.e. if the collision happened half way along the vector, then move the ball half way along that vector, then the remaining half you use to 'reflect' the ball.
3. rinse, repeat.


Yahfree(Posted 2008) [#3]
ok, thanks