Nice variation.
Redimensioning the window seems getting crazy some vehicle for a while but it's a nice looking situation
Ok, I edited this post, because I played around with some more changes, and the original post was junk.
Ignore the "Speed", though it is roughly scale to about 40 MPH on a 1/4 mile track.
There is a slight change to the formula that determines PUSH and TURN...
Oh, and it has the ships as an array... 30 to 330 (0 to 21 is the boxes?!?) Might be a bug, or just my bad programming. Seems the constants share the same values, with seporate names?
Took me a few tries to figure out why the triangles were chasing the boxes, and the boxes were chasing the boxes!
Just remember, there are two locations to change the value for the ships... One for the objects, and one for the motions.
[code=thinbasic]'
' Test of hovercraft AI
' Petr Schreiber, started on 09-26-2008
'
Uses "TBGL"
BEGIN CONST
' -- Scene IDs
%sScene = 1
' -- Entity IDs
%eCamera = 1
%eLight
%eHovercraft
%eWayPointStart
END CONST
GLOBAL FrameRate AS DOUBLE
FUNCTION TBMAIN()
LOCAL hWnd As DWORD
' -- Create and show window
hWnd = TBGL_CreateWindowEx("Test for hovercraft elemental AI", 800, 600, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
' -- Create scene
TBGL_SceneCreate(%sScene)
' -- Create basic entities
' -- Create camera to look from 15, 15, 15 to 0, 0, 0
TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 30)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)
' -- Create point light
TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 15, 10, 5)
TBGL_NewList 1
TBGL_UseLighting %FALSE
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Vertex -0.07, -0.14
TBGL_Vertex 0.07, -0.14
TBGL_Vertex 0.00, 0.14
TBGL_ENDPOLY
TBGL_UseLighting %TRUE
TBGL_EndList
' -- Create something to look at
TYPE tHoverCraft
nextWayPoint AS LONG
numWayPoint AS LONG
tolerance AS double ' -- Tolerance to reach waypoint
minSpeed AS double
maxSpeed AS double
steerFactor AS double
END TYPE
dim HoverInfo as tHoverCraft
LOCAL x AS LONG
FOR x = %eHovercraft + 30 TO %eHovercraft + 330
TBGL_EntityCreateDLSlot(%sScene, x, 0, 1)
TBGL_EntitySetColor(%sScene, x, RND(0,255), RND(0,255), RND(0,255))
' -- Assign data to it
with HoverInfo
.nextWayPoint = %eWayPointStart
.numWayPoint = 21
.tolerance = 0.7
.minSpeed = RND(100,150)*0.01
.maxSpeed = RND(400,450)*0.01
.steerFactor = RND(20,40)*0.01
END WITH
TBGL_EntitySetUserData(%sScene, x, HoverInfo)
next
local i as long
for i = %eWayPointStart to %eWayPointStart + 21
TBGL_EntityCreateBox(%sScene, i, 0, 0.1, 0.1, 0.1)
TBGL_EntitySetColor(%sScene, i, 255, 128, 0)
next
' -- Hardcoded waypoints
TBGL_EntitySetPos(%sScene, %eWayPointStart+0, -2, 2, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+1, 0, 6, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+2, 4, 8, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+3, 6, 5, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+4, 10, 0, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+5, 13, 1, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+6, 14, 6, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+7, 13, 8, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+8, 8, 11, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+9, -6, 10, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+10, -12, 8, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+11, -13, 6, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+12, -10, 3, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+13, -7, 1, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+14, -8, -3, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+15, -10, -6, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+16, -8, -8, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+17, -1, -9, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+18, 11, -10, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+19, 12, -8, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+20, 11, -6, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+21, 3, -2, 0)
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
LOCAL z AS LONG
' NOTE: Pointer offset from track-points
FOR z = %eHovercraft + 30 TO %eHovercraft + 330
HoverCraft_AI(z)
NEXT
'HoverCraft_AI(%eHovercraftMedium)
'HoverCraft_AI(%eHovercraftLazy)
TBGL_SceneRender(%sScene)
TBGL_DrawFrame
' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
END FUNCTION
Sub HoverCraft_AI( entity AS LONG )
local hoverData AS tHoverCraft ptr
' -- Retrieve data from entity
hoverData = TBGL_EntityGetUserDataPointer(%sScene, entity)
' -- Get angle and distance to next waypoint
LOCAL angle AS DOUBLE = TBGL_EntityGetAngleXY(%sScene, entity, hoverData.nextWayPoint, %TBGL_Y) ' -- The front part is on Y axis
local distance as double = TBGL_EntityGetDistance(%sScene, entity, hoverData.nextWayPoint)
' -- Move according to parametrization
TBGL_EntityTurn(%sScene, entity, 0, 0, (hoverData.steerFactor*(min(hoverData.minSpeed+(distance*9), hoverData.maxSpeed*3))*angle)/FrameRate)
TBGL_EntityPush(%sScene, entity, 0, min(hoverData.minSpeed+(distance*9), hoverData.maxSpeed)/FrameRate, 0)
' -- Check for next waypoints
IF distance < hoverData.tolerance then
if hoverData.nextWayPoint < %eWayPointStart+hoverData.numWayPoint then
incr hoverData.nextWayPoint
else
hoverData.nextWayPoint = %eWayPointStart
END IF
END IF
END SUB[/code]
Nice variation.
Redimensioning the window seems getting crazy some vehicle for a while but it's a nice looking situation
www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000
Eros, I just reposted an update...
The values before... were throwing the vehicles into "Slow mode" about 1/2 way between points. Once they passed a point, they sling-shot into full speed again. (That still needs adjustment.)
I altered the code, so they are about 80% near a point, before they attempt to slow-down, for the turn.
I also used a similar adjustment, taking the speed/distance into the turn/steer value... They have slight more control, if they are going slower... (Unless I did that backwards, then they are loosing control by going slower.)
I don't know how to get the speed value yet, so I just guessed.
It looks correct, as a flock. (Remember that is not full-scale, so a width the size of a triangle is actually about 2 cars wide.)
They pull tight on a line, and sling-shot with good variation on an attempted turn. (I like the swirls when the code is buggy, an they can't turn enough. LOL... Hover-vortex!)
uuuhh very nice looking
A lot of ... cars
There are still AI problems when window is sized or even moved but it is a pleasure to look at this example.
I can see cars move into some kind of groups maybe because they share similar behaves.
www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000
Hi Jason,
nice tweak! To get "real speed" is very easy.
I would recommend to stick with SI units for this project - so then 1.0 length unit = 1.0 meter.
Then when you
[code=thinbasic]
TBGL_EntityPush(%scene, %entity, 0, 0, 10/Framerate)
[/code]
... your vehicle moves at 10 meters/second.
One thing you will like, instead of:
[code=thinbasic]
.minSpeed = RND(100,150)*0.01
[/code]
you can use floating point random number generator:
[code=thinbasic]
.minSpeed = RNDF(1,1.5)
[/code]
Each entity should have different id, you can simply do following instead of hardcoding numeric literals:
[code=thinbasic]
BEGIN CONST
' -- Scene IDs
%sScene = 1
' -- Limits
%maxHoverCrafts = 100 ' -- Set how many hovercrafts do you want here
%maxWayPoints = 21 ' -- Set how many waypoints do you want here
' -- Entity IDs
%eCamera = 1
%eLight
%eHovercraftStart
%eHovercraftEnd = %eHovercraftStart + %maxHoverCrafts - 1
%eWayPointStart = %eHovercraftEnd + 1
%eWayPointEnd = %eWayPointStart + %maxWayPoints - 1
END CONST
[/code]
Then the final code ( now with random track, heh ) looks like:
[code=thinbasic]
'
' Test of hovercraft AI, v2
' Petr Schreiber, started on 09-26-2008
'
Uses "TBGL"
BEGIN CONST
' -- Scene IDs
%sScene = 1
' -- Limits
%maxHoverCrafts = 100 ' -- Set how many hovercrafts do you want here
%maxWayPoints = 21 ' -- Set how many waypoints do you want here
' -- Entity IDs
%eCamera = 1
%eLight
%eHovercraftStart
%eHovercraftEnd = %eHovercraftStart + %maxHoverCrafts - 1
%eWayPointStart = %eHovercraftEnd + 1
%eWayPointEnd = %eWayPointStart + %maxWayPoints - 1
END CONST
GLOBAL FrameRate AS DOUBLE
FUNCTION TBMAIN()
LOCAL hWnd As DWORD
' -- Create and show window
hWnd = TBGL_CreateWindowEx("Test for hovercraft elemental AI, v2", 800, 600, 32, %TBGL_WS_WINDOWED or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
' -- Create scene
TBGL_SceneCreate(%sScene)
' -- Create basic entities
' -- Create camera to look from 15, 15, 15 to 0, 0, 0
TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 30)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)
' -- Create point light
TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 15, 10, 5)
%listVehicle = 1
TBGL_NewList %listVehicle
TBGL_UseLighting %FALSE
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Vertex -0.07, -0.14
TBGL_Vertex 0.07, -0.14
TBGL_Vertex 0.00, 0.14
TBGL_ENDPOLY
TBGL_UseLighting %TRUE
TBGL_EndList
' -- Create random waypoints
local w as long
for w = %eWayPointStart to %eWayPointEnd
TBGL_EntityCreateBox(%sScene, w, 0, 0.1, 0.1, 0.1)
TBGL_EntitySetColor(%sScene, w, 255, 128, 0)
TBGL_EntitySetPos(%sScene, w, rndf(-15, 15), rndf(-10, 10), 0)
next
' -- Create something to look at
TYPE tHoverCraft
nextWayPoint AS LONG
numWayPoint AS LONG
tolerance AS double ' -- Tolerance to reach waypoint
minSpeed AS double
maxSpeed AS double
steerFactor AS double
END TYPE
dim HoverInfo as tHoverCraft
LOCAL h AS LONG
local x, y, z as double
TBGL_EntityGetPos(%sScene, %eWayPointStart, x, y, z)
FOR h = %eHovercraftStart TO %eHovercraftEnd
TBGL_EntityCreateDLSlot(%sScene, h, 0, %listVehicle)
TBGL_EntitySetColor(%sScene, h, RND(0,255), RND(0,255), RND(0,255))
' -- Start position relative to first waypoint
TBGL_EntitySetpos(%sScene, h, x+RNDf(-0.1,0.1), y-RNDf(0.1,0.2), 0)
' -- Assign data to it
with HoverInfo
.nextWayPoint = %eWayPointStart
.numWayPoint = %maxWayPoints
.tolerance = 0.7
.minSpeed = RNDF(1.0,1.5)
.maxSpeed = RNDf(4,4.5)
.steerFactor = RNDf(0.2,0.4)
END WITH
TBGL_EntitySetUserData(%sScene, h, HoverInfo)
next
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
FOR h = %eHovercraftStart TO %eHovercraftEnd
HoverCraft_AI(h)
NEXT
TBGL_SceneRender(%sScene)
TBGL_DrawFrame
' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
END FUNCTION
Sub HoverCraft_AI( entity AS LONG )
local hoverData AS tHoverCraft ptr
' -- Retrieve data from entity
hoverData = TBGL_EntityGetUserDataPointer(%sScene, entity)
' -- Get angle and distance to next waypoint
LOCAL angle AS DOUBLE = TBGL_EntityGetAngleXY(%sScene, entity, hoverData.nextWayPoint, %TBGL_Y) ' -- The front part is on Y axis
local distance as double = TBGL_EntityGetDistance(%sScene, entity, hoverData.nextWayPoint)
' -- Move according to parametrization
TBGL_EntityTurn(%sScene, entity, 0, 0, (hoverData.steerFactor*(min(hoverData.minSpeed+(distance*9), hoverData.maxSpeed*3))*angle)/FrameRate)
TBGL_EntityPush(%sScene, entity, 0, min(hoverData.minSpeed+(distance*9), hoverData.maxSpeed)/FrameRate, 0)
' -- Check for next waypoints
IF distance < hoverData.tolerance then
if hoverData.nextWayPoint < %eWayPointEnd then
incr hoverData.nextWayPoint
else
hoverData.nextWayPoint = %eWayPointStart
END IF
END IF
END SUB
[/code]
Petr
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
Nice Jason. With 10 vessels I get around 320 FPS. That is a good value.
Interesting that some of them go on a different path on some points but on the whole very good.
Home Desktop : Windows 7 - Intel Pentium (D) - 3.0 Ghz - 2GB - Geforce 6800GS
Home Laptop : WinXP Pro SP3 - Intel Centrino Duo - 1.73 Ghz - 2 GB - Intel GMA 950
Home Laptop : Windows 10 - Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz, 2401 Mhz, 2 Core(s), 4 Logical Processor(s) - 4 GB - Intel HD 4400
Work Desktop : Windows 10 - Intel I7 - 4 Ghz - 8GB - Quadro Fx 370
To ISAWHIM
I was discussing with Petr about an abnormal memory consumption produced by your script (see task manager when script is under execution).
At first we thought is was thinCore engine or TBGL module not releasing all the memory. But Petr discover you have the following line inside WHILE/WEND:
[code=thinbasic]LOCAL z AS LONG[/code]
The above line inside a WHILE/WEND loop continuously allocates bytes.
I'm making changes to thinBasic Core engine in order to generate a runtime error and trap this situation.
In the meantime, can you move the above line outside the WHILE/WEND loop?
Ciao
Eros
www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000
I didn't realize that %constantval = 100 was the same as MyVal(100)... (That is where I was having trouble, it kept saying constant exists, or it used %constant1 as %constant2, even though I typed %constant1 when trying to use %constatnt1+x)
LOCAL DIM situation noted... (I just put that there, to play with the path code.) Also noted the Float Random version. (Comes in handy for testing. But old habits die hard. TY.)
I have a more suitable set of code with slight more physics. (Should output non-scaled values, which would be scaled.) Once the game has set limits... But until then, I am using time and size as my only scale. (1 in my code is closer to 10 yards.)
How is collision detection coming? Until that becomes a generic function, I will use that XY_Distance for quick bubble collision. (Going back to 8 cars... I put about 1000 to check for track/formula spread, and to try to catch LOOPERS.)
The new code will never have a looper... I am adjusting the speed so if the ABS(ANGLE) is > (DISTANCE * Xmod), they attempt to slow-down and being slower has a formula trait of being able to turn more, but not beyond a certain point. In the game, that would only be a suggestion of possible moves. The actual AI output, depending on SKILL_VALUE would take a value close, but not exactly that value. The greatest attribute I have added is POWER and SPEED and WEIGHT. (Power being the engine size factor, Speed being the actual velocity, and Weight being a mod of all the physics as mass. Thus, the AI now has a physics code to react to.)
I am also creating a second "tolerance", but those are now part of the track values.
The point is irrelevant, except as a suggestive location/point value. The point has three levels, only two values. PointTargetArea, and PointTrackWidth. The third level is just larger than PointTrackWidth, and it is just the remainder of distance to travel. I am reversing the formula a little, and using the... (DISTANCE(XY_LAST to XY_NEW) - PointTrackWidth) to determine the area where the AI tries to find a new point. That draws a large circle around the last point, and once that point has been left, within the new point limit... it is safe to find a new point to chase, depending on the new points angle, from the point being chased now. (That allows them to change direction faster on an outside turn, where the tend to LOOP now.)
I am having the AI look ahead one more point, to see if the track is turning or going in a line. If it is turning, it adjusts speed, and begins to turn early. Otherwise it is going in a line, and will attempt to MAX speed.
Ok, here is another modification/setup...
This uses SOME of what I believe will be the required craft elements. (You don't have to save it, but you might be able to use something from it.)
I made note of most of the changes, and where I was headed for the physics part. For the AI part, I have added part of the one-point ahead looking. (I tried to use petr's method for the height, but I did not have any luck with it.)
Until I have a map-file to test, I will be adding a raised map from a BMP image. The points work within +/- 3 meters, for the most part. (The "Looping", is a side-effect, which I mention in the code, of using FrameTime to change the angle. That is why they looped on some systems, but not on mine. The faster the frame-time, the more precise the turn. The slower the FrameTime, the more sloppy the turn. Physics will fix that.)
System resources with only 8 cars, was 2% to 5% AVG. (Added a DoEvents to return the loop processing to the PC. Working on a better arrangement for that main loop. But this is OK for my testing.)
Added a real counter, to display the FPS on the title bar, and added some CHASE code, for a camera, to watch the paths. Instructions on the title bar, mouse controls.
AVG FPS with 300 cars, is 53.10 FPS (CPU near 85%)
AVG FPS with 100 cars, is 140.78 FPS (CPU near 55%) (Graphics begin to drop-out? Triangle holes in floor.)
AVG FPS with 8 cars, is 630.45 FPS (CPU near 2%) (Didn't see as much graphic drop-out.)
Full width is about 700 meters or about 0.44 miles wide... Not sure what craft-speed is... but that is the world and view dimensions/scale. (AI crafts are 1 meter wide and tall, and 2 meters long.)
Once the physics are in place, you only have to define the world values.
General world values, to all...
- Gravity Force (GF = 1.0000) Airbourn fall acceleration.
- Air Resistance (AF = 1.0000) Time decay of all forces except gravity.
- Collision AngleForce (CA = 1.0000) Specific to (Player/AI to World).
Player specific values, of world...
- MaxImpact Force (IF = 1.000) More = we are solid, Less = we are rubber. Specific to (Player to Player).
- MaxEngine Force (EF = 400.0) Power, not speed.
- - MaxPush Force (PF = calculated) 50% + Percent unused from diversions below.
- - MaxTurn Force (TF = 100.0) Limit of power used from engine as a percent. (100 is 25% of E)
- - MaxDrift Force (D = 100.0) Limit of power used from engine as a percent. (100 is 25% of E)
Speed is calculated in the game, not a value.
Damage value is calculated, not specific.
etc...
Beyond that, there is only the thinking left to do... (Where to go, and how to get there.)
[code=thinbasic]'
' Test of hovercraft AI
' Petr Schreiber, started on 09-26-2008
'
Uses "TBGL"
HiResTimer_Init
GLOBAL xHRT_Old, xHRT_New AS QUAD ' Used to calculate actual frame rate.
xHRT_Old = HiResTimer_Get
' NOTE: Having a frame upper limit, helps to ensure that sufficient time has passed
' before doing further calculation on insignificant game factors. Collision, Gravity,
' Air Resistance, Memory Dumping, Interruption, Key Calls, Drawing...
GLOBAL xGFV AS QUAD = (1/60)*1000000 ' Frame value, calculated for the QUAD HighResTimer loop
GLOBAL xGFR AS DOUBLE ' Game Frame Rate (Time-Slice)
GLOBAL PointCount AS LONG = 21 ' Change with new points, also change %eWayPointStart value
GLOBAL CraftCount AS LONG = 8 ' Change with new crafts, also change %eHovercraft value
GLOBAL TrackWidth AS DOUBLE = 8 ' 5 meters wide 10 meter diameter
GLOBAL cX, cY, cZ AS DOUBLE ' Used for camera positions
GLOBAL hWnd AS DWORD
' -- Scene IDs
BEGIN CONST
%sScene = 1
END CONST
' -- Entity IDs
BEGIN CONST
%eCamera = 1
%eLight = 2
%eGroundBase = 3
%eWayPointStart = 21
%eHovercraft = 8
END CONST
FUNCTION TBMAIN()
' -- Create and show window
hWnd = TBGL_CreateWindowEx("Test for hovercraft elemental AI", 800, 600, 32, %TBGL_WS_WINDOWED OR %TBGL_WS_CLOSEBOX OR %TBGL_WS_DONTSIZE)
TBGL_ShowWindow
TBGL_UseTexturing %TRUE
' -- Create scene
TBGL_SceneCreate(%sScene)
TBGL_SetDrawDistance(800)
' -- Create camera
TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 700)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)
' -- Create light
TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 0, -100, 100)
' -- Create Ground
'TBGL_LoadTexture("ground.bmp", 1, %TBGL_TEX_MIPMAP)
TBGL_EntityCreateBox(%sScene, %eGroundBase, 0, 800, 600, 10) ' Change to "(%sScene, %eGroundBase, 0, 800, 600, 3, 1)" for texture map.
TBGL_EntitySetColor(%sScene, %eGroundBase, 100, 155, 100)
TBGL_EntitySetPos(%sScene, %eGroundBase, 0, 0, -7)
' -- Craft Model Data
TBGL_NewList 1
TBGL_UseLighting %FALSE
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Vertex -1, -2, 0
TBGL_Vertex 1, -2, 0
TBGL_Vertex 0, 2, 0
TBGL_ENDPOLY
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Vertex -1, -2, 0
TBGL_Vertex 0, -2, 1
TBGL_Vertex 0, 2, 0
TBGL_ENDPOLY
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Vertex 0, -2, 1
TBGL_Vertex 1, -2, 0
TBGL_Vertex 0, 2, 0
TBGL_ENDPOLY
TBGL_UseLighting %TRUE
TBGL_EndList
' -- Create Craft Format
TYPE tHoverCraft
nextWayPoint AS LONG
thisWayPoint AS LONG
numWayPoint AS LONG
mass AS double
velocity AS double
force AS double
angleXY AS double
angleXZ AS double
angleYZ AS double
END TYPE
DIM HoverInfo AS tHoverCraft
' -- Create Random Crafts
LOCAL x AS LONG
FOR x = %eHovercraft TO %eHovercraft + CraftCount
TBGL_EntityCreateDLSlot(%sScene, x, 0, 1)
TBGL_EntitySetColor(%sScene, x, RND(0,255), RND(0,255), RND(0,255))
' -- Assign data to it
WITH HoverInfo
.nextWayPoint = %eWayPointStart+RND(1,21) ' Where am I going next
.thisWayPoint = %eWayPointStart-1 ' Where am I now
.numWayPoint = PointCount ' Not sure if this is used, or relevant (Game value not craft value.)
.mass = RNDF(0.80, 1.00) ' Not used yet
.velocity = RNDF(0.80, 1.00) ' Not used yet
.force = RNDF(0.10, 1.00) ' Not used yet
.angleXY = RND(-180, 180) ' Not used yet
.angleXZ = RND(-180, 180) ' Not used yet
.angleYZ = RND(-180, 180) ' Not used yet
END WITH
TBGL_EntitySetUserData(%sScene, x, HoverInfo)
TBGL_EntitySetPos(%sScene, x, 0, 0, 0)
NEXT
' -- Setup Track Points
LOCAL i AS LONG
FOR i = %eWayPointStart TO %eWayPointStart + PointCount
TBGL_EntityCreateBox(%sScene, i, 0, 1, 1, 4)
TBGL_EntitySetColor(%sScene, i, 255, 128, 0)
NEXT
' -- Hardcoded waypoints
' This is a SUPER LONG track. 1 = 1 meter. Full width is about 700 meters or about 0.44 miles wide.
' Scale speed
TBGL_EntitySetPos(%sScene, %eWayPointStart+0, -50, 50, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+1, 0, 150, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+2, 100, 200, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+3, 150, 125, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+4, 250, 0, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+5, 325, 25, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+6, 350, 150, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+7, 325, 200, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+8, 200, 275, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+9, -150, 250, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+10, -300, 200, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+11, -325, 150, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+12, -250, 75, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+13, -175, 25, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+14, -200, -75, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+15, -250, -150, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+16, -200, -200, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+17, -25, -225, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+18, 275, -250, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+19, 300, -200, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+20, 275, -150, 0)
TBGL_EntitySetPos(%sScene, %eWayPointStart+21, 175, -50, 0)
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Main loop
xGFR = TBGL_GetFrameRate ' Initializes framerate, or value = 1, That is bad.
GLOBAL z AS LONG
GLOBAL xFrameTimeCount AS DOUBLE
GLOBAL xFrameTimeTotal AS DOUBLE
While TBGL_IsWindow(hWnd)
DoEvents
xGFR = TBGL_GetFrameRate
IF xGFR < 2 THEN xGFR = TBGL_GetFrameRate ' Stops FrameMove issue
xHRT_New = HiResTimer_Get
INCR xFrameTimeCount
xFrameTimeTotal += xGFR
IF xHRT_New - xHRT_Old >= (xGFV * 60) THEN
TBGL_SetWindowTitle(hWnd, "(Hold LMB = Follow Car#1), (Hit RMB = Reset TopView), " & "(AVG FPS: " & FORMAT$(xFrameTimeTotal/xFrameTimeCount, "#0.00") & "), (SECONDS: " & FORMAT$(xFrameTimeTotal, "#0.00") & " / FRAMES: " & STR$(xFrameTimeCount) & " )")
xFrameTimeCount = 0
xFrameTimeTotal = 0
xHRT_Old = xHRT_New
END IF
TBGL_ClearFrame
FOR z = %eHovercraft TO %eHovercraft + CraftCount
HoverCraft_AI(z)
NEXT
' This is NOT the camera-follow I am looking for, but it works for now.
IF TBGL_GetWindowKeyState(hWnd, %VK_LBUTTON) THEN
TBGL_SetDrawDistance(400)
TBGL_EntityGetPos(%sScene, %eHovercraft, cX, cY, cZ, %TRUE)
TBGL_EntitySetPos(%sScene, %eCamera, cX, cY -80, cZ +40)
TBGL_EntitySetTarget(%sScene, %eCamera, %eHovercraft)
END IF
IF TBGL_GetWindowKeyState(hWnd, %VK_RBUTTON) THEN
TBGL_SetDrawDistance(800)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 700)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)
END IF
TBGL_SceneRender(%sScene)
TBGL_DrawFrame
' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_SceneDestroy(%sScene)
TBGL_DestroyWindow
END FUNCTION
Sub HoverCraft_AI( entity AS LONG )
LOCAL hoverData AS tHoverCraft PTR
' -- Retrieve data from entity
hoverData = TBGL_EntityGetUserDataPointer(%sScene, entity)
' -- Get angle and distance to next waypoint
' This will be the LOOKING that the vehicles will do, to determine if they are going to veer left/right
' also, the distance from will be compared to the distance between points, to determine if the vehicle
' should speed-up or slow-down, and identify how far off-track they are.
LOCAL angle AS DOUBLE = TBGL_EntityGetAngleXY(%sScene, entity, hoverData.nextWayPoint, %TBGL_Y) ' -- The front part is on Y axis
LOCAL distanceTo AS DOUBLE = TBGL_EntityGetDistance(%sScene, entity, hoverData.nextWayPoint)
LOCAL distanceFrom AS DOUBLE = TBGL_EntityGetDistance(%sScene, entity, hoverData.thisWayPoint)
' This is my crude point cycle code and general direction adjustments.
' TrackWidth is the radius of the point-elbow. The above code, when finished, will not use a simple
' radius to make a destination change, it will know that a point has been passed, not neared.
' The ELSE is a simple check, which will also be modified, and used to trigger a slow-down and turn
' as it approaches a destination point, prior to reaching it.
IF distanceTo < TrackWidth THEN
incr hoverData.thisWayPoint
incr hoverData.nextWayPoint
IF hoverData.thisWayPoint > %eWayPointStart + PointCount THEN hoverData.thisWayPoint = %eWayPointStart
IF hoverData.nextWayPoint > %eWayPointStart + PointCount THEN hoverData.nextWayPoint = %eWayPointStart
ELSE
' Bad code, trying to keep them from looping... Almost works as expected, I am using the wrong points
IF distanceFrom > (distanceFrom - (TrackWidth * 2)) THEN distanceTo = xGFR * 0.6
END IF
' This is NOT the physics, just code to keep them moving...
' This is where all the translated physics will output. The result will be the new "Forces", which will
' be used to determine the NEXT locations. The physics will also perform the collision of the expected
' output location, and those adjustments will be the final output which is used for movement.
' PUSH will be the output of FORCE, including Velocity and Mass.
' TURN XZ will be the output of FORCE-ANGLE, including Velocity and Mass.
' TURN Y will be the output of GROUND-ANGLE or GRAVITY, whichever applies.
' The camera should follow the player, with a little lag on TARGET and on POSITION
' but should always be between the player and the OLD point, along the track.
' The player should be able to spin-around 360deg, and the camera looks forward,
' in the direction that the player should be driving. That will help with slightly better
' conrol, and should reduce screen jitter from hard overturning.
TBGL_EntityTurn(%sScene, entity, 0, 0, (angle * distanceTo * 0.1)/xGFR)
' Dividing the angle by framerate causes issues...
' If frame rate is high, you turn fast and sharp, if framerate is low, you turn wide (Seen by adding many cars.)
' That would result in two people playing the same game, but the faster computer will have more precision.
' This will be replaced by a calculation of FORCE, and the AI selection of controls to combat that force over time.
TBGL_EntityPush(%sScene, entity, 0, (hoverData.velocity * 50 + (distanceTo * 0.1))/xGFR, 0)
END SUB
[/code]
Bookmarks