January 19, 2021, 08:22:12 PM

### Author Topic: simple collision system using linepicks and pickables  (Read 1087 times)

#### RemiD

• Hero Member
• Posts: 1128
##### simple collision system using linepicks and pickables
« on: October 14, 2018, 08:21:23 PM »
Hello,

I have already posted a more complex version of a collision system using linepicks and pickable shapes, but this one is simple, for simple 3d games with turning moving characters / bullets, for those who want to understand the approach
Code: [Select]
`Graphics3D(1000,625,32,2)HidePointer()SeedRnd(MilliSecs());----------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)Global XTree = CreateTree()HideEntity(XTree)Global XPlayer = CreateCylinder(16)ScaleMesh(XPlayer,0.5/2,1.75/2,0.5/2)PositionMesh(XPlayer,0,0.875,0)EntityColor(XPlayer,000,000,255)HideEntity(XPlayer)Global XBot = CreateCylinder(16)ScaleMesh(XBot,0.5/2,1.75/2,0.5/2)PositionMesh(XBot,0,0.875,0)EntityColor(XBot,125,125,255)HideEntity(XBot)Global XBullet = CreateSphere(8)ScaleMesh(XBullet,0.2/2,0.2/2,0.2/2)EntityColor(XBullet,125,125,125)HideEntity(XBullet)Global XParticle = CreateCube()ScaleMesh(XParticle,0.04/2,0.04/2,0.04/2)EntityColor(XParticle,125,125,125)HideEntity(XParticle);----------------------------------- ;cameraGlobal Camera = CreateCamera()CameraRange(Camera,1,1000)CameraClsColor(Camera,000,000,000);inputGlobal MXDiff%Global MYDiff%;origineOrigine = CreateCube()ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)EntityColor(Origine,255,000,255)EntityFX(Origine,1);groundGlobal GroundShape AddGround();rocksType Rock Field ShapeEnd TypeAddRocks();treesType Tree Field ShapeEnd TypeAddTrees();botsType Bot Field Shape Field Life# Field VX# Field VY# Field VZ# Field PrevMS%End TypeAddBots();playerGlobal PlayerShapeGlobal PlayerYaw#Global PlayerLife#Global PlayerVX#Global PlayerVY#Global PlayerVZ#Global PlayerPrevMS%AddPlayer();bulletsType Bullet Field Shape Field Life# Field VX# Field VY# Field VZ#End Type;particlesType Particle Field Shape Field Life#End Type;lightDLight = CreateLight(1)LightColor(DLight,255,255,255)PositionEntity(DLight,50,1000,-1000)RotateEntity(DLight,45,0,0)AmbientLight(064,064,064);setup pickables entitiesEntityPickMode(GroundShape,2)For r.Rock = Each Rock EntityPickMode(r\Shape,2)NextFor t.Tree = Each tree EntityPickMode(t\Shape,2)NextFor b.Bot = Each Bot EntityPickMode(b\Shape,2)NextEntityPickMode(PlayerShape,2)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)PositionEntity(Camera,EntityX(PlayerShape,True),EntityY(PlayerShape,True),EntityZ(PlayerShape,True))MoveEntity(Camera,0,1.65+1.5,-3.0)TurnEntity(Camera,22.5,0,0)EntityParent(Camera,PlayerShape)Global BulletsCount% = 0 ;to track how many bullets are active in the sceneGlobal ParticlesCount% = 0 ;to track how many particles are active in the sceneGlobal MainLoopTimer = CreateTimer(30) ;to lock the FPS at 30FPS max;mainloopMain()End()Function Main() Repeat  MXDiff = MouseXSpeed()  MYDiff = MouseYSpeed()  ;update player depending on input (mouse and keyboard)  UpdatePlayer()  ;update bots depending on ai  UpdateBots()  ;update bullets  UpdateBullets()  ;update particles  UpdateParticles()  WireFrame(False)  If( KeyDown(2)=True )   WireFrame(True)  EndIf  ;render  RenderWorld()  Text(0,0,"BulletsCount = "+BulletsCount)  Text(0,16,"ParticlesCount = "+ParticlesCount)  ;display the result on the screen  ;Flip(1)  WaitTimer(MainLoopTimer)  VWait():Flip(False) Until( KeyDown(1)=1 )End FunctionFunction 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 DMeshEnd FunctionFunction CreateTree() DMesh = CreateMesh() ;trunc CreateSurface(DMesh) TPart= CreateCylinder(8) ScaleMesh(TPart,0.3/2,3.0/2,0.3/2) PositionMesh(TPart,0,3.0/2,0) For SI% = 1 To CountSurfaces(TPart) Step 1  AddSurfaceToOtherSurface(GetSurface(TPart,SI),TPart,GetSurface(DMesh,1),DMesh) Next FreeEntity(TPart) ColorWithBrush(GetSurface(DMesh,1),100,050,000) ;leaves CreateSurface(DMesh) TPart = CreateCone(8) ScaleMesh(TPart,3.0/2,6.0/2,3.0/2) PositionMesh(TPart,0,3.0+6.0/2,0) For SI% = 1 To CountSurfaces(TPart) Step 1  AddSurfaceToOtherSurface(GetSurface(TPart,SI),TPart,GetSurface(DMesh,2),DMesh) Next FreeEntity(TPart) ColorWithBrush(GetSurface(DMesh,2),000,100,000) Return DMeshEnd FunctionFunction Distance2D#(PAX#,PAZ#,PBX#,PBZ#) Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance2DEnd FunctionFunction Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance3DEnd 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,VV)  ;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 FunctionFunction 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) NameEntity(GroundShape,"GRO"+Str(1))End FunctionFunction 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)  NameEntity(r\Shape,"ROC"+Handle(r)) NextEnd FunctionFunction 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 < 2.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)  NameEntity(t\Shape,"TRE"+Handle(t)) NextEnd FunctionFunction AddBots() For n% = 1 To 10 Step 1  ;choose a position  .LineChooseBotPosition  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 LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   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 LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   EndIf  Next  ;check if this position is far enough from others existing bots  For bb.Bot = Each Bot   D# = Distance2D(X,Z,EntityX(bb\Shape,True),EntityZ(bb\Shape,True))   If( D < 0.25+0.25+1.0 )    Goto LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   EndIf  Next  b.Bot = New Bot  b\Shape = CopyEntity(XBot)  PositionEntity(b\Shape,X,0,Z)  b\Life = 1.0  b\PrevMS = MilliSecs()  NameEntity(b\Shape,"BOT"+Handle(b)) NextEnd FunctionFunction AddPlayer() PlayerShape = CopyEntity(XPlayer) PositionEntity(PlayerShape,50,0,50) PlayerLife = 1.0 PlayerPrevMS = MilliSecs() NameEntity(PlayerShape,"PLA"+Str(1))End FunctionFunction UpdatePlayer()  ;turn left/right MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2) PlayerYaw = PlayerYaw - Float(MXDiff)/10 RotateEntity(PlayerShape,0,PlayerYaw,0,False) ;move forward/backward/left/right If( KeyDown(17)=0 And KeyDown(31)=0 And KeyDown(30)=0 And KeyDown(32)=0 )   TFormVector(0,0,0,PlayerShape,0) Else If( KeyDown(17)=1 )   TFormVector(0,0,+0.347,PlayerShape,0) ;player speed is 0.347 Else If( KeyDown(31)=1 )   TFormVector(0,0,-0.347,PlayerShape,0) ;player speed is 0.347 Else If( KeyDown(30)=1 )    TFormVector(-0.347,0,0,PlayerShape,0) ;player speed is 0.347 Else If( KeyDown(32)=1 )   TFormVector(+0.347,0,0,PlayerShape,0) ;player speed is 0.347 EndIf  ;calculates the movement vector PlayerVX = TFormedX() : PlayerVY = TFormedY() : PlayerVZ = TFormedZ() ;before moving player, check if it will collides with an obstacle entity (tree or bot) TFormPoint(0,0.25,0,PlayerShape,0) ;root of Player shape +0.25 (on the Y axis) LinePick(TFormedX(),TFormedY(),TFormedZ(),PlayerVX,PlayerVY,PlayerVZ,0.25-0.01) ;player ellipsoid radius is 0.25 ;throws a linepick from the position of player root +0.25 to direction of the movement vector EntRef% = PickedEntity() ;if yes If( EntRef <> 0 )  ;debug collision point / normal  PositionEntity(PickPoint,PickedX(),PickedY(),PickedZ())  PositionEntity(PickNormal,PickedX(),PickedY(),PickedZ()) : AlignToVector(PickNormal,PickedNX(),PickedNY(),PickedNZ(),3,1.0)  ;recalculate the appropriate position  PlayerX# = EntityX(PlayerShape,True) : PlayerY# = EntityY(PlayerShape,True) : PlayerZ# = EntityZ(PlayerShape,True)  PickX# = PickedX() : PickY# = PickedZ() : PickZ# = PickedZ()  D# = Distance2D(PlayerX,PlayerZ,PickX,PickZ)  TCoeff# = (D-0.25)/(0.347)  PlayerVX = PlayerVX*TCoeff : PlayerVZ = PlayerVZ*TCoeff  ;move player  TranslateEntity(PlayerShape,PlayerVX,PlayerVY,PlayerVZ) ;if no Else If( EntRef = 0 )  ;move player  TranslateEntity(PlayerShape,PlayerVX,PlayerVY,PlayerVZ) EndIf ;shoot a bullet If( MouseHit(1)=1 )  NowMS% = MilliSecs()  ;allow to shoot a new bullet only if the previous bullet was shot more than 100ms ago (1000milliseconds = 1second)  If( NowMS - PlayerPrevMS > 100 )   ;create a new bullet   BulletsCount = BulletsCount + 1   bu.bullet = New bullet   bu\Shape = CopyEntity(XBullet)   PositionEntity(bu\Shape,EntityX(PlayerShape,True),EntityY(PlayerShape,True)+0.875,EntityZ(PlayerShape,True))   RotateEntity(bu\Shape,EntityPitch(PlayerShape,True),EntityYaw(PlayerShape,True),EntityRoll(PlayerShape,True))   TurnEntity(bu\Shape,Rand(-1,+1),Rand(-1,+1),0)   bu\Life# = 1.0   PlayerPrevMS = NowMS  EndIf EndIfEnd FunctionFunction UpdateBots() For bo.Bot = Each Bot  ;depending on ai (wander, pursue and attack, flee and hide), decide how bot will move / act NextEnd FunctionFunction UpdateBullets() For bu.Bullet = Each Bullet  ;decrease bullet life so that it does not last forever  bu\Life = bu\Life - 0.01  ;if life is more than 0, update the bullet  If( bu\Life > 0 )   ;calculates the movement vector   TFormVector(0,0,+1.2,bu\Shape,0) ;bullet speed is 1.2   ;calculates the movement vector   bu\VX = TFormedX() : bu\VY = TFormedY() : bu\VZ = TFormedZ()   ;before moving the bullet, check if it will collides with an obstacle entity (tree or player or bot)   TFormPoint(0,0,0,bu\Shape,0) ;root of bullet shape    LinePick(TFormedX(),TFormedY(),TFormedZ(),bu\VX,bu\VY,bu\VZ,0.1) ;bullet ellipsoid radius is 0.1 ;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.1)/(1.2)    bu\VX = bu\VX*TCoeff : bu\VZ = bu\VZ*TCoeff    ;move bullet    TranslateEntity(bu\Shape,bu\VX,bu\VY,bu\VZ)    ;destroy the bullet    FreeEntity(bu\Shape) : Delete(bu)    BulletsCount = BulletsCount - 1    ;get kind of the picked entity    EntName\$ = EntityName(EntRef) : EntKind\$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)    If( EntKind = "GRO" )     MaterialR% = 050 : MaterialG% = 150 : MaterialB% = 050    Else If( EntKind = "ROC" )     MaterialR% = 125 : MaterialG% = 125 : MaterialB% = 125    Else If( EntKind = "TRE" )     MaterialR% = 100 : MaterialG% = 050 : MaterialB% = 000    Else If( EntKind = "BOT" )     MaterialR% = 125 : MaterialG% = 125 : MaterialB% = 255    Else If( EntKind = "PLA" )     MaterialR% = 000 : MaterialG% = 000 : MaterialB% = 255    EndIf    ;create some particles    For n% = 1 To 16 Step 1     pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1     pa\Shape = CopyEntity(XParticle)     EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)     PositionEntity(pa\Shape,PickX,PickY,PickZ,True)     AlignToVector(pa\Shape,PickNX,PickNY,PickNZ,3,1.0) : TurnEntity(pa\Shape,Rand(-45,+45),Rand(-45,+45),0)     pa\Life# = 1.0    Next   ;if no   Else If( EntRef = 0 )    ;move the bullet    TranslateEntity(bu\Shape,bu\VX,bu\VY,bu\VZ)   EndIf  ;if life is equal or less than 0, destroy the bullet  Else If( bu\Life <= 0 )   FreeEntity(bu\Shape) : Delete(bu)   BulletsCount = BulletsCount - 1  EndIf NextEnd FunctionFunction UpdateParticles() For pa.Particle = Each Particle  MoveEntity(pa\Shape,0,0,0.03)  pa\Life = pa\Life - 0.03  EntityAlpha(pa\Shape,pa\Life)  If( pa\Life <= 0 )    FreeEntity(pa\Shape) : Delete(pa)   ParticlesCount = ParticlesCount - 1  EndIf NextEnd Function`
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

#### RemiD

• Hero Member
• Posts: 1128
##### Re: simple collision system using linepicks and pickables
« Reply #1 on: October 22, 2018, 08:33:45 PM »
same world / entities / gameplay, but this time the code is modified in a way to have the collisions detection / repositionning with ellipsoids and collidable shapes (Blitz3d collision system)

Code: [Select]
`Graphics3D(1000,625,32,2)HidePointer()SeedRnd(MilliSecs());----------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)Global XTree = CreateTree()HideEntity(XTree)Global XPlayer = CreateCylinder(16)ScaleMesh(XPlayer,0.5/2,1.75/2,0.5/2)PositionMesh(XPlayer,0,0.875,0)EntityColor(XPlayer,000,000,255)HideEntity(XPlayer)Global XBot = CreateCylinder(16)ScaleMesh(XBot,0.5/2,1.75/2,0.5/2)PositionMesh(XBot,0,0.875,0)EntityColor(XBot,125,125,255)HideEntity(XBot)Global XBullet = CreateSphere(8)ScaleMesh(XBullet,0.2/2,0.2/2,0.2/2)EntityColor(XBullet,125,125,125)HideEntity(XBullet)Global XParticle = CreateCube()ScaleMesh(XParticle,0.04/2,0.04/2,0.04/2)EntityColor(XParticle,125,125,125)HideEntity(XParticle);----------------------------------- ;cameraGlobal Camera = CreateCamera()CameraRange(Camera,1,1000)CameraClsColor(Camera,000,000,000);inputGlobal MXDiff%Global MYDiff%;origineOrigine = CreateCube()ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)EntityColor(Origine,255,000,255)EntityFX(Origine,1);groundGlobal GroundShape AddGround();rocksType Rock Field ShapeEnd TypeAddRocks();treesType Tree Field ShapeEnd TypeAddTrees();botsType Bot Field Ellipsoid Field Shape Field Life# Field PrevMS%End TypeAddBots();playerGlobal PlayerEllipsoidGlobal PlayerShapeGlobal PlayerYaw#Global PlayerLife#Global PlayerPrevMS%AddPlayer();bulletsType Bullet Field Ellipsoid Field Shape Field Life#End Type;particlesType Particle Field Shape Field Life#End Type;lightDLight = CreateLight(1)LightColor(DLight,255,255,255)PositionEntity(DLight,50,1000,-1000)RotateEntity(DLight,45,0,0)AmbientLight(064,064,064);setup collision groups (do not confuse "EntityType()" which define a group of entities and "Type End Type" which define a customtype variable !!! )Const GShape% = 1Const GTurningMoving% = 2EntityType(GroundShape,GShape)For r.Rock = Each Rock EntityType(r\Shape,GShape)NextFor t.Tree = Each Tree EntityType(t\Shape,GShape)NextFor bo.Bot = Each Bot EntityType(bo\Shape,GShape) : EntityType(bo\Ellipsoid,GTurningMoving)NextEntityType(PlayerShape,GShape) : EntityType(PlayerEllipsoid,GTurningMoving);setup collidables entities and collisions detection / responseCollisions(GTurningMoving,GShape,2,1)EntityPickMode(GroundShape,2) For r.Rock = Each Rock EntityPickMode(r\Shape,2)NextFor t.Tree = Each tree EntityPickMode(t\Shape,2)NextFor b.Bot = Each Bot EntityPickMode(b\Shape,2) : NextEntityPickMode(PlayerShape,2) : Global CollPoint = CreateCube()ScaleMesh(CollPoint,0.03/2,0.03/2,0.03/2)EntityColor(CollPoint,255,000,255)EntityFX(CollPoint,1)Global CollNormal = CreateCube()ScaleMesh(CollNormal,0.01/2,0.01/2,0.3/2)PositionMesh(CollNormal,0,0,0.3/2)EntityColor(CollNormal,125,000,125)EntityFX(CollNormal,1)PositionEntity(Camera,EntityX(PlayerShape,True),EntityY(PlayerShape,True),EntityZ(PlayerShape,True))MoveEntity(Camera,0,1.65+1.5,-3.0)TurnEntity(Camera,22.5,0,0)EntityParent(Camera,PlayerShape)Global BulletsCount% = 0 ;to track how many bullets are active in the sceneGlobal ParticlesCount% = 0 ;to track how many particles are active in the sceneGlobal MainLoopTimer = CreateTimer(30) ;to lock the FPS at 30FPS max;mainloopMain()End()Function Main() Repeat  MXDiff = MouseXSpeed()  MYDiff = MouseYSpeed()  ;update player before collisions (depending on input mouse/keyboard)  UpdatePlayerBC()  ;update bots before collisions (depending on ai)  UpdateBotsBC()  ;update bullets before collisions  UpdateBulletsBC()  ;detect collisions + response (reposition)  UpdateWorld()  ;update player after collisions  UpdatePlayerAC()  ;update bots after collisions  UpdateBotsAC()  ;update bullets after collisions  UpdateBulletsAC()  ;update particles  UpdateParticles()  WireFrame(False)  If( KeyDown(2)=True )   WireFrame(True)  EndIf  ;render  RenderWorld()  Text(0,0,"BulletsCount = "+BulletsCount)  Text(0,16,"ParticlesCount = "+ParticlesCount)  ;display the result on the screen  ;Flip(1)  WaitTimer(MainLoopTimer)  VWait():Flip(False) Until( KeyDown(1)=1 )End FunctionFunction 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 DMeshEnd FunctionFunction CreateTree() DMesh = CreateMesh() ;trunc CreateSurface(DMesh) TPart= CreateCylinder(8) ScaleMesh(TPart,0.3/2,3.0/2,0.3/2) PositionMesh(TPart,0,3.0/2,0) For SI% = 1 To CountSurfaces(TPart) Step 1  AddSurfaceToOtherSurface(GetSurface(TPart,SI),TPart,GetSurface(DMesh,1),DMesh) Next FreeEntity(TPart) ColorWithBrush(GetSurface(DMesh,1),100,050,000) ;leaves CreateSurface(DMesh) TPart = CreateCone(8) ScaleMesh(TPart,3.0/2,6.0/2,3.0/2) PositionMesh(TPart,0,3.0+6.0/2,0) For SI% = 1 To CountSurfaces(TPart) Step 1  AddSurfaceToOtherSurface(GetSurface(TPart,SI),TPart,GetSurface(DMesh,2),DMesh) Next FreeEntity(TPart) ColorWithBrush(GetSurface(DMesh,2),000,100,000) Return DMeshEnd FunctionFunction Distance2D#(PAX#,PAZ#,PBX#,PBZ#) Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance2DEnd FunctionFunction Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance3DEnd 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,VV)  ;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 FunctionFunction 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) NameEntity(GroundShape,"GRO"+Str(1))End FunctionFunction 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)  NameEntity(r\Shape,"ROC"+Handle(r)) NextEnd FunctionFunction 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 < 2.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)  NameEntity(t\Shape,"TRE"+Handle(t)) NextEnd FunctionFunction AddBots() For n% = 1 To 10 Step 1  ;choose a position  .LineChooseBotPosition  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 LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   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 LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   EndIf  Next  ;check if this position is far enough from others existing bots  For bb.Bot = Each Bot   D# = Distance2D(X,Z,EntityX(bb\Shape,True),EntityZ(bb\Shape,True))   If( D < 0.25+0.25+1.0 )    Goto LineChooseBotPosition ;i have not added a check to exit the loop in case there are no more empty space, so don't add too many bots !!!   EndIf  Next  b.Bot = New Bot  b\Shape = CopyEntity(XBot)  b\Ellipsoid = CreatePivot()  EntityRadius(b\Ellipsoid,0.24)  PositionEntity(b\Ellipsoid,X,0.24+0.1,Z)  b\Life = 1.0  b\PrevMS = MilliSecs()  NameEntity(b\Shape,"BOT"+Handle(b)) NextEnd FunctionFunction AddPlayer() PlayerShape = CopyEntity(XPlayer) PlayerEllipsoid = CreatePivot() EntityRadius(PlayerEllipsoid,0.24) PositionEntity(PlayerEllipsoid,50,0.24+0.1,50) PlayerLife = 1.0 PlayerPrevMS = MilliSecs() NameEntity(PlayerShape,"PLA"+Str(1))End FunctionFunction UpdatePlayerBC() ;turn left/right MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2) PlayerYaw = PlayerYaw - Float(MXDiff)/10 RotateEntity(PlayerEllipsoid,0,PlayerYaw,0,False) ;move forward/backward/left/right If( KeyDown(17)=0 And KeyDown(31)=0 And KeyDown(30)=0 And KeyDown(32)=0 )   MoveEntity(PlayerEllipsoid,0,0,0) Else If( KeyDown(17)=1 )   MoveEntity(PlayerEllipsoid,0,0,+0.347) Else If( KeyDown(31)=1 )   MoveEntity(PlayerEllipsoid,0,0,-0.347) Else If( KeyDown(30)=1 )    MoveEntity(PlayerEllipsoid,-0.347,0,0) Else If( KeyDown(32)=1 )   MoveEntity(PlayerEllipsoid,+0.347,0,0) EndIf  ;shoot a bullet If( MouseHit(1)=1 )  NowMS% = MilliSecs()  ;allow to shoot a new bullet only if the previous bullet was shot more than 100ms ago (1000milliseconds = 1second)  If( NowMS - PlayerPrevMS > 100 )   ;create a new bullet   BulletsCount = BulletsCount + 1   bu.bullet = New bullet   bu\Shape = CopyEntity(XBullet)   bu\Ellipsoid = CreatePivot()   PositionEntity(bu\Ellipsoid,EntityX(PlayerShape,True),EntityY(PlayerShape,True)+0.875,EntityZ(PlayerShape,True))   RotateEntity(bu\Ellipsoid,EntityPitch(PlayerShape,True),EntityYaw(PlayerShape,True),EntityRoll(PlayerShape,True))   MoveEntity(bu\Ellipsoid,0,0,+0.25+0.1+0.01)   TurnEntity(bu\Ellipsoid,Rand(-1,+1),Rand(-1,+1),0)   bu\Life# = 1.0   EntityRadius(bu\Ellipsoid,0.1)   EntityType(bu\Shape,GShape) : EntityType(bu\Ellipsoid,GTurningMoving)   PlayerPrevMS = NowMS  EndIf EndIf End FunctionFunction UpdateBotsBC() For bo.Bot = Each Bot  ;depending on ai (wander, pursue and attack, flee and hide), decide how bot will move / act NextEnd FunctionFunction UpdateBulletsBC() For bu.Bullet = Each Bullet  ;decrease bullet life so that it does not last forever  bu\Life = bu\Life - 0.01  ;if life is more than 0, update the bullet  If( bu\Life > 0 )   ;move the bullet   MoveEntity(bu\Ellipsoid,0,0,+1.2)  ;if life is equal or less than 0, destroy the bullet  Else If( bu\Life <= 0 )   FreeEntity(bu\Shape) : Delete(bu)   BulletsCount = BulletsCount - 1  EndIf NextEnd FunctionFunction UpdatePlayerAC() ;position rotate PlayerShape depending on PlayerEllipsoid position orientation (-0.25 on the Y axis because of the ellipsoid radius) PositionEntity(PlayerShape,EntityX(PlayerEllipsoid,True),EntityY(PlayerEllipsoid,True)-0.25,EntityZ(PlayerEllipsoid,True)) RotateEntity(PlayerShape,EntityPitch(PlayerEllipsoid,True),EntityYaw(PlayerEllipsoid,True),EntityRoll(PlayerEllipsoid,True)) ;retrieve infos about the collisions which happened between Player ellipsoid and others collidables ;count the number of collisions which happened to Player ellipsoid CC% = CountCollisions(PlayerEllipsoid) ;if there was at least one collision (i only consider the first) If( CC > 0 )   EntRef% = CollisionEntity(PlayerEllipsoid,1) : EntName\$ = EntityName(EntRef) : EntKind\$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)  CollX# = CollisionX(PlayerEllipsoid,1) : CollY# = CollisionY(PlayerEllipsoid,1) : CollZ# = CollisionZ(PlayerEllipsoid,1)  CollNX# = CollisionNX(PlayerEllipsoid,1) : CollNY# = CollisionNY(PlayerEllipsoid,1) : CollNZ# = CollisionNZ(PlayerEllipsoid,1)  ;debug collision point and collision normal  PositionEntity(CollPoint,CollX,CollY,CollZ)  PositionEntity(CollNormal,CollX,CollY,CollZ) : AlignToVector(CollNormal,CollNX,CollNY,CollNZ,3,1.0)  ;update Player consequently EndIfEnd FunctionFunction UpdateBotsAC() For bo.Bot = Each Bot  ;position rotate bot Shape depending on bot ellipsoid position orientation (-0.25 on the Y axis because of the ellipsoid radius)  PositionEntity(bo\Shape,EntityX(bo\Ellipsoid,True),EntityY(bo\Ellipsoid,True)-0.25,EntityZ(bo\Ellipsoid,True))  RotateEntity(bo\Shape,EntityPitch(bo\Ellipsoid,True),EntityYaw(bo\Ellipsoid,True),EntityRoll(bo\Ellipsoid,True))  ;retrieve infos about the collisions which happened between bot ellipsoid and others collidables  ;count the number of collisions which happened to bot ellipsoid  ;CC% = CountCollisions(bo\Ellipsoid)  ;if there was at least one collision (i only consider the first)  ;If( CC > 0 )    ;EntRef% = CollisionEntity(bo\Ellipsoid,1) : EntName\$ = EntityName(EntRef) : EntKind\$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)   ;CollX# = CollisionX(bo\Ellipsoid,1) : CollY# = CollisionY(bo\Ellipsoid,1) : CollZ# = CollisionZ(bo\Ellipsoid,1)   ;CollNX# = CollisionNX(bo\Ellipsoid,1) : CollNY# = CollisionNY(bo\Ellipsoid,1) : CollNZ# = CollisionNZ(bo\Ellipsoid,1)   ;update Bot consequently  ;EndIf NextEnd FunctionFunction UpdateBulletsAC() For bu.Bullet = Each Bullet  ;position rotate bullet Shape depending on bullet ellipsoid position orientation  PositionEntity(bu\Shape,EntityX(bu\Ellipsoid,True),EntityY(bu\Ellipsoid,True)-0.25,EntityZ(bu\Ellipsoid,True))  RotateEntity(bu\Shape,EntityPitch(bu\Ellipsoid,True),EntityYaw(bu\Ellipsoid,True),EntityRoll(bu\Ellipsoid,True))  ;retrieve infos about the collisions which happened between Bullet ellipsoid and others collidables  ;count the number of collisions which happened to Bullet ellipsoid  CC% = CountCollisions(bu\Ellipsoid)  ;if there was at least one collision (i only consider the first)  If( CC > 0 )    EntRef% = CollisionEntity(bu\Ellipsoid,1) : EntName\$ = EntityName(EntRef) : EntKind\$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)   CollX# = CollisionX(bu\Ellipsoid,1) : CollY# = CollisionY(bu\Ellipsoid,1) : CollZ# = CollisionZ(bu\Ellipsoid,1)   CollNX# = CollisionNX(bu\Ellipsoid,1) : CollNY# = CollisionNY(bu\Ellipsoid,1) : CollNZ# = CollisionNZ(bu\Ellipsoid,1)   ;update bot consequently   ;destroy the bullet   FreeEntity(bu\Shape) : FreeEntity(bu\Ellipsoid) : Delete(bu)   BulletsCount = BulletsCount - 1   ;get kind of the picked entity   EntName\$ = EntityName(EntRef) : EntKind\$ = Left(EntName,3) : EntH% = Right(EntName,Len(EntName)-3)   If( EntKind = "GRO" )    MaterialR% = 050 : MaterialG% = 150 : MaterialB% = 050   Else If( EntKind = "ROC" )    MaterialR% = 125 : MaterialG% = 125 : MaterialB% = 125   Else If( EntKind = "TRE" )    MaterialR% = 100 : MaterialG% = 050 : MaterialB% = 000   Else If( EntKind = "BOT" )    MaterialR% = 125 : MaterialG% = 125 : MaterialB% = 255   Else If( EntKind = "PLA" )    MaterialR% = 000 : MaterialG% = 000 : MaterialB% = 255   EndIf   ;create some particles   For n% = 1 To 16 Step 1    pa.Particle = New Particle : ParticlesCount = ParticlesCount + 1    pa\Shape = CopyEntity(XParticle)    EntityColor(pa\Shape,MaterialR,MaterialG,MaterialB)    PositionEntity(pa\Shape,CollX,CollY,CollZ,True)    AlignToVector(pa\Shape,CollNX,CollNY,CollNZ,3,1.0) : TurnEntity(pa\Shape,Rand(-45,+45),Rand(-45,+45),0)    pa\Life# = 1.0   Next  EndIf  NextEnd FunctionFunction UpdateParticles() For pa.Particle = Each Particle  MoveEntity(pa\Shape,0,0,0.03)  pa\Life = pa\Life - 0.03  EntityAlpha(pa\Shape,pa\Life)  If( pa\Life <= 0 )    FreeEntity(pa\Shape) : Delete(pa)   ParticlesCount = ParticlesCount - 1  EndIf NextEnd Function`
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0