I need to do a 2D isometric (though not necessarily 45-degree oriented) trajectory calculation for the launching of a projectile to hit a target I click on with the mouse; think throwing a grenade in X-Com.
Distance is always known. The program would need to perform calculations to find the angle and/or power or whichever is easiest - I'd not mind hardcoding or faking either as long as the result is that with gravity taken in account, the arcing projectile hits where I clicked.
I checked out
this
link mentioned in a previous post in the Programming section, but I'm not clear on how exactly these concepts translate into code yet.
The assumption is that the height of the launch would always happen from a constant height (say, 100) and the target would always be on a height of 0.
Here's a simplified version of what I've been pissing around with, sans pages of commented-out experimental nonsense.
If anyone can prod this code in the right direction then true awesomeness is yours forever.
Distance is always known. The program would need to perform calculations to find the angle and/or power or whichever is easiest - I'd not mind hardcoding or faking either as long as the result is that with gravity taken in account, the arcing projectile hits where I clicked.
I checked out
this
link mentioned in a previous post in the Programming section, but I'm not clear on how exactly these concepts translate into code yet.
The assumption is that the height of the launch would always happen from a constant height (say, 100) and the target would always be on a height of 0.
Here's a simplified version of what I've been pissing around with, sans pages of commented-out experimental nonsense.
Strict Graphics 800, 600, 0 Const GRAVITY:Float = 0.01 Global origin_x:Float = 100 Global origin_y:Float = 300 Global mouse_x:Float Global mouse_y:Float Global distance:Float Global angle:Float Global list:TList = CreateList() Repeat Cls If KeyDown(KEY_LEFT) origin_x:-1 If KeyDown(KEY_RIGHT) origin_x:+1 If KeyDown(KEY_UP) origin_y:-1 If KeyDown(KEY_DOWN) origin_y:+1 mouse_x = MouseX() mouse_y = MouseY() distance = getDistance( origin_x, origin_y, mouse_x, mouse_y ) angle = getAngle( origin_x, origin_y, mouse_x, mouse_y ) If MouseDown(1) ListAddLast( list, tObject.Create() ) EndIf '-- Draw the origin -- SetColor( 255, 255, 255 ) Plot( origin_x, origin_y ) '-- Draw and update all particles -- For Local obj:tObject=EachIn list obj.update() obj.draw() Next '-- Draw debug info -- SetColor( 255, 255, 255 ) DrawText("Distance from origin to mouse: "+distance, 0, 0) DrawText("OriginX: " + origin_x, 0, 10) DrawText("OriginY: " + origin_y, 0, 20) DrawText("Angle: " + angle + 180, 0, 30) Flip Until KeyHit(KEY_ESCAPE) Function getAngle( x1:Float, y1:Float, x2:Float, y2:Float) Local yDiff:Float = y2 - y1 Local xDiff:Float = x2 - x1 Local result:Float = ATan2( yDiff, xDiff ) If result < 0 Then result:+360 If result > 360 Then result:-360 Return result End Function Function getDistance:Float(x1:Float, y1:Float, x2:Float, y2:Float) Local x_diff:Float = x2 - x1 Local y_diff:Float = y2 - y1 Return Sqr( x_diff^2 + y_diff^2 ) End Function '--------------------- '--- Moving object --- '--------------------- Type tObject Field x_start:Float Field y_start:Float Field x:Float Field y:Float Field z:Float Field x_target:Float Field y_target:Float Field x_vel:Float Field y_vel:Float Field dist_target:Float Field original_distance:Float Field height:Float Field rot:Float Field time:Int Field speed:Float Field grav:Float Function Create:tObject() Local this:tObject= New tObject ' -- Velocity & speed vars -- this.original_distance = distance this.dist_target = distance 'TODO:Recalculate each frame? this.rot = angle 'TODO:Recalculate each frame? this.speed = 2 this.grav = GRAVITY 'TODO:Recalculate each frame? this.x_vel = 0 'TODO:Recalculate each frame? this.y_vel = 0 'TODO:Recalculate each frame? this.time = 0 this.height = 100 '-- Coordinate vars -- this.x_start = this.x this.y_start = this.y this.x = origin_x this.y = origin_y this.z = origin_y - this.height this.x_target = mouse_x this.y_target = mouse_y Return this End Function Method update() If time > 300 Or z >= y killMe() Return EndIf '-- Basic coords -- x:+speed * Cos(rot) y:+speed * Sin(rot) z = y - height '-- Coord modifiers -- height:-grav grav:+GRAVITY time:+1 End Method Method draw() SetColor( 255, 0, 0 ) Plot(x, y) SetColor( 255, 255, 255 ) Plot(x, z) End Method Method killMe() list.remove(Self) End Method End Type
If anyone can prod this code in the right direction then true awesomeness is yours forever.