soz, but pathfinding looks too big and hard thing atm for me, so i may add it some day later
i have just updated program to these features:
*Load map
*Select objects
*Move camera
*Move objects to point on map
*Follow enemies and friendly differently
*Smooth rotation and speed until reach target
*Added 2 sprites and text over them
here is the code(with even more comments):
Remstart
Today, February 01, 2011, 8:31:10 PM
Project: Terrain
*Load map
*Select objects
*Move camera
*Move objects to point on map
*Follow enemies and friendly differently
*Smooth rotation and speed until reach target
*Added 2 sprites and text over them
Remend
`--- Constants ---
#constant UnitCount 200
#constant VehiclesCount 100
#constant OtherObjectCount 100
#constant FollowDistance 500.0 `this is squared (^2)
`because square root in get_distance function would slow down program a little
`--- Types ---
type Units `u can add more stats in here, atm for program work need only "target" variable
name as string
Team as integer
hp as integer
dmg as integer
MaxSpeed as float
Speed as float
traction as float `acelleration
RotationSpeed as float `how fast object rotates
Range as float `attack range- distance in which attacked object will be followed
MoveTarget as integer `Object to be followed
AttackTarget as integer `Object to be attacked
IsMoving as integer `if is moving
IsFollowing as integer `if is following
Dx as float `destination coordinates
Dy as float
Dz as float
endtype
`--- Variables ---
global activeID as integer `selected object number
global TotalUnitCount as integer `total number of Your controllable units
TotalUnitCount= UnitCount + VehiclesCount
`--- Arrays ---
`array of all your controlable objects (units, soldiers, robots or whatever u use in game
dim Unit(TotalUnitCount) as units
`------------------------------------------------------------------------------------------
`--- Program start ---
`------------------------------------------------------------------------------------------
Setup() `program setup
TerrainSetup() `make and set up terrain
LoadMenuPanel() `load sprites for in game menu
MakeBoxes() `make random objects just for testing, remove later
MakeSelectionIndicator() `make objects to be shown above selected objects
`and at their destination coordinates
`------------------------------------------------------------------------------------------
`--- Main Loop ---
`------------------------------------------------------------------------------------------
do
`camera movement
MoveCamera()
`left mouse click: select object
if mouseclick()= 1 then activeID= SelectObjects()
`place indicators over selected object and its target position
`(can load your own object like sword, target sign and etc.)
SelectionIndicator(activeID)
`right mouse click: set active object's target as a point on map or other object
if mouseclick()= 2 then MakeTarget()
`When all actions are made its time to move all the objects (if they should move ofc)
MoveObjects()
`paste sprites and later print text, so text don't disappear behind sprites
`thx to Phaelax
`more about text over sprites here:
`http://forum.thegamecreators.com/?m=forum_view&t=171622&b=1
RefreshSprites()
`when u encounter problems with new functions added, print variables to see
`if your functions give right answers, very usefull for debugging
Info()
`Selected object/unit info
ObjectInfo()
update terrain `apply all the changes to terrain
sync `apply all the changes to screen
loop
`------------------------------------------------------------------------------------------
`--- Functions and procedures ---
`------------------------------------------------------------------------------------------
function Setup()`program setup
sync on `automatic screen refresh on
sync rate 500 `refresh rate (i think it is times per second)
`i set such a high rate to see what highest actual frame rate my pc can reach
`i dont know what rate is recomemnded, but mostly used in tutorials it is 60 or 90
`when new objects are created camera isnt positioned at coordinates of new object
autocam off
`width and height in pixels and how much colors will contain
`(not sure but should be 16 or 32 bits)
set display mode 1024,768,32
set camera range 10,10000 `how far objects will be visible from 10 units to 10000 units
Fog on `u know what fog is :D
Fog distance 15000 `this is distance in which u can't see anything through fog
`it makes less colorful objects in smaller distance too
`if u remove fog, skybox will be very bright
Fog color RGB(128,128,128) `fog color- grey
maximize window `make full screen
randomize timer() `set starting value for random() function
`every time u run program random numbers will be different
xrotate camera 20 `point camera little down
`hide mouse `U can hide mouse cursor if want. I like to see it :P
`later U can put some image instead of cursor i.e. target
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function TerrainSetup() `make and set up terrain
set dir "media\DefaultMap\" ` set the directory to map's location (2 levels higher)
` load base and detail texture
load image "texture.bmp", 1
load image "detail.tga", 2
make object terrain 1 ` create the terrain object
set terrain heightmap 1, "map.bmp" ` set the heightmap
set terrain scale 1, 3, 0.1, 3 ` set the scale
set terrain split 1, 16 ` split value by 16 * 16
set terrain tiling 1, 4 ` detail map tiling
set terrain light 1, 1, -0.25, 0, 1, 1, 0.78, 0.5 ` light - xdir, ydir, zdir, red, green, blue, intensity
set terrain texture 1, 1, 2 ` base and detail texture
build terrain 1 ` finally build the terrain
position object 1, 0,0,0 ` position terrain at zero coordinates
sc_setupComplexObject 1,1,2 ` setup collision on the terrain
set dir ".." ` reset the directory (1 level lower to media\)
set dir "Skybox\" ` set the directory to skybox's location
`load our skybox (this is very low quality, u can find smth better)
`this file has images asociated (1-6 jpg images in media directory).
`U can change or edit them
load object "skybox.x", 6
set object light 6, 0
set object texture 6, 3, 1 `not sure what it should do, but it improves skybox texture :)
position object 6, 500, 50, 500 `~in middle of terrain
scale object 6, 10000, 10000, 10000 `make skybox big!
set dir ".." `reset the directory back to media\
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MoveCamera()
`keyboard input for movement
if upkey()=1 then move camera 3
if downkey()=1 then move camera -3
if leftkey()=1 then yrotate camera wrapvalue(camera angle y()-2)
if rightkey()=1 then yrotate camera wrapvalue(camera angle y()+2)
`find out the camera height
x#=camera position x()
z#=camera position z()
y#=get terrain ground height(1,x#,z#)+30
`position the camera
position camera x#,y#,z#
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function SelectObjects()
`function to pick any object's whose number is between 10 and TotalUnitCount+10
`using screen coordinates
which= pick object(mousex(),mousey(),10,TotalUnitCount+10)
endfunction which `return value which object was selected, if 0 then none of objects
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MakeBoxes() `make 20 random boxes
make object box 9,10,7,15 `make object
make mesh from object 1, 9 `extract shape of object
for i= 10 to 20 `10 times
make object box i,10,7,15 `make box
add limb i, 1, 1 `add a part for object, parts shape is mesh 1
offset limb i, 1, 0, 0, 1 `position part of object in local coordinates
hide limb i, 1 `hide- make that part invisible
x=rnd(200)+50 `get random x and z coordinates
z=rnd(200)+50
y=get terrain ground height (1,x,z) `get height in that point
position object i,x,y+4,z `position object +4 units above ground
rotate object i,0,rnd(100),0 `random rotate object object
color object i,rgb(0,255,0) `color object- green
Unit(i).Name="Green Box"
Unit(i).Hp=100
Unit(i).Dmg=20
Unit(i).RotationSpeed=3.0
unit(i).maxspeed=0.5
Unit(i).Speed=0.0
Unit(i).IsMoving=0.0
Unit(i).IsFollowing=0.0
Unit(i).Traction=0.01
Unit(i).Team=1
Unit(i).Range=16000 `squared(^2)
next i
for i= 21 to 30 `make 10 more boxes in other team
make object box i,10,7,15
add limb i, 1, 1
offset limb i, 1, 0, 0, 1
hide limb i, 1
x=rnd(200)+200
z=rnd(200)+200
y=get terrain ground height (1,x,z)
position object i,x,y+4,z
rotate object i,0,rnd(100),0
color object i,rgb(128,128,0) `color boxes "yellow-green" lol
Unit(i).Name="Dirty Box"
Unit(i).Hp=100
Unit(i).Dmg=20
Unit(i).RotationSpeed=3.0
unit(i).maxspeed=0.5
Unit(i).Speed=0.0
Unit(i).IsMoving=0.0
Unit(i).IsFollowing=0.0
Unit(i).Traction=0.01
Unit(i).Team=2
Unit(i).Range=16000 `this is squared (^2)
next i
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function SelectionIndicator(obj) `indicator handler
if obj=0: `if no objects selected
if object visible(2)=1: `if indicator visible
hide object (2) `make it invisible
endif
else `if some object is selected
if object visible(2)=0: `if indicator is not visible
show object (2) `make it visible
endif
`position indicator +10 units above your selected object
position object 2,object position x (obj),object position y (obj)+10,object position z(obj)
endif
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MakeSelectionIndicator() `make objects for indicators
make object cone 2, 5 `for active object
zrotate object 2, 180 `rotate/point down
set object 2, 1, 1, 0 `don't know what this does
color object 2,RGB(0, 255, 0) `green color
make object cone 3, 5 `to mark target-coordinates on map
zrotate object 3, 180 `rotate/point down
set object 3, 1, 1, 0
color object 3,RGB(255, 255, 0) `yellow color
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function Info()
`str$(a) function returns integer, float or other type variable as string
`"text x,y, string" function can't print other variables than strings
`strings can be added to each other i.e. "cat"+"dog"+str$(2)="catdog2"
text 10,10,"Object selected :"+str$(activeID) `selected, active object
text 10,30,"FPS :" + str$(Screen FPS()) `frames per second (how many times screen refreshes)
`determines how hard program is for pc, fps will go down if pc is too weak
`my 1.8Ghz, 1.5Gb Ram machine shows 100-120 in this program stage.
`as more functions are added it should slow down
text 10,50,"Left mouse click to select object"
text 10,70,"Right mouse click to place target/target object"
text 10,100,"Object team:" + str$(unit(ActiveID).Team)
text 10,120,"Target team:" + str$(unit(unit(ActiveID).MoveTarget).Team)
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function object_distance_squared(a,b) `returns distance between objects squared
`(distance^2 or distance*distance)
w#= (object position x(a)-object position x(b))^2 `difference in x axis ^2
h#= (object position y(a)-object position y(b))^2 `difference in y axis ^2
l#= (object position z(a)-object position z(b))^2 `difference in z axis ^2
d#= l#+w#+h# `summ up all distances (like pitagores just in 3D)
`if u want to get real distance use d#= sqrt(l#+w#+h#)
`but square root is calculated long, so if u make many calculations
`program can slow down signicicantly
endfunction d#
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function LoadMenuPanel() `this will load sprites for menu
set dir "Sprites\" `directory for sprites
load image "MiniMap.bmp",3 `minimap in left corner
sprite 1,0,600,3
hide sprite 1
load image "Panel.bmp",4 `will be info about selected unit/object
sprite 2,250,600,4
hide sprite 2
set dir ".." `reset directory to media\
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MakeTarget() `place target indicator if needed (i cant comment this funtion well, because its no my made.
`forum link for it: http://forum.thegamecreators.com/?m=forum_view&t=79830&b=1
obj=SelectObjects() `targeted object number
if obj=0 `if none objects selected
mX = mouseX()
mY = mouseY()
cx# = camera position x()
cy# = camera position y()
cz# = camera position z()
pickState = Pick Object (mX, mY, 1, 1)
If pickState <> 0 `if nothing selected
Dist# = Get Pick Distance()
Pick Screen mX, mY, Dist#
indX# = cx# + get pick vector x()
indY# = cy# + get pick vector y()
indZ# = cz# + get pick vector z()
Position Object 3, indX#, indY#+3, indZ# `position indicator on terrain
Unit(ActiveID).Dx=indX# `set units destination coordinates
Unit(ActiveID).Dy=indY#
Unit(ActiveID).Dz=indZ#
Unit(ActiveID).IsFollowing=0 `no more folowing or attacking
unit(i).movetarget=0
unit(i).attacktarget=0
Unit(ActiveID).IsMoving=1 `start moving to destination coordinates
if unit(ActiveID).MoveTarget<>0 then unit(ActiveID).MoveTarget=0
if object visible(3)=0 then show object (3) `show destination point indicator
EndIf
else
unit(ActiveID).MoveTarget=obj `set units target value to selected object
`if target object is enemy, set attack target
if unit(ActiveID).MoveTarget>0 and unit(obj).Team<>unit(ActiveID).Team then unit(ActiveID).AttackTarget=obj
Unit(ActiveID).IsMoving=0 `no more moving to destination coordinates
Unit(ActiveID).IsFollowing=1 `start folowing
if object visible(3)=1 then hide object (3) `hide destination point indicator
endif
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MoveObjects()
for i=10 to TotalUnitCount `for all controllable objects
if unit(i).IsMoving <>0 `if object is moving to destination point
MoveObject(i) `then move it
if abs(unit(i).dx-object position x(i))<5 and abs(unit(i).dz-object position z(i))<5 `if at destination. stop object
unit(i).Ismoving=0 `if reached destination point then stop
endif
endif
if unit(i).IsFollowing <>0 `if object is folowing other object
if unit(unit(i).MoveTarget).Team=unit(i).Team
if object_distance_squared (i,Unit(i).MoveTarget)>FollowDistance `if is too far
FollowObject(i) `then move it towards target
text 10,150, "follow friendly"
endif
else
if object_distance_squared (i,Unit(i).MoveTarget)>Unit(i).Range-10 then FollowObject(i)
text 10,165, "follow enemy"
endif
endif
next i
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function MoveObject(ID) `made by Neuro Fuzzy, this is little edited to suit this program
`link to His tutorial: http://www.neurofuzzydev.com/V/D/43a.htm
`link to download full vectors tutorial:
`http://forum.thegamecreators.com/?m=forum_view&t=133126&b=7
a = 1
null = make vector3(a)
set vector3 a, unit(ID).Dx - object position x(ID), 0, unit(ID).Dz - object position z(ID)
distance# = length vector3(a)
Rem PJY - check the length of this vector.
Rem PJY - now we test to find out if the selected cube is pointing at the targeted cube
Rem PJY - we do this by comparing the angle between the vector representing the selected cube's direction
Rem PJY - and the vector 90 degrees to the side of that
normalize vector3 a, a
b = 2
null = make vector3(b)
set vector3 b, limb position x(ID, 1) - object position x(ID), 0, limb position z(ID, 1) - object position z(ID)
normalize vector3 b, b
Rem PJY - calculate angle between direction of selected cube and vector towards the target cube
angle# = acos(dot product vector3(a, b))
Rem PJY - create a cross product vector c to determine in which direction to turn selected cube
c = 3
null = make vector3(c)
set vector3 c, 0, 1, 0
cross product vector3 c, b, c
angle2# = acos(dot product vector3(a, c))
Rem PJY - if the selected cube is not pointing at the targeted cube, turn it towards the targeted cube
if angle# > 0.1
if angle2# <> 0
Rem PJY - select whether to turn right or left
if angle2# >= 90
turn object right ID, 1
else
turn object left ID, 1
endif
endif
endif
Rem PJY - now depending on the angle and the distance between the cubes
Rem PJY - we move the selected cube. The reason for the following code is that
Rem PJY - without it in certain situations the seleceted cube could begin
Rem PJY - "orbiting" the targeted cube, i.e. where it is moving so much per turn
Rem PJY - that it is not decreasing the angle
`all of the following code meaning is to slow down object
`when it is near or in big angle with it destination point
`the best way to set angles, distances and slow down/acelerate values
`is to experiment.
`all these values varie with different box sizes, speeds, stop distances
`if object is pointing ~ at its target then acelerate till max speed
if angle# < 1
if unit(ID).speed<unit(ID).maxspeed then unit(ID).speed=unit(ID).speed+unit(ID).traction
endif
`if object is pointing sharp angle at its target then acelerate till max speed/1.5
if angle# => 1 AND angle# < 10
if unit(ID).speed<unit(ID).maxspeed/1.5
unit(ID).speed=unit(ID).speed+unit(ID).traction
else
dec unit(ID).speed, 0.01 `if too fast, decrease speed
endif
endif
`if object is pointing bigger angle at its target then acelerate till max speed/2
if angle# => 10 AND angle# < 90 AND distance# > 20
if unit(ID).speed<unit(ID).maxspeed/2
unit(ID).speed=unit(ID).speed+unit(ID).traction
else
dec unit(ID).speed, 0.01 `if too fast, decrease speed
endif
endif
`if object is pointing away from its target then acelerate till max speed/8
if angle# => 90 AND angle# < 120 AND distance# > 20
if unit(ID).speed<unit(ID).maxspeed/8
unit(ID).speed=unit(ID).speed+unit(ID).traction
else
dec unit(ID).speed, 0.01 `if too fast, decrease speed
endif
endif
`if object is pointing away from its target and distance is small
`then acelerate till max speed/10
if angle# => 120 AND distance# > 10
if unit(ID).speed<unit(ID).maxspeed/10
unit(ID).speed=unit(ID).speed+unit(ID).traction
else
dec unit(ID).speed, 0.01 `if too fast, slow down
endif
endif
`i added this by experimenting with boxes, to slow down even more
if angle# => 80 AND distance# < 20
if unit(ID).speed<unit(ID).maxspeed/20
unit(ID).speed=unit(ID).speed+unit(ID).traction
else
dec unit(ID).speed, 0.02 `if too fast, slow down
endif
endif
move object ID, unit(ID).speed `when we set units speed, now can finally move it, YeY!
null = delete vector3(b)
null = delete vector3(c)
null = delete vector3(a)
`get coordinates of object
Ox#=object position x(ID)
Oz#=object position z(ID)
Oy#=get terrain ground height (1,Ox#,Oz#)+4
`and place it on terrain
position object ID,Ox#,Oy#,Oz#
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function FollowObject(ID) `this is a simple function,
`which changes object destination coordinates into followed object coordinates,
Unit(ID).dx=object Position X(Unit(ID).Movetarget)
Unit(ID).dz=object Position Z(Unit(ID).Movetarget)
`and then calls MoveObject() function to move object
MoveObject(ID)
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function ObjectInfo() `write selected object information
if activeID<>0
text 610, 680, "Name: "+ Unit(ActiveID).Name
text 610, 695, "Hp: "+ str$(Unit(ActiveID).Hp)
text 610, 710, "Dmg: "+ str$(Unit(ActiveID).Dmg)
endif
endfunction
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function RefreshSprites()
paste sprite 1,0,600
paste sprite 2,250,600
endfunction
and u can download full project with media as well
Join The dark Side! We have cookies