RotateSprite et SpritePixelCollision

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
jak64
Messages : 85
Inscription : dim. 03/mai/2020 23:16

RotateSprite et SpritePixelCollision

Message par jak64 »

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.
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: RotateSprite et SpritePixelCollision

Message par Mesa »

C'est dommage que ce vieux bug soit toujours là.

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)
M.
Dernière modification par Mesa le ven. 28/mai/2021 8:17, modifié 1 fois.
Avatar de l’utilisateur
jak64
Messages : 85
Inscription : dim. 03/mai/2020 23:16

Re: RotateSprite et SpritePixelCollision

Message par jak64 »

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é.
Avatar de l’utilisateur
jak64
Messages : 85
Inscription : dim. 03/mai/2020 23:16

Re: RotateSprite et SpritePixelCollision

Message par jak64 »

Ouah, mon petit dessin n'a pas marché, je viens d'en faire un vite fait sur Powerpoint pour expliquer :

Image

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.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: RotateSprite et SpritePixelCollision

Message par Fig »

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
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
Avatar de l’utilisateur
jak64
Messages : 85
Inscription : dim. 03/mai/2020 23:16

Re: RotateSprite et SpritePixelCollision

Message par jak64 »

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.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: RotateSprite et SpritePixelCollision

Message par Fig »

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
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: RotateSprite et SpritePixelCollision

Message par Mesa »

Pour info quelqu'un du forum français a fait un jeu 2D avec le moteur 3D et là les collisions sont parfaites.

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
M.
Répondre