Hello,
I initially started to code this by showing Phodis how to detect collisions / reposition turning moving entities using linepicks and pickables, see : https://www.syntaxbomb.com/index.php/topic,4937.msg20244.html#15
and then i added some things / improvements here and there, and now i plan to (try to) finish a simple 3d shooter.
here is where i am at :
;see last post of this thread
Brilliant!!
Wish there was example code like this back when b3d came out :)
I can follow bits and pieces on your code RemiD... this is shaping up to be something really good... I'm envisioning that game Ravenfield and how I imagine
it would have started out in it's early stages. Freaking awesome :)
good work Remi!
Nice work Remid, very clear code :)
a few updates :
->i have put the player and the bots in one list "humanoids"
->i have added grenades (so now there are bullets, grenades, mines)
->humanoids, when damaged, lose particles of blood (red)
->each weapon produce a different amount of damage and consequently different amount of blood particles
the game is all made of primitives at the moment...
edit : fixed a bug
;simple-shooter-3D-201810242122
Graphics3D(1000,624,32,2)
HidePointer()
SeedRnd(MilliSecs())
Global ColorR%
Global ColorG%
Global ColorB%
;----------premade shapes----------
Global XRock = CreateRock(8,0.4)
ScaleMesh(XRock,2.0/2,1.5/2,2.0/2)
PositionMesh(XRock,0,1.5/2-0.5,0)
EntityColor(XRock,125,125,125)
HideEntity(XRock)
Global XTree = CreateTree()
EntityColor(XTree,100,050,000)
HideEntity(XTree)
Global XHumanoid = CreateCylinder(16)
ScaleMesh(XHumanoid,0.5/2,1.75/2,0.5/2)
PositionMesh(XHumanoid,0,0.875,0)
EntityColor(XHumanoid,125,125,255)
HideEntity(XHumanoid)
Global XBullet = CreateSphere(2)
ScaleMesh(XBullet,0.06/2,0.06/2,0.06/2)
EntityColor(XBullet,190,190,190)
HideEntity(XBullet)
Global XGrenade = CreateMesh()
TPart = CreateSphere(8)
ScaleMesh(TPart,0.3/2,0.3/2,0.3/2)
AddMesh(TPart,XGrenade) : FreeEntity(TPart)
TPart = CreateCylinder(8)
ScaleMesh(TPart,0.1/2,0.2/2,0.1/2)
PositionMesh(TPart,0,0.3/2,0)
AddMesh(TPart,XGrenade) : FreeEntity(TPart)
EntityColor(XGrenade,065,130,065)
HideEntity(XGrenade)
Global XMine = CreateCylinder(16)
ScaleMesh(XMine,0.3/2,0.06/2,0.3/2)
PositionMesh(XMine,0,0,0)
EntityColor(XMine,060,060,060)
HideEntity(XMine)
Global XPack = CreateCube()
ScaleMesh(XPack,0.1/2,0.1/2,0.1/2)
PositionMesh(XPack,0,0.1/2,0)
EntityColor(XPack,255,255,255)
HideEntity(XPack)
Global XTriParticle = CreateSphere(2)
ScaleMesh(XTriParticle,0.06/2,0.06/2,0.06/2)
EntityColor(XTriParticle,125,125,125)
HideEntity(XTriParticle)
Global XCubeParticle = CreateCube()
ScaleMesh(XCubeParticle,0.03/2,0.03/2,0.03/2)
EntityColor(XCubeParticle,125,125,125)
HideEntity(XCubeParticle)
Global XLineParticle = CreateCube()
ScaleMesh(XLineParticle,0.01/2,0.01/2,0.6/2)
EntityColor(XLineParticle,125,125,125)
HideEntity(XLineParticle)
Global XOmniExplosion = CreateSphere(16)
ScaleMesh(XOmniExplosion,1.0/2,1.0/2,1.0/2)
EntityColor(XOmniExplosion,255,125,000)
EntityFX(XOmniExplosion,1+16)
HideEntity(XOmniExplosion)
Global XDirExplosion = CreateCylinder(16)
ScaleMesh(XDirExplosion,1.0/2,1.0/2,1.0/2)
PositionMesh(XDirExplosion,0,1.0/2,0)
EntityColor(XDirExplosion,255,125,000)
EntityFX(XDirExplosion,1+16)
HideEntity(XDirExplosion)
Global XTrail = CreateMesh()
Surface = CreateSurface(XTrail) ;vertices 0 and 3 will be the start of the trail, vertices 1,2 and 4,5 will be the end of the trail
VI% = AddVertex(Surface,-0.06,0.0,0.0) : VertexColor(Surface,VI,255,255,255,0.0)
VI% = AddVertex(Surface,+0.06,0.0,0.0) : VertexColor(Surface,VI,255,255,255,0.0)
VI% = AddVertex(Surface,0.0,0.0,+1.0) : VertexColor(Surface,VI,255,255,255,0.1)
VI% = AddVertex(Surface,0.0,+0.06,0.0) : VertexColor(Surface,VI,255,255,255,0.0)
VI% = AddVertex(Surface,0.0,-0.06,0.0) : VertexColor(Surface,VI,255,255,255,0.0)
VI% = AddVertex(Surface,0.0,0.0,+1.0) : VertexColor(Surface,VI,255,255,255,0.1)
AddTriangle(Surface,0,1,2)
AddTriangle(Surface,3,4,5)
UpdateNormals(XTrail)
EntityFX(XTrail,1+2+16+32)
;-----------------------------------
;camera
Global Camera = CreateCamera()
CameraRange(Camera,1,1000)
CameraClsColor(Camera,001,001,001)
;input
Global MXDiff%
Global MYDiff%
;origine
Origine = CreateCube()
ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)
Global BulletsCount% = 0 ;to track how many bullets are active in the scene
Global GrenadesCount% = 0 ;to track how many grenades are active in the scene
Global MinesCount% = 0 ;to track how many mines are active in the scene
Global ParticlesCount% = 0 ;to track how many particles are active in the scene
Global ExplosionsCount% = 0 ;to track how many explosions are active in the scene
Global TrailsCount% = 0 ;to track how many trails are active in the scene
;ground
Global GroundShape
AddGround()
;rocks
Type Rock
Field Shape
End Type
AddRocks()
;trees
Type Tree
Field Shape
End Type
AddTrees()
;player
Global PlayerYaw#
Global PlayerH%
;humanoids
Type Humanoid
Field Eyes
Field Ears
Field ColorR%, ColorG%, ColorB%
Field Shape
Field VX#
Field VY#
Field VZ#
Field PrevMS%
Field LifeMS%
Field SpeedMS%
Field ShieldMS%
Field PowerMS%
Field BulletsCount%
Field GrenadesCount%
Field MinesCount%
Field Life%
End Type
AddHumanoids()
;bullets
Type Bullet
Field Shape
Field Velocity#
Field VX#
Field VY#
Field VZ#
Field TrailH%
End Type
;grenades
Type Grenade
Field Shape
Field Velocity#
Field Gravity#
Field VX#
Field VY#
Field VZ#
End Type
;mines
Type Mine
Field Shape
End Type
AddMines()
;particles
Type Particle
Field Shape
Field Velocity#
Field Life#
End Type
;explosions
Type Explosion
Field Shape
Field Size#
Field MaxSize#
Field Growth#
End Type
;trails (for bullets)
Type Trail
Field Shape
Field BulletH%
End Type
;packs
Type Pack
Field Kind% ;lifepack or speedpack or shieldpack or powerpack or bulletspack or grenadespack or minespack
Field Shape
End Type
;pack kinds
Const CLife% = 1
Const CSpeed% = 2
Const CShield% = 3
Const CPower% = 4
Const CBullets% = 5
Const CGrenades% = 6
Const CMines% = 7
;lifepack = life+1 during xms
;speedpack = speed*2 during xms
;shieldpack = damagereceived/2 during xms
;powerpack = damageemitted*2 during xms
;bulletspack = bullets+30
;grenadespack = grenades+3
;minespack = mines+3
AddPacks()
EntityPickMode(GroundShape,2) : NameEntity(GroundShape,"GRO"+Str(1))
For r.Rock = Each Rock
EntityPickMode(r\Shape,2) : NameEntity(r\Shape,"ROC"+Str(Handle(r)))
Next
For t.Tree = Each Tree
EntityPickMode(t\Shape,2) : NameEntity(t\Shape,"TRE"+Str(Handle(t)))
Next
For h.Humanoid = Each Humanoid
EntityPickMode(h\Shape,2) : NameEntity(h\Shape,"HUM"+Str(Handle(h)))
Next
Global PickPoint = CreateCube()
ScaleMesh(PickPoint,0.03/2,0.03/2,0.03/2)
EntityColor(PickPoint,255,000,255)
EntityFX(PickPoint,1)
Global PickNormal = CreateCube()
ScaleMesh(PickNormal,0.01/2,0.01/2,0.3/2)
PositionMesh(PickNormal,0,0,0.3/2)
EntityColor(PickNormal,125,000,125)
EntityFX(PickNormal,1)
DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,50,1000,-1000)
RotateEntity(DLight,45,0,0)
AmbientLight(064,064,064)
PlayerH% = GetHumanoidH(Rand(1,10))
hu.Humanoid = Object.Humanoid(PlayerH)
PositionEntity(Camera,EntityX(hu\Shape,True),EntityY(hu\Shape,True),EntityZ(hu\Shape,True))
MoveEntity(Camera,0,1.65+1.5,-3.0)
TurnEntity(Camera,22.5,0,0)
EntityParent(Camera,hu\Shape)
;PositionEntity(Camera,50,50,-22.5)
;RotateEntity(Camera,45,0,0)
Global MainLoopTimer = CreateTimer(30)
;mainloop
Main()
End()
Function Main()
Repeat
MainLoopMilliStart% = MilliSecs()
MXDiff = MouseXSpeed()
MYDiff = MouseYSpeed()
;update humanoids
UpdateHumanoids()
;update bullets
UpdateBullets()
;update grenades
UpdateGrenades()
;update mines
UpdateMines()
;update particles
UpdateParticles()
;update explosions
UpdateExplosions()
;update packs
UpdatePacks()
;update effects (on player / bots)
UpdateEffects()
;update trails
UpdateTrails()
;wireframe mode off/on
WireFrame(False)
If( KeyDown(2)=True )
WireFrame(True)
EndIf
;render
RenderWorld()
Color(255,255,255)
If( KeyDown(3)=1 )
Text(500,0,"Tris = "+TrisRendered())
Text(500,16,"FPS = "+FPS)
Text(0,0,"BulletsCount = "+BulletsCount)
Text(0,16,"GrenadesCount = "+GrenadesCount)
Text(0,32,"MinesCount = "+MinesCount)
Text(0,48,"ParticlesCount = "+ParticlesCount)
Text(0,64,"ExplosionsCount = "+ExplosionsCount)
Text(0,80,"TrailsCount = "+TrailsCount)
EndIf
;display life points on top of player/bots
For hu.Humanoid = Each Humanoid
CameraProject(Camera,EntityX(hu\Shape,True),EntityY(hu\Shape,True)+1.75+0.1,EntityZ(hu\Shape,True))
LineStr$ = Str(hu\Life) : PX% = ProjectedX()-StringWidth(LineStr)/2 : PY% = ProjectedY()-16
Color(hu\ColorR*0.9,hu\ColorG*0.9,hu\ColorB*0.9) : Text(PX,PY,LineStr)
Next
;display the result on the screen
;Flip(1)
WaitTimer(MainLoopTimer)
VWait():Flip(False)
MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
If( MainLoopMilliTime < 1 )
MainLoopMilliTime = 1
EndIf
FPS% = 1000.0/MainLoopMilliTime
Until( KeyDown(1)=1 )
End Function
;vertices+triangles (with normals, with colors, with alphas, with uvs)
Function AddSurfaceToOtherSurface(Surface,Mesh,OSurface,OMesh)
SurfaceVerticesCount% = CountVertices(Surface)
;DebugLog("SurfaceVerticesCount = "+SurfaceVerticesCount)
OSurfaceVerticesCount% = CountVertices(OSurface)
;DebugLog("OSurfaceVerticesCount = "+OSurfaceVerticesCount)
For VI% = 0 To CountVertices(Surface)-1 Step 1
;DebugLog("VI = "+VI)
VLX# = VertexX(Surface,VI)
VLY# = VertexY(Surface,VI)
VLZ# = VertexZ(Surface,VI)
TFormPoint(VLX,VLY,VLZ,Mesh,0)
VGX# = TFormedX()
VGY# = TFormedY()
VGZ# = TFormedZ()
VNX# = VertexNX(Surface,VI)
VNY# = VertexNY(Surface,VI)
VNZ# = VertexNZ(Surface,VI)
VR% = VertexRed(Surface,VI)
VG% = VertexGreen(Surface,VI)
VB% = VertexBlue(Surface,VI)
VA# = VertexAlpha(Surface,VI)
VU# = VertexU(Surface,VI,0)
VV# = VertexV(Surface,VI,0)
If( OSurfaceVerticesCount = 0 )
NVI = VI
Else If( OSurfaceVerticesCount > 0 )
NVI% = OSurfaceVerticesCount+VI
EndIf
;DebugLog("NVI = "+NVI)
AddVertex(OSurface,VGX,VGY,VGZ)
VertexNormal(OSurface,NVI,VNX,VNY,VNZ)
VertexColor(OSurface,NVI,VR,VG,VB,VA)
VertexTexCoords(OSurface,NVI,VU,VB)
;WaitKey()
Next
SurfaceTrianglesCount% = CountTriangles(Surface)
;DebugLog("SurfaceTrianglesCount = "+SurfaceTrianglesCount)
OSurfaceTrianglesCount% = CountTriangles(OSurface)
;DebugLog("OSurfaceTrianglesCount = "+OSurfaceTrianglesCount)
For TI% = 0 To CountTriangles(Surface)-1 Step 1
V0I% = TriangleVertex(Surface,TI,0) ;vertex0
V1I% = TriangleVertex(Surface,TI,1) ;vertex1
V2I% = TriangleVertex(Surface,TI,2) ;vertex2
;DebugLog("oldtriangle"+TI+" "+V0I+","+V1I+","+V2I)
If( OSurfaceVerticesCount = 0 )
NV0I% = V0I
NV1I% = V1I
NV2I% = V2I
Else If( OSurfaceVerticesCount > 0 )
NV0I% = OSurfaceVerticesCount+V0I
NV1I% = OSurfaceVerticesCount+V1I
NV2I% = OSurfaceVerticesCount+V2I
EndIf
;DebugLog("newtriangle"+TI+" "+NV0I+","+NV1I+","+NV2I)
AddTriangle(OSurface,NV0I,NV1I,NV2I)
Next
;WaitKey()
End Function
Function ColorWithBrush(Surface,R%,G%,B%,A#=1.0,Fx%=0,BlendMode%=1)
Brush = CreateBrush()
BrushColor(Brush,R,G,B)
BrushAlpha(Brush,A)
BrushFX(Brush,Fx)
BrushBlend(Brush,BlendMode)
PaintSurface(Surface,Brush)
FreeBrush(Brush)
End Function
Function CreateRock(Details%=8,MaxIrregularity#=0.3)
SMesh = CreateSphere(Details)
SSurface = GetSurface(SMesh,1)
DMesh = CreateMesh()
DSurface = CreateSurface(DMesh)
DVerticesCount% = 0
;for each triangle of the source surface
For STI% = 0 To CountTriangles(SSurface)-1 Step 1
;for vertex0 of this triangle
SV0I% = TriangleVertex(SSurface,STI,0)
;get this vertex0 position
X# = VertexX(SSurface,SV0I) : Y# = VertexY(SSurface,SV0I) : Z# = VertexZ(SSurface,SV0I)
;check if there is already a vertex existing at this position in the destination surface (with a tolerance of 0.01unit)
TVI% = -1
For DVI% = 0 To CountVertices(DSurface)-1 Step 1
If( VertexX(DSurface,DVI) >= X-0.01 And VertexX(DSurface,DVI) <= X+0.01 And VertexY(DSurface,DVI) >= Y-0.01 And VertexY(DSurface,DVI) <= Y+0.01 And VertexZ(DSurface,DVI) >= Z-0.01 And VertexZ(DSurface,DVI) <= Z+0.01 )
TVI = DVI
Exit
EndIf
Next
;if yes
If( TVI <> - 1 )
;use this vertex
DV0I% = TVI
;if no
Else If( TVI% = - 1 )
;create a new vertex in the destination surface
DVerticesCount = DVerticesCount + 1
DV0I% = DVerticesCount - 1
AddVertex(DSurface,X,Y,Z)
EndIf
;for vertex1 of this triangle
SV1I% = TriangleVertex(SSurface,STI,1)
;get this vertex1 position
X# = VertexX(SSurface,SV1I) : Y# = VertexY(SSurface,SV1I) : Z# = VertexZ(SSurface,SV1I)
;check if there is already a vertex existing at this position in the destination surface (with a tolerance of 0.01unit)
TVI% = -1
For DVI% = 0 To CountVertices(DSurface)-1 Step 1
If( VertexX(DSurface,DVI) >= X-0.01 And VertexX(DSurface,DVI) <= X+0.01 And VertexY(DSurface,DVI) >= Y-0.01 And VertexY(DSurface,DVI) <= Y+0.01 And VertexZ(DSurface,DVI) >= Z-0.01 And VertexZ(DSurface,DVI) <= Z+0.01 )
TVI = DVI
Exit
EndIf
Next
;if yes
If( TVI <> - 1 )
;use this vertex
DV1I% = TVI
;if no
Else If( TVI% = - 1 )
;create a new vertex in the destination surface
DVerticesCount = DVerticesCount + 1
DV1I% = DVerticesCount - 1
AddVertex(DSurface,X,Y,Z)
EndIf
;for vertex2 of this triangle
SV2I% = TriangleVertex(SSurface,STI,2)
;get this vertex0 position
X# = VertexX(SSurface,SV2I) : Y# = VertexY(SSurface,SV2I) : Z# = VertexZ(SSurface,SV2I)
;check if there is already a vertex existing at this position in the destination surface (with a tolerance of 0.01unit)
TVI% = -1
For DVI% = 0 To CountVertices(DSurface)-1 Step 1
If( VertexX(DSurface,DVI) >= X-0.01 And VertexX(DSurface,DVI) <= X+0.01 And VertexY(DSurface,DVI) >= Y-0.01 And VertexY(DSurface,DVI) <= Y+0.01 And VertexZ(DSurface,DVI) >= Z-0.01 And VertexZ(DSurface,DVI) <= Z+0.01 )
TVI = DVI
Exit
EndIf
Next
;if yes
If( TVI <> - 1 )
;use this vertex
DV2I% = TVI
;if no
Else If( TVI% = - 1 )
;create a new vertex in the destination surface
DVerticesCount = DVerticesCount + 1
DV2I% = DVerticesCount - 1
AddVertex(DSurface,X,Y,Z)
EndIf
;create a new triangle in the destination surface
AddTriangle(DSurface,DV0I,DV1I,DV2I)
Next
UpdateNormals(DMesh)
;add some irregularities to the surface
For DVI% = 0 To CountVertices(DSurface)-1 Step 1
X# = VertexX(DSurface,DVI) : Y# = VertexY(DSurface,DVI) : Z# = VertexZ(DSurface,DVI)
NX# = VertexNX(DSurface,DVI) : NY# = VertexNY(DSurface,DVI) : NZ# = VertexNZ(DSurface,DVI)
NewX# = X + NX*Rnd(0.1,MaxIrregularity) : NewY# = Y + NY*Rnd(0.1,MaxIrregularity) : NewZ# = Z + NZ*Rnd(0.1,MaxIrregularity)
VertexCoords(DSurface,DVI,NewX,NewY,NewZ)
Next
DebugLog(CountVertices(SSurface)+" "+CountTriangles(SSurface))
DebugLog(CountVertices(DSurface)+" "+CountTriangles(DSurface))
FreeEntity(SMesh)
UpdateNormals(DMesh)
Return DMesh
End Function
Function CreateTree()
DMesh = CreateMesh()
TPart = CreateCone(8)
ScaleMesh(TPart,0.3/2,3.0/2,0.3/2)
PositionMesh(TPart,0,3.0/2,0)
AddMesh(TPart,DMesh) : FreeEntity(TPart)
Return DMesh
End Function
Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)
Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance2D
End Function
Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)
Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance3D
End Function
Function AddGround()
GroundShape = CreateCube()
ScaleMesh(GroundShape,100.0/2,1.0/2,100.0/2)
PositionMesh(GroundShape,100.0/2,-1.0/2,100.0/2)
EntityColor(GroundShape,050,150,050)
End Function
Function AddRocks()
For n% = 1 To 15 Step 1
;choose a position
.LineChooseRockPosition
X# = Rnd(0+1.0,100-1.0) : Z# = Rnd(0+1.0,100-1.0)
;check if this position is far enough from others existing rocks
For rr.Rock = Each Rock
D# = Distance2D(X,Z,EntityX(rr\Shape,True),EntityZ(rr\Shape,True))
If( D < 1.0+1.0+1.0 )
Goto LineChooseRockPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many rocks !!!
EndIf
Next
r.Rock = New Rock
r\Shape = CopyEntity(XRock)
Size# = Rnd(0.5,2.0)
ScaleEntity(r\Shape,Size,Size,Size)
PositionEntity(r\Shape,X,0,Z)
Next
End Function
Function AddTrees()
For n% = 1 To 60 Step 1
;choose a position
.LineChooseTreePosition
X# = Rnd(0+1.5,100-1.5) : Z# = Rnd(0+1.5,100-1.5)
;check if this position is far enough from others existing rocks
For rr.Rock = Each Rock
D# = Distance2D(X,Z,EntityX(rr\Shape,True),EntityZ(rr\Shape,True))
If( D < 1.0+1.5+1.0 )
Goto LineChooseTreePosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many trees !!!
EndIf
Next
;check if this position is far enough from others existing trees
For tt.Tree = Each Tree
D# = Distance2D(X,Z,EntityX(tt\Shape,True),EntityZ(tt\Shape,True))
If( D < 1.5+1.5+1.0 )
Goto LineChooseTreePosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many trees !!!
EndIf
Next
t.Tree = New Tree
t\Shape = CopyEntity(XTree)
Size# = Rnd(1.0,3.0)
ScaleEntity(t\Shape,Size,Size,Size)
PositionEntity(t\Shape,X,0,Z)
Next
End Function
Function AddHumanoids()
For n% = 1 To 10 Step 1
;choose a position
.LineChooseHumanoidPosition
X# = Rnd(0+0.25,100-0.25) : Z# = Rnd(0+0.25,100-0.25)
;check if this position is far enough from others existing rocks
For rr.Rock = Each Rock
D# = Distance2D(X,Z,EntityX(rr\Shape,True),EntityZ(rr\Shape,True))
If( D < 2.0+0.25+1.0 )
Goto LineChooseHumanoidPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many humanoids !!!
EndIf
Next
;check if this position is far enough from others existing trees
For tt.Tree = Each Tree
D# = Distance2D(X,Z,EntityX(tt\Shape,True),EntityZ(tt\Shape,True))
If( D < 1.5+0.25+1.0 )
Goto LineChooseHumanoidPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many humanoids !!!
EndIf
Next
;check if this position is far enough from others existing humanoids
For hh.Humanoid = Each Humanoid
D# = Distance2D(X,Z,EntityX(hh\Shape,True),EntityZ(hh\Shape,True))
If( D < 0.25+0.25+1.0 )
Goto LineChooseHumanoidPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many humanoids !!!
EndIf
Next
h.Humanoid = New Humanoid
h\ColorR = Rand(025,255) : h\ColorG = Rand(025,255) : h\ColorB = Rand(025,255)
h\Shape = CopyEntity(XHumanoid)
EntityColor(h\Shape,h\ColorR,h\ColorG,h\ColorB)
PositionEntity(h\Shape,X,0,Z)
h\PrevMS = MilliSecs()+Rand(1,1000)
h\LifeMS = MilliSecs()-100000
h\SpeedMS = MilliSecs()-100000
h\ShieldMS = MilliSecs()-100000
h\PowerMS = MilliSecs()-100000
h\Life = 100
Next
End Function
Function AddMines()
For n% = 1 To 50 Step 1
.LineChooseMinePosition
X# = Rnd(0+0.3,100-0.3) : Z# = Rnd(0+0.3,100-0.3) : Y# = 0
MinesCount = MinesCount + 1
m.Mine = New Mine
m\Shape = CopyEntity(XMine)
PositionEntity(m\Shape,X,Y,Z)
Next
End Function
Function AddPacks()
For n% = 1 To 10 Step 1
TKind% = Rand(1,1) ;Rand(1,7) ;1->LifePack 2->SpeedPack 3->ShieldPack 4->PowerPack 5->BulletsPack 6->GrenadesPack 7->MinesPack
.LineChoosePackPosition
X# = Rnd(0+0.05,100.0-0.05) : Z# = Rnd(0+0.05,100.0-0.05)
p.Pack = New Pack
p\Kind = TKind
p\Shape = CopyEntity(XPack)
GetPackColor(TKind)
EntityColor(p\Shape,ColorR,ColorG,ColorB)
PositionEntity(p\Shape,X,0.05,Z)
Next
End Function
Function GetPackColor(TKind%)
If( TKind = CLife ) ;lifepack
ColorR = 065 : ColorG = 255 : ColorB = 255
Else If( TKind = CSpeed ) ;speedpack
ColorR = 255 : ColorG = 255 : ColorB = 065
Else If( TKind = CShield ) ;shieldpack
ColorR = 065 : ColorG = 255 : ColorB = 065
Else If( TKind = CPower ) ;powerpack
ColorR = 255 : ColorG = 065 : ColorB = 065
Else If( TKind = CBullets ) ;bulletspack
ColorR = 125 : ColorG = 095 : ColorB = 095
Else If( TKind = CGrenades ) ;grenadespack
ColorR = 095 : ColorG = 125 : ColorB = 095
Else If( TKind = CMines ) ;minespack
ColorR = 095 : ColorG = 095 : ColorB = 125
EndIf
End Function
Function GetHumanoidH%(I%)
TI% = 0
For h.Humanoid = Each Humanoid
TI = TI + 1
If( I = TI )
Return Handle(h)
EndIf
Next
End Function
Function UpdateHumanoids()
;update player depending on controls
pl.Humanoid = Object.Humanoid(PlayerH)
If( pl\Life <= 0 )
;destroy player
FreeEntity(pl\Shape) : Delete(pl)
Else If( pl\Life > 0 )
;update player
;turn left/right
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
PlayerYaw = PlayerYaw - Float(MXDiff)/10
RotateEntity(pl\Shape,0,PlayerYaw,0,False)
;move forward/backward/left/right
Velocity# = 6.666/30.0
If( KeyDown(17)=0 And KeyDown(31)=0 And KeyDown(30)=0 And KeyDown(32)=0 )
TFormVector(0,0,0,pl\Shape,0)
Else If( KeyDown(17)=1 )
TFormVector(0,0,+Velocity,pl\Shape,0)
Else If( KeyDown(31)=1 )
TFormVector(0,0,-Velocity,pl\Shape,0)
Else If( KeyDown(30)=1 )
TFormVector(-Velocity,0,0,pl\Shape,0)
Else If( KeyDown(32)=1 )
TFormVector(+Velocity,0,0,pl\Shape,0)
EndIf
;calculates the movement vector
pl\VX = TFormedX() : pl\VY = TFormedY() : pl\VZ = TFormedZ()
;before moving humanoid, check if it will collide with an obstacle entity (ground or rock or tree or humanoid)
TFormPoint(0,0.25,0,pl\Shape,0) ;root of humanoid shape +0.25 (on the Y axis)
LinePick(TFormedX(),TFormedY(),TFormedZ(),pl\VX,pl\VY,pl\VZ,0.25-0.01) ;humanoid radius is 0.25 ;throws a linepick from the position of humanoid +0.25 to direction of the movement vector
EntRef% = PickedEntity()
;if yes
If( EntRef <> 0 )
PositionEntity(PickPoint,PickedX(),PickedY(),PickedZ())
PositionEntity(PickNormal,PickedX(),PickedY(),PickedZ()) : AlignToVector(PickNormal,PickedNX(),PickedNY(),PickedNZ(),3,1.0)
;recalculate the appropriate position
PlayerX# = EntityX(pl\Shape,True) : PlayerY# = EntityY(pl\Shape,True) : PlayerZ# = EntityZ(pl\Shape,True)
PickX# = PickedX() : PickY# = PickedZ() : PickZ# = PickedZ()
D# = Distance2D(PlayerX,PlayerZ,PickX,PickZ)
TCoeff# = (D-0.25)/(Velocity)
pl\VX = pl\VX*TCoeff : pl\VZ = pl\VZ*TCoeff
;move player
TranslateEntity(pl\Shape,pl\VX,pl\VY,pl\VZ)
;if no
Else If( EntRef = 0 )
;move player
TranslateEntity(pl\Shape,pl\VX,pl\VY,pl\VZ)
EndIf
If( MouseDown(1)=1 )
;shoot a bullet
NowMS% = MilliSecs()
If( NowMS - pl\PrevMS > 100 )
;create a new bullet
BulletsCount = BulletsCount + 1
bu.Bullet = New Bullet
bu\Shape = CopyEntity(XBullet)
PositionEntity(bu\Shape,EntityX(pl\Shape,True),EntityY(pl\Shape,True)+0.875,EntityZ(pl\Shape,True))
RotateEntity(bu\Shape,EntityPitch(pl\Shape,True),EntityYaw(pl\Shape,True),EntityRoll(pl\Shape,True))
TurnEntity(bu\Shape,Rnd(-1,+1),Rnd(-1,+1),0)
;bu\Velocity = 35.208/30.0*Rnd(0.9,1.1)
bu\Velocity = 125.0/30.0*Rnd(0.9,1.1)
;get bullet position / orientation
TX# = EntityX(bu\Shape,True) : TY# = EntityY(bu\Shape,True) : TZ# = EntityZ(bu\Shape,True)
TPitch# = EntityPitch(bu\Shape,True) : TYaw# = EntityYaw(bu\Shape,True) : TRoll# = EntityRoll(bu\Shape,True)
;create a new trail
TrailsCount = TrailsCount + 1
tr.Trail = New Trail
tr\Shape = CopyEntity(XTrail)
PositionEntity(tr\Shape,TX,TY,TZ,True)
RotateEntity(tr\Shape,TPitch,TYaw,TRoll,True)
ScaleEntity(tr\Shape,1.0,1.0,0.001)
;associate bullet and trail
bu\TrailH% = Handle(tr)
;associate trail and bullet
tr\BulletH% = Handle(bu)
;store new milli value
pl\PrevMS = NowMS
EndIf
Else If( MouseHit(2)=1 )
;throw a grenade
NowMS% = MilliSecs()
If( NowMS - pl\PrevMS > 250 )
;create a new grenade
GrenadesCount = GrenadesCount + 1
gr.Grenade = New Grenade
gr\Shape = CopyEntity(XGrenade)
PositionEntity(gr\Shape,EntityX(pl\Shape,True),EntityY(pl\Shape,True)+0.875,EntityZ(pl\Shape,True))
RotateEntity(gr\Shape,EntityPitch(pl\Shape,True),EntityYaw(pl\Shape,True),EntityRoll(pl\Shape,True))
TurnEntity(gr\Shape,-45,Rnd(-1,+1),0)
gr\Velocity = 35.208/3.0/30.0*Rnd(0.9,1.1)
gr\Gravity = 0.0
;store new milli value
pl\PrevMS = NowMS
EndIf
Else If( MouseHit(3)=1 )
;drop a mine
EndIf
EndIf
;update bots depending on AI
For bo.Humanoid = Each Humanoid
If( Handle(bo) <> PlayerH )
If( bo\Life <= 0 )
;destroy bot
FreeEntity(bo\Shape) : Delete(bo)
Else If( bo\Life > 0 )
;update bot
;simple AI :
;check if player is near enough
D# = Distance2D(EntityX(bo\Shape,True),EntityZ(bo\Shape,True),EntityX(pl\Shape,True),EntityZ(pl\Shape,True))
If( D < 30 )
PointEntity(bo\Shape,pl\Shape,0)
;shoot a bullet
NowMS% = MilliSecs()
If( NowMS - bo\PrevMS > Rand(200,400) )
;create a new bullet
BulletsCount = BulletsCount + 1
bu.Bullet = New Bullet
bu\Shape = CopyEntity(XBullet)
PositionEntity(bu\Shape,EntityX(bo\Shape,True),EntityY(bo\Shape,True)+0.875,EntityZ(bo\Shape,True))
RotateEntity(bu\Shape,EntityPitch(bo\Shape,True),EntityYaw(bo\Shape,True),EntityRoll(bo\Shape,True))
TurnEntity(bu\Shape,Rnd(-1,+1),Rnd(-1,+1),0)
bu\Velocity = 125.0/30.0*Rnd(0.9,1.1)
;get bullet position / orientation
TX# = EntityX(bu\Shape,True) : TY# = EntityY(bu\Shape,True) : TZ# = EntityZ(bu\Shape,True)
TPitch# = EntityPitch(bu\Shape,True) : TYaw# = EntityYaw(bu\Shape,True) : TRoll# = EntityRoll(bu\Shape,True)
;create a new trail
TrailsCount = TrailsCount + 1
tr.Trail = New Trail
tr\Shape = CopyEntity(XTrail)
PositionEntity(tr\Shape,TX,TY,TZ,True)
RotateEntity(tr\Shape,TPitch,TYaw,TRoll,True)
ScaleEntity(tr\Shape,1.0,1.0,0.001)
;associate bullet and trail
bu\TrailH% = Handle(tr)
;associate trail and bullet
tr\BulletH% = Handle(bu)
;store new milli value
bo\PrevMS = NowMS
EndIf
;throw a grenade
;
;drop a mine
EndIf
EndIf
EndIf
Next
End Function
Function UpdateBullets()
For bu.Bullet = Each Bullet
;calculates the movement vector
TFormVector(0,0,+bu\Velocity,bu\Shape,0)
;calculates the movement vector
bu\VX = TFormedX() : bu\VY = TFormedY() : bu\VZ = TFormedZ()
;before moving the Bullet, check if it will collide with an obstacle entity (ground or rock or tree or humanoid)
TFormPoint(0,0,0,bu\Shape,0) ;root of Bullet shape
LinePick(TFormedX(),TFormedY(),TFormedZ(),bu\VX,bu\VY,bu\VZ,0.03) ;bullet radius is 0.03 ;throws a linepick from the position of Bullet +0 to direction of the movement vector
EntRef% = PickedEntity()
;if yes
If( EntRef <> 0 )
;recalculate the appropriate position
BulletX# = EntityX(bu\Shape,True) : BulletY# = EntityY(bu\Shape,True) : BulletZ# = EntityZ(bu\Shape,True)
PickX# = PickedX() : PickY# = PickedY() : PickZ# = PickedZ()
PickNX# = PickedNX() : PickNY# = PickedNY() : PickNZ# = PickedNZ()
D# = Distance2D(BulletX,BulletZ,PickX,PickZ)
TCoeff# = (D-0.03)/(bu\Velocity)
bu\VX = bu\VX*TCoeff : bu\VY = bu\VY*TCoeff : bu\VZ = bu\VZ*TCoeff
;move Bullet
TranslateEntity(bu\Shape,bu\VX,bu\VY,bu\VZ)
;get the name, kind, handle of the entity hit (ground or rock or tree or bot or player)
EntName$ = EntityName(EntRef) : EntKind$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)
;depending on the kind, get the color of the material hit
MaterialR% = 000 : MaterialG% = 000 : MaterialB% = 000
If( EntKind = "GRO" ) ;050,150,050
MaterialR% = 050*0.9 : MaterialG% = 150*0.9 : MaterialB% = 050*0.9
Else If( EntKind = "ROC" ) ;125,125,125
MaterialR% = 125*0.9 : MaterialG% = 125*0.9 : MaterialB% = 125*0.9
Else If( EntKind = "TRE" ) ;100,050,000 (trunc)
MaterialR% = 100*0.9 : MaterialG% = 050*0.9 : MaterialB% = 000*0.9
Else If( EntKind = "HUM" ) ;125,125,255
MaterialR% = 225*0.9 : MaterialG% = 000*0.9 : MaterialB% = 000*0.9
EndIf
;destroy the associated trail
trH% = bu\TrailH
tr.Trail = Object.Trail(trH)
FreeEntity(tr\Shape) : Delete(tr)
TrailsCount = TrailsCount - 1
;destroy the Bullet
FreeEntity(bu\Shape) : Delete(bu)
BulletsCount = BulletsCount - 1
;create particles of impact/damage
For n% = 1 To 8 Step 1
pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1
pa\Shape = CopyEntity(XTriParticle)
EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)
PositionEntity(pa\Shape,PickX,PickY,PickZ)
AlignToVector(pa\Shape,PickNX,PickNY,PickNZ,3,1.0) : TurnEntity(pa\Shape,Rand(-45,+45),Rand(-45,+45),0)
pa\Velocity = 0.03
pa\Life = 1.0
Next
;remove life from collided entity (if humanoid)
If( EntKind = "HUM" )
hu.Humanoid = Object.Humanoid(EntH)
hu\Life = hu\Life - 2
EndIf
;if no
Else If( EntRef = 0 )
;move the Bullet
TranslateEntity(bu\Shape,bu\VX,bu\VY,bu\VZ)
EndIf
If( bu <> Null )
;check if Bullet is near enough or too far the center of the map
D#=Distance3D(50,0.875,50,EntityX(bu\Shape,True),EntityY(bu\Shape,True),EntityZ(bu\Shape,True))
;if too far
If( D > 100.0 )
;destroy the associated trail
trH% = bu\TrailH
tr.Trail = Object.Trail(trH)
FreeEntity(tr\Shape) : Delete(tr)
TrailsCount = TrailsCount - 1
;destroy the Bullet
FreeEntity(bu\Shape) : Delete(bu)
BulletsCount = BulletsCount - 1
EndIf
EndIf
Next
End Function
Function UpdateGrenades()
For gr.Grenade = Each Grenade
;increase gravity force
gr\Gravity = gr\Gravity + 9.780/30.0/10
;calculates the movement vector
TFormVector(0,-gr\Gravity,+gr\Velocity,gr\Shape,0)
gr\VX = TFormedX() : gr\VY = TFormedY() : gr\VZ = TFormedZ()
;before moving the Grenade, check if it will collide with an obstacle entity (ground or rock or tree or humanoid)
TFormPoint(0,0,0,gr\Shape,0) ;root of grenade shape
LinePick(TFormedX(),TFormedY(),TFormedZ(),gr\VX,gr\VY,gr\VZ,0.3) ;grenade radius is 0.3 ;throws a linepick from the position of grenade +0 to direction of the movement vector
EntRef% = PickedEntity()
;if yes
If( EntRef <> 0 )
;recalculate the appropriate position
GrenadeX# = EntityX(gr\Shape,True) : GrenadeY# = EntityY(gr\Shape,True) : GrenadeZ# = EntityZ(gr\Shape,True)
PickX# = PickedX() : PickY# = PickedY() : PickZ# = PickedZ()
PickNX# = PickedNX() : PickNY# = PickedNY() : PickNZ# = PickedNZ()
D# = Distance3D(GrenadeX,GrenadeY,GrenadeZ,PickX,PickY,PickZ)
TCoeff# = (D-0.3)/(gr\Velocity)
gr\VX = gr\VX*TCoeff : gr\VY = gr\VY*TCoeff : gr\VZ = gr\VZ*TCoeff
;move grenade
TranslateEntity(gr\Shape,gr\VX,gr\VY,gr\VZ)
;get the name, kind, handle of the entity hit (ground or rock or tree or bot or player)
EntName$ = EntityName(EntRef) : EntKind$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)
;store grenade properties
GrenadeX# = EntityX(gr\Shape,True) : GrenadeY# = EntityY(gr\Shape,True) : GrenadeZ# = EntityZ(gr\Shape,True)
;destroy grenade
FreeEntity(gr\Shape) : Delete(gr)
GrenadesCount = GrenadesCount - 1
;create explosion effect
e.Explosion = New Explosion : ExplosionsCount = ExplosionsCount + 1
e\Shape = CopyEntity(XOmniExplosion)
e\Size = 0.3
e\MaxSize = 3.0
e\Growth = 0.2
A# = 1.0-(e\Size/e\MaxSize)
EntityAlpha(e\Shape,A)
PositionEntity(e\Shape,GrenadeX,GrenadeY,GrenadeZ)
;create particles of spread (from Grenade)
MaterialR% = 065 : MaterialG% = 130 : MaterialB% = 065
For n% = 1 To 32 Step 1
pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1
pa\Shape = CopyEntity(XCubeParticle)
EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)
PositionEntity(pa\Shape,GrenadeX,GrenadeY,GrenadeZ)
RotateEntity(pa\Shape,-90,0,0) : TurnEntity(pa\Shape,Rand(-180,+180),Rand(-180,+180),0)
pa\Velocity = 0.09
pa\Life# = 1.0
Next
;create particles of damage (on ground or rock or tree or humanoid)
MaterialR% = 000 : MaterialG% = 000 : MaterialB% = 000
If( EntKind = "GRO" ) ;050,150,050
MaterialR% = 050*0.9 : MaterialG% = 150*0.9 : MaterialB% = 050*0.9
Else If( EntKind = "ROC" ) ;125,125,125
MaterialR% = 125*0.9 : MaterialG% = 125*0.9 : MaterialB% = 125*0.9
Else If( EntKind = "TRE" ) ;100,050,000 (trunc)
MaterialR% = 100*0.9 : MaterialG% = 050*0.9 : MaterialB% = 000*0.9
Else If( EntKind = "HUM" ) ;125,125,255
MaterialR% = 225*0.9 : MaterialG% = 000*0.9 : MaterialB% = 000*0.9
EndIf
For n% = 1 To 120 Step 1
pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1
pa\Shape = CopyEntity(XTriParticle)
EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)
PositionEntity(pa\Shape,PickX,PickY,PickZ)
AlignToVector(pa\Shape,PickNX,PickNY,PickNZ,3,1.0) : TurnEntity(pa\Shape,Rand(-45,+45),Rand(-45,+45),0)
pa\Velocity = 0.09
pa\Life = 1.0
Next
;remove life from collided entity (if humanoid)
If( EntKind = "HUM" )
hu.Humanoid = Object.Humanoid(EntH)
hu\Life = hu\Life - 12
EndIf
;if no
Else If( EntRef = 0 )
;move the grenade
TranslateEntity(gr\Shape,gr\VX,gr\VY,gr\VZ)
EndIf
If( gr <> Null )
;check if grenade is above the ground level
If( EntityY(gr\Shape,True) < 0 )
;destroy the grenade
FreeEntity(gr\Shape) : Delete(gr)
GrenadesCount = GrenadesCount - 1
EndIf
EndIf
Next
End Function
Function UpdateMines()
For m.Mine = Each Mine
;check if an entity triggers it (player or bot)
IsTriggered% = False
EntName$ = "" : EntKind$ = "" : EntH% = 0
;is player or a bot near enough to trigger it ?
For hu.Humanoid = Each Humanoid
D# = Distance2D(EntityX(m\Shape,True),EntityZ(m\Shape,True),EntityX(hu\Shape,True),EntityZ(hu\Shape,True))
If( D < 0.15+0.25 )
IsTriggered = True
EntName$ = EntityName(hu\Shape) : EntKind$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)
Goto LineEndCheckIfTriggered
EndIf
Next
.LineEndCheckIfTriggered
If( IsTriggered = True )
;store mine properties
MineX# = EntityX(m\Shape,True) : MineY# = EntityY(m\Shape,True) : MineZ# = EntityZ(m\Shape,True)
;destroy mine
FreeEntity(m\Shape) : Delete(m)
MinesCount = MinesCount - 1
;create explosion effect
e.Explosion = New Explosion : ExplosionsCount = ExplosionsCount + 1
e\Shape = CopyEntity(XDirExplosion)
e\Size = 0.01
e\MaxSize = 3.0
e\Growth = 0.2
A# = 1.0-(e\Size/e\MaxSize)
EntityAlpha(e\Shape,A)
PositionEntity(e\Shape,MineX,MineY,MineZ)
;create particles of spread (from mine)
MaterialR% = 060 : MaterialG% = 060 : MaterialB% = 060
For n% = 1 To 16 Step 1
pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1
pa\Shape = CopyEntity(XCubeParticle)
EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)
PositionEntity(pa\Shape,MineX,MineY,MineZ)
RotateEntity(pa\Shape,-90,0,0) : TurnEntity(pa\Shape,Rand(-22.5,+22.5),Rand(-22.5,+22.5),0)
pa\Velocity = 0.09
pa\Life# = 1.0
Next
;create particles of damage (on player or on bot)
If( EntKind = "HUM" )
MaterialR% = 225 : MaterialG% = 000 : MaterialB% = 000
EndIf
For n% = 1 To 200 Step 1
pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1
pa\Shape = CopyEntity(XTriParticle)
EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)
PositionEntity(pa\Shape,MineX,MineY,MineZ)
RotateEntity(pa\Shape,-90,0,0) : TurnEntity(pa\Shape,Rand(-45,+45),Rand(-45,+45),0)
pa\Velocity = 0.09
pa\Life# = 1.0
Next
;remove life from collided entity (player or bot)
If( EntKind = "HUM" )
hu.Humanoid = Object.Humanoid(EntH)
hu\Life = hu\Life - 24
EndIf
EndIf
Next
End Function
Function UpdateParticles()
For pa.Particle = Each Particle
MoveEntity(pa\Shape,0,0,pa\Velocity)
pa\Life = pa\Life - 0.03
EntityAlpha(pa\Shape,pa\Life)
If( pa\Life <= 0 )
FreeEntity(pa\Shape) : Delete(pa)
ParticlesCount = ParticlesCount - 1
EndIf
Next
End Function
Function UpdateExplosions()
For e.Explosion = Each Explosion
e\Size = e\Size + e\Growth
ScaleEntity(e\Shape,e\Size,e\Size,e\Size)
A# = 1.0-(e\Size/e\MaxSize)
EntityAlpha(e\Shape,A)
If( e\Size => e\MaxSize )
FreeEntity(e\Shape) : Delete(e)
ExplosionsCount = ExplosionsCount - 1
EndIf
Next
End Function
Function UpdatePacks()
For p.Pack = Each Pack
;check if an entity takes it (player or bot)
IsTaken% = False
EntName$ = "" : EntKind$ = "" : EntH% = 0
;is player or a bot near enough to take it ?
For hu.Humanoid = Each Humanoid
D# = Distance2D(EntityX(p\Shape,True),EntityZ(p\Shape,True),EntityX(hu\Shape,True),EntityZ(hu\Shape,True))
If( D < 0.05+0.25 )
IsTaken = True
EntName$ = EntityName(hu\Shape) : EntKind$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)
Goto LineEndCheckIfTaken
EndIf
Next
.LineEndCheckIfTaken
If( IsTaken = True )
;store pack properties
PackX# = EntityX(p\Shape,True) : PackY# = EntityY(p\Shape,True) : PackZ# = EntityZ(p\Shape,True)
PackKind% = p\Kind
;destroy pack
FreeEntity(p\Shape) : Delete(p)
;create particles of effect
;
;add effect to entity (if player or if bot)
If( EntKind = "HUM" )
hu.Humanoid = Object.Humanoid(EntH)
If( PackKind = CLife )
hu\LifeMS = MilliSecs()
Else If( PackKind = CSpeed )
hu\SpeedMS = MilliSecs()
Else If( PackKind = CShield )
hu\ShieldMS = MilliSecs()
Else If( PackKind = CPower )
hu\PowerMS = MilliSecs()
Else If( PackKind = CBullets )
hu\BulletsCount = hu\BulletsCount+30
Else If( PackKind = CGrenades )
hu\GrenadesCount = hu\GrenadesCount+3
Else If( PackKind = CMines )
hu\MinesCount = hu\MinesCount+3
EndIf
EndIf
EndIf
Next
End Function
Function UpdateEffects()
NowMS% = MilliSecs()
For hu.Humanoid = Each Humanoid
;LifePack effect
If( NowMS - hu\LifeMS < 10000 )
hu\Life = hu\Life + 1
If( hu\Life > 100 )
hu\Life = 100
EndIf
EndIf
;SpeedPack effect
;
;ShieldPack effect
;
;PowerPack effect
;
Next
End Function
Function UpdateTrails()
For tr.Trail = Each Trail
buH% = tr\BulletH
bu.Bullet = Object.Bullet(buH)
D# = Distance3D(EntityX(tr\Shape,True),EntityY(tr\Shape,True),EntityZ(tr\Shape,True),EntityX(bu\Shape,True),EntityY(bu\Shape,True),EntityZ(bu\Shape,True))
ScaleEntity(tr\Shape,1,1,D)
;PositionEntity(tr\Shape,EntityX(bu\Shape,True),EntityY(bu\Shape,True),EntityZ(bu\Shape,True))
;RotateEntity(tr\Shape,EntityPitch(bu\Shape,True),EntityYaw(bu\Shape,True),EntityRoll(bu\Shape,True))
;ScaleEntity(tr\Shape,1.0,1.0,+bu\Velocity)
Next
End Function
executable (Windows) : http://rd-stuff.fr/simple-shooter-3D-201810242122-EXE.zip
(the "mav" when player has no more life points is normal, i have not finished to code this part)
controls :
mouse horizontal axis to turn left/right
WASD (or ZQSD) to move forward/backward/left/right
mouse left to shoot bullets
mouse right to throw a grenade
i plan to had a way to throw a grenade at different ranges by holding the mouse button for some time then releasing it.
the big step is still to code a system where humanoids can turn move jump fall, and detect collisions to be stopped by obstacles.
then this would also allow to add forces which make the humanoids move in the direction of explosions (of a grenade or mine)
Sounds cool. Hopefully an exe too at the end (for those without Blitz3D).
Blitz 3D is free to download these days, I recommend using it with the IDEal UI, So much coding fun within B3D. And... It'd give you a chance to modify Remid s code, the best way to learn IMO.
Blitz 3D lives on ;)
What is funny is that when i was a noob (i started to code 9 years ago, but not continuously) i use to be afraid to post my codes on forums, because i thought that somebody would steal them and make a similar game.
Now i know that for a good enough gameplay, the code has some complex stuff here and there, and keeping a understandable, well organized, error-free, code is not easy, and only a few coders will understand it and be able to use it, so i don't care to post it ;)
(and i don't plan to earn money by selling games anymore, i am more interested in designing/building/selling physical things, like homemade devices which are useful in the real world -> this requires some programming too !)
But making games is a cool hobby in the winter season ! 8)
Quote from: RemiD on October 24, 2018, 17:42:00
What is funny is that when i was a noob (i started to code 9 years ago, but not continuously) i use to be afraid to post my codes on forums, because i thought that somebody would steal them and make a similar game.
Now i know that for a good enough gameplay, the code has some complex stuff here and there, and keeping a understandable, well organized, error-free, code is not easy, and only a few coders will understand it and be able to use it, so i don't care to post it ;)
(and i don't plan to earn money by selling games anymore, i am more interested in designing/building/selling physical things, like homemade devices which are useful in the real world -> this requires some programming too !)
But making games is a cool hobby in the winter season ! 8)
This is exactly how I look at it. I made a little money coding some Amiga stuff back in the nineties but I'm stone-cold realistic enough to know that it's a hard thing to make money from either games or application programming now. I always consider game coding a hobby now and do it just to keep my mind sharp and that invariably helps me with my day job anyway, so it's all win.
I first coded 35 years ago, a little AI stuff in ZXBasic. Probably explains my coding fatigue of late ;D
35 z a big number in the years stakes - thanks to Qube and his coding compo s, my mojo has been reinvigorated invigorated... If only a little, cheers Qube.
@xerra, I got a demo of a blitzbasic app (they were called programs back then), on an Amiga Format cover disk, I can't recall if it was diskette or CD, happy days.
Quote from: 3DzForMe on October 24, 2018, 23:49:40
I first coded 35 years ago, a little AI stuff in ZXBasic. Probably explains my coding fatigue of late ;D
35 z a big number in the years stakes - thanks to Qube and his coding compo s, my mojo has been reinvigorated invigorated... If only a little, cheers Qube.
@xerra, I got a demo of a blitzbasic app (they were called programs back then), on an Amiga Format cover disk, I can't recall if it was diskette or CD, happy days.
I remember the same magazine and even buying it from W.H.Smiths in Liverpool Street station as I was catching a train to work from there that afternoon. Reason I remember all that is because I'd been an Amos guy prior to that and a buddy and I were looking forward to getting the demo so we could collaborate on a game for the competition they were running with the demo.
Think it was another year or so before I actually wrote something worthwhile with it, however. Never did do that collaboration :-(
As for years coding, I've been at it since I first read a book on Basic programs and typed in a few listings on my Vic 20 back in 1981 or so. Got a few years where I didn't code much between then and now, however, even though I've always had a computer of some sort since then.
I wonder what hijacking means ? (related to posting on forums) :P
( in a way i hijacked my own thread by talking about my coding history, ;D )
Quote from: RemiD on October 25, 2018, 17:28:30
I wonder what hijacking means ? (related to posting on forums) :P
( in a way i hijacked my own thread by talking about my coding history, ;D )
Yeah, kinda went on a tangent there. My bad. Sorry, RemiD. I'll save my waffle for another post where I can brag about what an old fart I am :)
no progress for today because i want to add a rebounding effect for grenades (before they explode) but i have difficulties with some maths formulas to add reflections (of vectors) by considering the movement speed, the gravity speed, the air friction, the impact slowdown... and for now it is a buggy mess ;D
I used a physics library to achieve this in the past, JV-ODE is pretty good.
i know that i can use a physics library (i like bullet and jvode), but i want to understand the damn thing !
and at the moment i rather fail ???
Finally, i managed to code something which looks like convincing enough projectile physics : 8) https://www.syntaxbomb.com/index.php/topic,4986.0.html
and this was not as easy as it seems !