Dark Bit Factory & Gravity
PROGRAMMING => Other languages => Blitz => Topic started by: JumpMan on June 02, 2007
-
Hi everyone:
lately I have been working on creating my own chasser missiles for a game. I think what I got is somewhat decent. The problem is, if I try to make it faster, it does not give me the responce I want. I want to make it move faster but with the same small radius turn. I have provided the code and executable. I apreciate a fix, alternative solution, or a better algorith.
SuperStrict
Framework BRL.GLMax2D
Import BRL.Random
Const Acceleration# = 00.5
Const TopSpeed# = 05.0
Const TurnAcceleration# = 01.0
Const TurnMax# = 10.0
Local Missiles% = 30
Local Missile:TMisile[Missiles] ' create missiles
Local streak:tstreak[Missiles] ' create streak for missiles
Graphics 800,600,32,60
Global width% = GraphicsWidth()
Global height% = GraphicsHeight()
SetBlend alphablend
glEnable(GL_LINE_SMOOTH) 'Quick antaliasing hack
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST)
glLineWidth(3.0)
' create missiles and streaks.
For Local i% = 0 To Missiles-1
Missile[i] = TMisile.create(Rand(700)+50,Rand(500)+50,Rand(360))
streak[i] =tstreak.create(Missile[i].x,Missile[i].y,Rand(255),Rand(255),Rand(255))
Next
SeedRnd MilliSecs()
Local z% = 0 'A dirty speed hack
Repeat
SetColor 20,200,40
DrawText "Press (esc) to exit",300,30
For Local i% = 0 To Missiles-1
Missile[i].update(MouseX(),MouseY())
streak[i].add(Missile[i].x,Missile[i].y)
streak[i].draw()
Next
If z Flip() ' Dirty speed hack by skipping a sync cycle
Cls
z=1-z 'dirty speed hack
Until KeyHit(key_escape)
'
' Resources
'-----------------------------------------------------------------------------------
'
Type Tpoint
Field x#
Field y#
End Type
' used to draw a streak.
'Note: does become jugged If points are separated To far And
' angles are set sharp.
Type Tstreak
Field list:TList
Field lastpoint:tpoint
Field active%
Field Red%,Green%,Blue%
Function create:tstreak(x#,y#,Red%,Green%,Blue%)
Local s:tstreak = New tstreak
Local p:tpoint = New tpoint
If Not s.list Then
s.List = CreateList()
s.lastpoint = New tpoint
s.active = True
EndIf
p.x = x
p.y = y
s.list.addlast(p)
s.lastpoint.x = p.x
s.lastpoint.y = p.y
s.Red = Red
s.Green = Green
s.Blue = Blue
Return s
End Function
' adds a segment to a streak.
Method add(x#,y#)
If list.count()>50 active = False; Return
Local p:tpoint = New tpoint
p.x = x
p.y = y
list.addlast(p)
lastpoint.x = p.x
lastpoint.y = p.y
End Method
'
Method draw%()
If Not list.count() Return -1
If list.count() > 1 Then
Local Alpha# = 0.0
Local p1:Tpoint = Tpoint(list.first())
SetColor Red,Green,Blue
For Local p2:tpoint = EachIn list
If p2<>p1 Then
SetAlpha alpha
DrawLine(p1.x,p1.y,p2.x,p2.y,False)
p1 = p2
EndIf
alpha :+.02
Next
EndIf
If Not active list.remove(list.first())
End Method
End Type
Type TMisile
Field Red%
Field Green%
Field Blue%
Field x#,y#
Field DirectionX#,DirectionY#
Field XS#,YS#
Field Done:Int
Field Degree#
Field Direction#
Field TurnSpeed#
Field GoLeft%
Field GoRight%
Function create:TMisile(x#,y#,dir#)
Local s:TMisile = New TMisile
s.x = x
s.y = y
s.Direction = Dir
s.Done = False
s.Red = 200
s.Green = 0
s.Blue = 0
Return s
End Function
'Used To Draw Missile (currently unused)
Method draw() ' used to draw missile
' use from field in type
' x, y -- is the current missile position also used for head of streak
'direction -- is the angle the missile is facing in degrees.
End Method
' Target chassing logic
Method Update%(nx%,ny%)
'Set acceleration
XS:+ Cos(Direction)*Acceleration
YS:+ Sin(Direction)*Acceleration
Local CurrentSpeed# = Sqr(XS*XS + YS*YS)
If CurrentSpeed > TopSpeed
XS:+ (XS/CurrentSpeed)*(TopSpeed - CurrentSpeed)
YS:+ (YS/CurrentSpeed)*(TopSpeed - CurrentSpeed)
EndIf
X:+ XS
Y:+ YS
'Set Rotation
Local distance# = Sqr((x-nx)^2+(y-ny)^2) '
Local TargetAngle# = (ATan2(y-ny,x-nx)+180.0) Mod 360.0
Local difference# = TargetAngle-Direction
'turn toward target
If TargetAngle < Direction
If Abs(difference) > 180.0 TurnSpeed:+TurnAcceleration Else TurnSpeed:-TurnAcceleration
ElseIf TargetAngle > Direction
If Abs(difference) > 180.0 TurnSpeed:-TurnAcceleration Else TurnSpeed:+TurnAcceleration
EndIf
'If found stop turning
If Abs(difference) < 1.0 TurnSpeed = 0.0
'Limit TurnSpeed
If TurnSpeed > TurnMax TurnSpeed = TurnMax
If TurnSpeed < -TurnMax TurnSpeed = -TurnMax
Direction = (Direction+TurnSpeed+360) Mod 360
EndMethod
End Type
-
It looks pretty cool to me! Are you saying that if you increase TopSpeed then it doesn't work quite the same?
I don't have BlitzMax so I can't do much experimentation.
Your code seems to rely on the Flip for timing. It might be better if the movement equations incorporated the delta time as a variable, to deal with all different machines.
Jim
-
These are my test results:
If I increase Acceleration to double, the turning radius become smaller its good but the path becomes more circular and that is not what I want.
If I increase TopSpeed to double, the Distance before turning becomes twice as long and then it gives some ugly sharp turns.
If I increase TurnAcceleration it finds the target from a far distance but at closerange it becomes an orbiting object never reaching the target.
and a combination of either don't give better results.
the flip hack was just a frustrating move on my part. never really intended for actual use.
-
I made some changes to the code, and Made it some what Plausable. I figured that even if I use a delta the steps between points my be to large for it to look smooth. And If I change any of the numbers in the constants I get a distorted result. Then my only option is to increase the number of points to calculate per game cycle(flip()). with this I can 2x,3x,4x.... the speed per cycle. not the best solution but now I can do what I intended it for.
still if any body has a better solution I am down for it.
I included the source in case it's usefull for someones demo.
-
Heres a though, I once tried to code 3d battleships in Delphi, but never go very far with it, appart from the missile projection from one ship to another.
The way I went about it was to use bezier lines. This produced nice paths for the missile to follow, and is a very easy and quick to implement, and is always bang on target :)
EDIT
Having ran the exe (very cool btw :kewl: ) this wouldnt be a practical alternative.
-
->JumpMan
What happens if you just run the logic twice per frame? If that works, what does it tell you about how to code it in a single pass? Just an idea.
Jim
-
Tetra- Thanks for the appreciation. Believe it or not the bezier curve was my original attempt at this but was not giving me the results I was looking for. That is why, I started doing it this way.
Jim - I Just don't see your point. Maybe I am Comfused. When I think about the options all I see is just to multiply everithing by 2 or 3 or n. That would make the spacing larger making it look like connected lines instead of a nutural curve shape. Am I missing something?
-
Well, if you run it twice, you get
move
turn
move
turn
which will make things twice as fast. If you just multiply everything by 2, you get
move
move
turn
turn
or
move x 2
turn x 2
which isn't what you wanted.
That's all - no big insight :)
Jim
-
Thanks Tetra & Jim for your interest in helping.
JP
-
I just found out Thre is a Bug in the code Thats Also why it behaves so erregular. But Sence it looks good that way, I am not going to fix it...
now I can continue on improving it when I am completely done with it I will post the complete code.