Bonjour,
J'ai remarqué qu'en utilisant RotateSprite, le SpritePixelCollision ne fonctionne pas correctement... Très dommage, même en utilisant les options #PB_Sprite_PixelCollision lors du chargement du Sprite et en utilisant DisplayTransparentSprite à l'affichage, la détection des collisions n'est pas correcte.
Je ne rencontrais pas ce problème avec le langage Phrogram...
Si vous avez une idée, merci à vous.
RotateSprite et SpritePixelCollision
Re: RotateSprite et SpritePixelCollision
C'est dommage que ce vieux bug soit toujours là.
Une façon de faire est de détecter la collision à la main:
M.
Une façon de faire est de détecter la collision à la main:
Code : Tout sélectionner
#Window_main = 0
Structure point_f
x.f
y.f
EndStructure
Procedure inpoly(*p.point_f, List poly.point_f())
Protected.point_f new, old, lp, rp
Protected inside
;If ListSize(poly()) < 3: ProcedureReturn 0: EndIf
LastElement(poly()): old = poly()
ForEach poly()
;find leftmost endpoint 'lp' and the rightmost endpoint 'rp' based on x value
If poly()\x > old\x
lp = old
rp = poly()
Else
lp = poly()
rp = old
EndIf
If lp\x < *p\x And *p\x <= rp\x And (*p\y - lp\y) * (rp\x - lp\x) < (rp\y - lp\y) * (*p\x - lp\x)
inside = ~inside
EndIf
old = poly()
Next
ProcedureReturn inside & 1
EndProcedure
Global NewList v.point_f()
If InitSprite() =0 Or InitKeyboard() =0
End
EndIf
Procedure SpriteTransformation(Sprite.i, X.f, Y.f, Width.f, Height.f, Angle.f, x0.f,y0.f)
; by stargate
Protected Cos.f = Cos(Radian(Angle))
Protected Sin.f = Sin(Radian(Angle))
TransformSprite(Sprite, X*Cos-Y*Sin, X*Sin+Y*Cos, (X+Width)*Cos-Y*Sin, (X+Width)*Sin+Y*Cos, (X+Width)*Cos-(Y+Height)*Sin,
(X+Width)*Sin+(Y+Height)*Cos, X*Cos-(Y+Height)*Sin, X*Sin+(Y+Height)*Cos)
AddElement(v())
v()\x = X*Cos-Y*Sin+x0
v()\y = X*Sin+Y*Cos+y0
AddElement(v())
v()\x = (X+Width)*Cos-Y*Sin +x0
v()\y = (X+Width)*Sin+Y*Cos+y0
AddElement(v())
v()\x = (X+Width)*Cos-(Y+Height)*Sin+x0
v()\y = (X+Width)*Sin+(Y+Height)*Cos+y0
AddElement(v())
v()\x = X*Cos-(Y+Height)*Sin+x0
v()\y = X*Sin+(Y+Height)*Cos+y0
EndProcedure
Define.point_f mp
flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
WinW =1024
WinH =768
If OpenWindow(#Window_main,0,0,WinW,WinH, "Sprite selection", Flag) = 0
End
EndIf
If OpenWindowedScreen(WindowID(0), 0,0,WinW,WinH) = 0
End
EndIf
UsePNGImageDecoder()
LoadSprite(0,#PB_Compiler_Home+"Examples\Sources\Data\PurebasicLogo.bmp",#PB_Sprite_PixelCollision)
CopySprite(0,1,#PB_Sprite_PixelCollision)
W =SpriteWidth(0)
H =SpriteHeight(0)
r.d = 1
x = 150
y = 150
x1.f = 450.0
y1.f = 400.0
CreateSprite(2,200,40,#PB_Sprite_PixelCollision)
cursor = 3
CreateSprite(cursor,4,4,#PB_Sprite_PixelCollision)
If StartDrawing(SpriteOutput(3))
Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))
StopDrawing()
EndIf
SpriteTransformation(1, -10,-(h*r)/2, w*r, h*r ,60, x1, y1) ; mis en dehors de la boucle pour ne pas remplir la liste inutilement: A OPTIMISER
Repeat
Repeat
EventID = WindowEvent()
Select EventID
Case #PB_Event_CloseWindow
End
EndSelect
Until event = 0
ClearScreen(RGB(50,50,50))
mx = WindowMouseX(0)
my = WindowMouseY(0)
mp\x = mx
mp\y = my
DisplayTransparentSprite(cursor,mx,my,255,RGBA(255,255,255,255))
txt$ = ""
If SpritePixelCollision(0,x,y,cursor,mx,my) <> 0
txt$ = "mouse over sprite0"
EndIf
DisplayTransparentSprite(0,x,y,255,#Red)
; SpriteTransformation(1, -10,-(h*r)/2, w*r, h*r ,60, x1, y1); ; mis en dehors de la boucle pour ne pas remplir la liste inutilement: A OPTIMISER
DisplaySprite(1,x1,y1)
If inpoly(mp, v())
txt1$ = "mouse over sprite1"
Else
txt1$=""
EndIf
If StartDrawing(SpriteOutput(2))
Box(0,0,OutputWidth(),OutputHeight(),0)
DrawText(0,0,txt$+" | " +txt1$)
StopDrawing()
EndIf
DisplaySprite(2,0,0)
FlipBuffers()
Until Quit = 1
[/code]
Etrangement ce code fonctionne chez moi sans astuce !?
[code]EnableExplicit
;Quelques variables
Global Event
Global Image
Global Ground
Global Ennemy
Global Ball, BallX = 100, BallY = 200
Global BallVelocityX.f = 1, BallVelocityY.f = 0, BallGravityY.f = 2
;Initialisation diverses
If InitSprite()
InitKeyboard()
InitMouse()
EndIf
UsePNGImageDecoder()
UsePNGImageEncoder()
;Creation du screen
OpenWindow(0, 0, 0, 800, 600, "Jeux 1 - Saut touche 'HAUT' au clavier", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)
;Création et sauvegarde de l'image de référence pour la création des autres sprites
;Cette image est sauvegardée au format PNG afin de gérér la transparence.
Image = CreateImage(#PB_Any, 8, 8, 24, RGB(255, 255, 255))
SaveImage(Image, "WhiteSquare.png", #PB_ImagePlugin_PNG)
;Creation du sol
Ground = LoadSprite(#PB_Any, "WhiteSquare.png")
ZoomSprite(Ground, 800, 32)
;Création d'un obstacle
Ennemy = LoadSprite(#PB_Any, "WhiteSquare.png")
ZoomSprite(Ennemy, 32, 32)
;Creation de la ball
Ball = LoadSprite(#PB_Any, "WhiteSquare.png")
ZoomSprite(Ball, 32, 32)
;Boucle evenementielle
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0 ;Plus d'évenement fenêtre
FlipBuffers()
ClearScreen(RGB(135, 206, 235))
;Adfichage des sprites
DisplaySprite(Ground, 0, 570)
DisplaySprite(Ennemy, 384, 537)
DisplaySprite(Ball, BallX, BallY)
;Evenement clavier : Touche Up => Impulsion vers le haut
ExamineKeyboard()
;Pour pouvoir effectuer un saut la balle ne doit plus bouger
If KeyboardReleased(#PB_Key_Up) And BallVelocityY = 0
BallVelocityY = -30 ;La balle va monter
EndIf
;Affichage de la balle
If BallVelocityY <> 0
BallX + BallVelocityX ;Déplacement à droite
RotateSprite(Ball, 2, #PB_Relative) ;Une petite rotation
EndIf
;La balle est en mouvement
;Elle va monter puis redescendre
BallVelocityY + BallGravityY
BallY + BallVelocityY
; C'est le moment de tester la collision de La balle avec un obstacle
; ici se sera le sol.
If SpriteCollision(Ball, BallX, BallY+10, Ground, 0, 570)
BallY = 537 ; Ajustement de la position Y de la balle
BallVelocityY = 0 ;Interdiction de bouger
; RotateSprite(Ball, 0, #PB_Absolute) ;Plus de rotation
EndIf
;Collision avec l'ennemi
If SpriteCollision(Ball, BallX, BallY+10, Ennemy, 384, 537)
BallY = 505 ; Ajustement de la position Y de la balle
BallVelocityY = 0 ;Interdiction de bouger
; RotateSprite(Ball, 0, #PB_Absolute) ;Plus de rotation
EndIf
Until KeyboardPushed(#PB_Key_Escape)
Dernière modification par Mesa le ven. 28/mai/2021 8:17, modifié 1 fois.
Re: RotateSprite et SpritePixelCollision
Bonjour,
Bien sûr, le deuxième code fonctionne, mais la collision n'a pas la précision voulue. Si on augmente la taille du carré, on verra que la collision ne se fait
pas avec précision car la détection se fait avec la "surface" initiale du sprite avant rotation, c'est à dire pour m'expliquer, dans les pixels qui se trouvent dans le carré avant rotation de celui-ci :
************** * Dans ce petit dessin, le sprite initial est carré. après rotation il ressemble au losange. La détection de
* * * * la collision ne se fera que sur la surface commune aux 2 figures (si on superpose les 2 dessins, il y a bien
* * * * des pixels communs et ce n'est que sur ceux-là que le détection se fera), ce qui est dommage pour la
* * * * précision, car comme je le disais, ce problème n'existe pas dans un langage comme Phrogram que j'ai
************** * déjà utilisé.
Bien sûr, le deuxième code fonctionne, mais la collision n'a pas la précision voulue. Si on augmente la taille du carré, on verra que la collision ne se fait
pas avec précision car la détection se fait avec la "surface" initiale du sprite avant rotation, c'est à dire pour m'expliquer, dans les pixels qui se trouvent dans le carré avant rotation de celui-ci :
************** * Dans ce petit dessin, le sprite initial est carré. après rotation il ressemble au losange. La détection de
* * * * la collision ne se fera que sur la surface commune aux 2 figures (si on superpose les 2 dessins, il y a bien
* * * * des pixels communs et ce n'est que sur ceux-là que le détection se fera), ce qui est dommage pour la
* * * * précision, car comme je le disais, ce problème n'existe pas dans un langage comme Phrogram que j'ai
************** * déjà utilisé.
Re: RotateSprite et SpritePixelCollision
Ouah, mon petit dessin n'a pas marché, je viens d'en faire un vite fait sur Powerpoint pour expliquer :
1) Le sprite initial est carré
2) il est tourné de 45 degrés
3) Voilà ce que ça donne si on les supperpose
4) Et la surface commune sur laquelle se fera la détection des collisions (en jaune). On voit que cela est moins précis lorsqu'on fait subir des rotations aux sprites.
1) Le sprite initial est carré
2) il est tourné de 45 degrés
3) Voilà ce que ça donne si on les supperpose
4) Et la surface commune sur laquelle se fera la détection des collisions (en jaune). On voit que cela est moins précis lorsqu'on fait subir des rotations aux sprites.
Re: RotateSprite et SpritePixelCollision
Ce n'est pas un bug à proprement parler, ce n'est juste pas implanté.(trop complexe)
Tu peux faire une détection en ne vérifiant que certains point de ta figure (par exemple les angles et un ou plusiuers points pour chaque coté ...)
Ces points sont à faire tourner en même temps que ton sprite, en utilisant la forme suivante: X=A.cos(angle)+B et Y=A.sin(angle)+B
Tu peux faire une détection en ne vérifiant que certains point de ta figure (par exemple les angles et un ou plusiuers points pour chaque coté ...)
Ces points sont à faire tourner en même temps que ton sprite, en utilisant la forme suivante: X=A.cos(angle)+B et Y=A.sin(angle)+B
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Version de PB : 6.00LTS - 64 bits
Re: RotateSprite et SpritePixelCollision
Bonjour,
Ca je sais faire, je l'ai même programmé en assembleur 6502 il y a moult années, mais c'est tout de même dommage que cette fonction ne soit pas native dans Purebasic.
Ca je sais faire, je l'ai même programmé en assembleur 6502 il y a moult années, mais c'est tout de même dommage que cette fonction ne soit pas native dans Purebasic.
Re: RotateSprite et SpritePixelCollision
Oui, c'est dommage effectivement. Pb, donne les outils, mais pas un moteur complet tout fait pour créer des jeux.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Version de PB : 6.00LTS - 64 bits
Re: RotateSprite et SpritePixelCollision
Pour info quelqu'un du forum français a fait un jeu 2D avec le moteur 3D et là les collisions sont parfaites.
M.
Code : Tout sélectionner
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Global Quit.b = #False
Structure Tile
CollideEntity.l
TileEntity.l
life.l
autotile.b
climb.b
EndStructure
Structure Destructible
ID.l
x.l:y.l
explode.b
explodeForce.f
scrapType.l
EndStructure
NewList Destructible.Destructible()
Structure pt
ent.l
mat.l
px.d
py.d
ox.d
oy.d
v.d
a.d
t.d
ttl.l
EndStructure
Global NewList Particle.pt()
Global Dim Pixels.i(1920,1080)
Global Dim ground.Tile(512,128)
CamX.d:CamY.d = 128:CamZ.d = 100
If InitEngine3D():InitSprite():InitKeyboard():InitJoystick()
If Screen3DRequester()
Declare.i CreateTile(Size.d)
Declare.d LinearInterpolate(y1.d,y2.d,mu.d)
Declare CreateParticle(x.f,y.f,angle.f,mat.i,vx.d,vy.d)
; Create tile
;
Add3DArchive("./",#PB_3DArchive_FileSystem)
SHEET = LoadTexture(#PB_Any,"sheet.png")
StartDrawing(TextureOutput(SHEET))
For y = 0 To 1080-1
For x = 0 To 1920-1
DrawingMode(#PB_2DDrawing_AlphaChannel)
Pixels(x,y) = Point(x,y)
Next
Next
StopDrawing()
index = 0
For ty = 0 To 8
For tx = 0 To 15
CreateTexture(index,32,32,"")
StartDrawing(TextureOutput(index))
DrawingMode(#PB_2DDrawing_AlphaChannel):Box(0,0,32,32,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For y = 0 To 31
For x = 0 To 31
Plot(x,31-y,Pixels(x+(tx*32),y+(ty*32)))
Next
Next
StopDrawing()
CreateMaterial(index,TextureID(index))
MaterialBlendingMode(index,#PB_Material_AlphaBlend)
MaterialFilteringMode(index, #PB_Material_None)
index+1
Next
Next
BG_TEX = CreateTexture(#PB_Any,240,270,"")
StartDrawing(TextureOutput(BG_TEX))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,240,270,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For y = 0 To 270-1
For x = 0 To 240-1
Plot(x,269-y,Pixels(x+960,y))
Next
Next
StopDrawing()
m = CreateMaterial(#PB_Any,TextureID(BG_TEX))
MaterialBlendingMode(m,#PB_Material_AlphaBlend)
MaterialFilteringMode(m, #PB_Material_None)
BG_TEX = CreateTexture(#PB_Any,240,270,"")
StartDrawing(TextureOutput(BG_TEX))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,240,270,RGBA(0,0,0,0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
For y = 0 To 270-1
For x = 0 To 240-1
Plot(x,269-y,Pixels(x+1200,y))
Next
Next
StopDrawing()
mb = CreateMaterial(#PB_Any,TextureID(BG_TEX))
MaterialBlendingMode(mb,#PB_Material_AlphaBlend)
MaterialFilteringMode(mb, #PB_Material_None)
For i = 0 To 20
PlaneMesh = CreatePlane(#PB_Any,240,270,1,1,1,1)
e = CreateEntity(#PB_Any,MeshID(PlaneMesh),MaterialID(mb),(-i*240)+Random(120),135-70+Random(140),-250)
RotateEntity(e,90,0,0)
e = CreateEntity(#PB_Any,MeshID(PlaneMesh),MaterialID(m),(-i*340)+Random(220),135-70+Random(140),-450)
RotateEntity(e,90,0,0)
Next
INVISIBLE_TEXTURE = CreateTexture(#PB_Any,64,64,"")
StartDrawing(TextureOutput(INVISIBLE_TEXTURE))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,64,64,RGBA(0,0,0,0))
; DrawingMode(#PB_2DDrawing_AlphaBlend)
; Box(0,0,64,64,RGBA(255,0,0,64))
StopDrawing()
INVISIBLE_MATERIAL = CreateMaterial(#PB_Any,TextureID(INVISIBLE_TEXTURE))
MaterialBlendingMode(INVISIBLE_MATERIAL,#PB_Material_AlphaBlend)
; create tile mesh
;
TILE_MESH = CreateTile(1)
CUBE_MESH = CreateCube(#PB_Any,1)
MCUBE_MESH = CreateCube(#PB_Any,0.5)
For y = 0 To 127
For x = 0 To 511
value.i = Pixels(x,(1080-127)+y)
If value = $FFFFFFFF
ground(x,y)\autotile = #True
ground(x,y)\life = -1
ground(x,y)\TileEntity = CreateEntity(#PB_Any,MeshID(TILE_MESH),MaterialID(0),x,128-y,0)
ground(x,y)\CollideEntity = CreateEntity(#PB_Any,MeshID(CUBE_MESH),MaterialID(INVISIBLE_MATERIAL),x,128-y,0)
CreateEntityBody(ground(x,y)\CollideEntity,#PB_Entity_BoxBody,0,0.1,0.5)
; CreateEntityBody(ground(x,y)\CollideEntity,#PB_Entity_BoxBody,0,0.1,0.5)
EndIf
If value = $FF002080
ground(x,y)\life = 8
ground(x,y)\TileEntity = CreateEntity(#PB_Any,MeshID(TILE_MESH),MaterialID(48))
ground(x,y)\CollideEntity = CreateEntity(#PB_Any,MeshID(CUBE_MESH),MaterialID(INVISIBLE_MATERIAL),x,128-y,0)
AttachEntityObject(ground(x,y)\CollideEntity,"",EntityID(ground(x,y)\TileEntity))
CreateEntityBody(ground(x,y)\CollideEntity,#PB_Entity_BoxBody,0.8,0,0.5)
; CreateEntityBody(ground(x,y)\CollideEntity,#PB_Entity_BoxBody,0.8,0,0.5)
EntityAngularFactor(ground(x,y)\CollideEntity,0,0,1)
EntityLinearFactor(ground(x,y)\CollideEntity,1,1,0)
AddElement(Destructible())
Destructible()\ID = ground(x,y)\CollideEntity
Destructible()\x = x:Destructible()\y = y
Destructible()\scrapType = 1 ; wood
EndIf
If value = $FF808080
ground(x,y)\climb = #True
ground(x,y)\TileEntity = CreateEntity(#PB_Any,MeshID(TILE_MESH),MaterialID(41+Random(6,0)),x,128-y,-0.1)
EndIf
Next
Next
;autotile
For y = 0 To 127
For x = 0 To 511
;level
If ground(x,y)\autotile
tile_value.l = 0
If y-1 =>0 : If ground(x,y-1)\autotile = 1 : tile_value + 1 : EndIf : EndIf
If y+1 <128 : If ground(x,y+1)\autotile = 1 : tile_value + 4 : EndIf : EndIf
If x-1 =>0 : If ground(x-1,y)\autotile = 1 : tile_value + 8 : EndIf : EndIf
If x+1 <512 : If ground(x+1,y)\autotile = 1 : tile_value + 2 : EndIf : EndIf
SetEntityMaterial(ground(x,y)\TileEntity,MaterialID(tile_value))
EndIf
Next
Next
TILE_MESH = CreateSphere(#PB_Any,0.49,32,32);CreateTile(0.8)
D = CreateEntity(#PB_Any,MeshID(TILE_MESH),MaterialID(INVISIBLE_MATERIAL),0,128,0)
CreateEntityBody(D,#PB_Entity_SphereBody,1,0.1,0.5)
; CreateEntityBody(D,#PB_Entity_SphereBody,1,0.1,0.5)
EntityAngularFactor(D,0,0,0)
EntityLinearFactor(D,1,1,0)
T = CreateTile(1)
TM = CreateEntity(#PB_Any,MeshID(T),MaterialID(32))
AttachEntityObject(D,"",EntityID(TM))
WorldGravity(-9.81)
Camera2D = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera2D,RGB(255,128,64))
CameraRange(Camera2D,0.01,1000)
CameraFOV(Camera2D,40)
AmbientColor(RGB(255,128,64))
; CreateLight(0,$CACACA,100,100,100)
deltaTime.f = 0
While #True
GameClock = ElapsedMilliseconds()
Screen3DEvents()
If Quit Or KeyboardPushed(#PB_Key_Escape)
Break
EndIf
If KeyboardPushed(#PB_Key_Right) And GetEntityAttribute(D,#PB_Entity_LinearVelocityX) < 4
ApplyEntityForce(D,10,0,0)
EndIf
If KeyboardPushed(#PB_Key_Left) And GetEntityAttribute(D,#PB_Entity_LinearVelocityX) > -4
ApplyEntityForce(D,-10,0,0)
EndIf
Tx = Int(EntityX(D)+0.5)
Ty = (128)-Int(EntityY(D))
If Tx<0 : Tx=0 : EndIf
If Ty<0 : Ty=0 : EndIf
If Tx>511 : Tx=511 : EndIf
If Ty>127 : Ty=127 : EndIf
If ground(Tx,Ty)\climb = 1 And kf = #False
If GetEntityAttribute(D,#PB_Entity_LinearVelocityY)<=1.8
EntityVelocity(D, GetEntityAttribute(D,#PB_Entity_LinearVelocityX)/1.1 , 0, 0)
EntityLinearFactor(D,1,0,0)
EndIf
ElseIf ground(Tx,Ty)\climb = 0
EntityLinearFactor(D,1,1,0)
ElseIf ground(Tx,Ty)\climb = 1 And kf = #True
If GetEntityAttribute(D,#PB_Entity_LinearVelocityY)<=1.8
EntityLinearFactor(D,1,1,0)
ApplyEntityImpulse(D,0,7.5,0)
kf = #False
EndIf
EndIf
If KeyboardPushed(#PB_Key_Up) And ground(Tx,Ty)\climb
MoveEntity(D,0,0.1*deltaTime,0)
EndIf
If KeyboardPushed(#PB_Key_Down) And ground(Tx,Ty)\climb
MoveEntity(D,0,-0.1*deltaTime,0)
EndIf
If KeyboardPushed(#PB_Key_Space) And kf = #False And Abs(GetEntityAttribute(D,#PB_Entity_LinearVelocityY)) < 0.005
kf = #True
ApplyEntityImpulse(D,0,7.5,0)
EndIf
If Not KeyboardPushed(#PB_Key_Space) And kf=#True
kf=#False
EndIf
SetEntityAttribute(D,#PB_Entity_LinearSleeping,0)
SetEntityAttribute(D,#PB_Entity_AngularSleeping,0)
ExamineWorldCollisions(1)
While NextWorldCollision()
ForEach Destructible()
If Destructible()\ID = FirstWorldCollisionEntity()
WorldCollisionAppliedImpulse()
ground( Destructible()\x,Destructible()\y)\life - GetY()
If ground( Destructible()\x,Destructible()\y)\life < 0
For i = 0 To 9
vx.d=GetEntityAttribute(Destructible()\ID,#PB_Entity_LinearVelocityX)
vy.d=GetEntityAttribute(Destructible()\ID,#PB_Entity_LinearVelocityY)
CreateParticle(EntityX(Destructible()\ID),EntityY(Destructible()\ID),90,49+Random(2),vx,vy)
Next
FreeEntity( ground( Destructible()\x,Destructible()\y)\CollideEntity)
FreeEntity( ground( Destructible()\x,Destructible()\y)\TileEntity)
DeleteElement(Destructible())
Break 2
EndIf
EndIf
Next
Wend
ForEach Particle()
If(Particle()\ttl<ElapsedMilliseconds())
FreeEntity(Particle()\ent)
DeleteElement(Particle(),1)
EndIf
Next
CamX = LinearInterpolate(CamX,EntityX(D),deltaTime/600)
CamY = LinearInterpolate(CamY,EntityY(D),deltaTime/200)
MoveCamera(Camera2D,CamX,CamY,10,#PB_Absolute)
CameraLookAt(Camera2D,EntityX(D),EntityY(D),0)
RenderWorld(deltaTime*2) ; Draw 3d stuff
; Draw hud
FlipBuffers()
deltaTime = (ElapsedMilliseconds() - GameClock)
Wend
EndIf
Else
MessageRequester("Error","Engine3D.dll error when loading.")
End
EndIf
Procedure.i CreateTile(Size.d)
TILE_MESH = CreateMesh(#PB_Any)
MeshVertexPosition(-(Size/2), -(Size/2), 0)
MeshVertexTextureCoordinate(0, 0)
MeshVertexPosition((Size/2), -(Size/2), 0)
MeshVertexTextureCoordinate(1, 0)
MeshVertexPosition((Size/2), (Size/2), 0)
MeshVertexTextureCoordinate(1, 1)
MeshVertexPosition(-(Size/2), (Size/2), 0)
MeshVertexTextureCoordinate(0, 1)
MeshFace(0,1,2)
MeshFace(3,0,2)
FinishMesh(#True)
NormalizeMesh(TILE_MESH)
UpdateMeshBoundingBox(TILE_MESH)
ProcedureReturn TILE_MESH
EndProcedure
Procedure.d LinearInterpolate(y1.d,y2.d,mu.d)
ProcedureReturn(y1*(1-mu)+y2*mu)
EndProcedure
Procedure CreateParticle(x.f,y.f,angle.f,mat.i,vx.d,vy.d)
AddElement(Particle())
Particle()\ox = (x-0.5)+((10-Random(10))/10)
Particle()\oy = (y-0.5)+((10-Random(10))/10)
Particle()\ttl = ElapsedMilliseconds()+3000
Particle()\ent = CreateEntity(#PB_Any,MeshID(CreateTile(1)),MaterialID(mat),Particle()\ox,Particle()\oy,0.5)
EntityAngularFactor(Particle()\ent,0,0,1)
EntityLinearFactor(Particle()\ent,1,1,0)
CreateEntityBody(Particle()\ent,#PB_Entity_BoxBody,4,1,0)
ApplyEntityImpulse(Particle()\ent,(((-10+Random(20))/10)*3)+vx,(((-10+Random(20))/10)*10)+vy,0)
SetEntityCollisionFilter(Particle()\ent, 1, $1001)
EndProcedure