Stones Gun

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Stones Gun

Post by applePi »

i have posted here http://www.purebasic.fr/english/viewtop ... 40#p429603 for the MP3D forum what appears as a stones thrower which have the appearance of water emanating from a nozzle, it appears that the behavior of the 3D engine pushing the cubes, but this is not the only reason it appears that the cubes influence each other so they come out in a stream. if you try to push one cube only it will be a poor push.
so i want to try this in PB 3D Ogre, the same as above , pushing only one cube gives the one cube a poor power. but when we make many cubes it affects each other sequentially so it is emanating strongly
note that near the end of the 1000 stones which are shared between the Gun and the enemy artilleries your system will may be be slow , depends on your pc
also note that since we want the Guns tilted 45 degree so we should also rotate the cubic stones 45 deg also. but still i can't get a one clean flow of the cubic stones.
also note that positioning of the cubic stones are critical to direct the stones . also the stone size dictate how much powerfull the stream is
Image

Code: Select all

Declare dropStone(stn.l)
Declare dropStone2(stn.l)
ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press Space / Z to throw stones", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-5, 0, 0, 0)

#stone = 5
Global Dim stone(1000)
Global stn, stn2

;-Texture
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
LoadTexture(0,"wood.jpg")

;-Material
CreateMaterial(1,TextureID(0))
SetMaterialColor(1, #PB_Material_AmbientColor, RGB(100,100,100))
CreateMaterial(2,TextureID(0))
SetMaterialColor(2, #PB_Material_AmbientColor, $FFFF00)
MaterialCullingMode(2, #PB_Material_NoCulling )


;- Entities
CreatePlane(1,30,30,20,20,1,1)
plane  = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
EntityPhysicBody(plane, #PB_Entity_StaticBody)   

CreateCube(2, 1)
CreateCylinder(3, 1, 4 , 0, 0, 0)

Gun = CreateEntity(#PB_Any,MeshID(2), MaterialID(2))
ScaleEntity(Gun,2,1,1)
MoveEntity(Gun,-7,4,0)
RotateEntity(Gun, 0, 0,-135)
EntityPhysicBody(Gun,#PB_Entity_StaticBody ,100)

enemy = CreateEntity(#PB_Any,MeshID(3), MaterialID(2))
;ScaleEntity(Gun,2,1,1)
MoveEntity(enemy,6,4,0)
RotateEntity(enemy, 0, 45,45)
EntityPhysicBody(enemy,#PB_Entity_StaticBody ,10)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0,-2,8,18)
CameraLookAt(0,-2,5,0)

;-Light
AmbientColor($666666)
CreateLight(0,RGB(160,160,255),200,400,200)
   
  CreateCube(#stone, 0.7)
  For i = 1 To 1000
  stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
    
    Next
;- Main loop
Repeat
  Event = WindowEvent()

    ExamineKeyboard()
   
    If KeyboardPushed(#PB_Key_Space)
    ;If KeyboardReleased(#PB_Key_Space)  
      stn+1
      If stn > 1000: stn=1: EndIf
      dropStone(stn)
    EndIf
    
    If KeyboardPushed(#PB_Key_Z)
    ;If KeyboardReleased(#PB_Key_Space)  
      stn+1
      If stn > 1000: stn=1: EndIf
      dropStone2(stn)
    EndIf 
 
  ; Render
  RenderWorld()
  FlipBuffers()

   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
   EndIf

Until Quit = #True Or Event = #PB_Event_CloseWindow

End

Procedure dropStone(stn.l)
  
  MoveEntity(stone(stn), -6.3,5,0)
  RotateEntity(stone(stn), 0, 0,-135)
    EntityPhysicBody(stone(stn),#PB_Entity_BoxBody,1)
    
  
  EndProcedure
  
  Procedure dropStone2(stn.l)
  
  MoveEntity(stone(stn), 6,4,0)
  RotateEntity(stone(stn), 0, 0,45)
  EntityPhysicBody(stone(stn),#PB_Entity_BoxBody,1)
    
  
EndProcedure
Edit:
this is using balls instead of the cubes for the stones, note that the green gun throw exact stream of balls (it is a scaled cube) while the blue gun throw semi chaotic balls (note that it is a hollow cylinder) . the power supplied to the balls by using the 3D engine reflex to the objects when they are in the same place and time which are prohibited. imagine this as a gas pressure.
Image
when you feel the game begins to die press F to free ball entities and recharge again. the blue hollow gun needs more design while the left green gun are good. a future version will be a portable artillery in which we can freely change the gun angle. don't forget that the official example FPSFirstPerson.pb in C:\PureBasic\Examples\3D\Demos have a great gun which utilize the power from ApplyEntityImpulse(Shoot, ...), my example utilize the power from illegal action in pressing a 6000 balls in the same place or almost so utilizing how the 3d engine behaves in this situation

Code: Select all

Declare dropStone(stoneNum.l)
Declare dropStone2(stoneNum.l)
ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press Space / Z to throw stones .... F ..to free stones entities and Recharge", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-5, 0, 0, 0)

#stone = 5
Global Dim stone(6000)
Global stoneNum

;-Texture
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
LoadTexture(0,"wood.jpg")
LoadTexture(1,"clouds.jpg")

;-Material
CreateMaterial(1,TextureID(0))
SetMaterialColor(1, #PB_Material_AmbientColor, RGB(100,100,100))
CreateMaterial(2,TextureID(0))
SetMaterialColor(2, #PB_Material_AmbientColor, $FFFF00)
MaterialCullingMode(2, #PB_Material_NoCulling )
CreateMaterial(3,TextureID(1))
SetMaterialColor(3, #PB_Material_AmbientColor, RGB(255,255,255))

;- Entities
CreatePlane(1,30,30,20,20,1,1)
plane  = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
EntityPhysicBody(plane, #PB_Entity_StaticBody)   

CreateCube(2, 1)
CreateCylinder(3, 0.7, 6 , 0, 0, 0)

GunRed = CreateEntity(#PB_Any,MeshID(2), MaterialID(2))
ScaleEntity(GunRed,2,1,1)
MoveEntity(GunRed,-7,4,0)
RotateEntity(GunRed, 0, 0,-135)
EntityPhysicBody(GunRed,#PB_Entity_StaticBody ,100)

GunBlue = CreateEntity(#PB_Any,MeshID(3), MaterialID(3))
;ScaleEntity(Gun,2,1,1)
MoveEntity(GunBlue,6,4,0)
RotateEntity(GunBlue, 0, 45,45)
EntityPhysicBody(GunBlue,#PB_Entity_StaticBody ,100)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0,-2,8,18)
CameraLookAt(0,-2,5,0)

;-Light
AmbientColor($666666)
CreateLight(0,RGB(160,160,255),200,400,200)
   
;CreateCube(#stone, 0.5)
CreateSphere(#stone, 0.4 )

  For i = 0 To 6000
    stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
    
    Next
;- Main loop
Repeat
  Event = WindowEvent()

    ExamineKeyboard()
   
    If KeyboardPushed(#PB_Key_Space)
    ;If KeyboardReleased(#PB_Key_Space)  
      stoneNum+1
      If stoneNum > 6000: stoneNum=0: EndIf
      dropStone(stoneNum)
    EndIf
    
    If KeyboardPushed(#PB_Key_Z)
    ;If KeyboardReleased(#PB_Key_Space)  
      stoneNum+1
      If stoneNum > 6000: stoneNum=0: EndIf
      dropStone2(stoneNum)
    EndIf 
    If KeyboardPushed(#PB_Key_F) ; free the stone entities and recreate them again
     For i=0 To 6000
       FreeEntity(stone(i))
       stoneNum=0 : temp = 0
     Next 
     For i = 0 To 6000
    stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
    
    Next
     EndIf
 
  ;Render
  RenderWorld()
  FlipBuffers()

   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    
    temp + 1
    If temp > 200 ; free every 201 stone entities thrown
      temp = 0
      For i=1 To temp
        FreeEntity(stone(stoneNum - i))
      Next
     EndIf 
     

Until Quit = #True Or Event = #PB_Event_CloseWindow

End

Procedure dropStone(stoneNum.l)
  
  MoveEntity(stone(stoneNum), -6.4,4.9,0)
  RotateEntity(stone(stoneNum), 0, 0,-135)
  EntityPhysicBody(stone(stoneNum),#PB_Entity_BoxBody,1)
    
  
  EndProcedure
  
  Procedure dropStone2(stoneNum.l)
  SetEntityMaterial(stone(stoneNum), MaterialID(2))

  MoveEntity(stone(stoneNum), 4.7,5.2,0)
  
  EntityPhysicBody(stone(stoneNum),#PB_Entity_BoxBody,1)
    
  
EndProcedure
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 756
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Stones Gun

Post by Samuel »

Hello ApplePi,

Nice example you got there. :D
If you'd like to increase the speed. You could try lowering how many segments and rings the spheres have.
I think the default is somewhere around 16.

One other thing. Instead of recreating the spheres when you press F. Couldn't you just move the spheres to the start location?
I ask because it seems like your doing some extra steps with freeing and then recreating.
If you had a different number of spheres each time you press F then I could see freeing them up being necessary.
In this case though I don't think you need to recreate them.

Anyways good job and I look forward to seeing the portable artillery version.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Stones Gun

Post by applePi »

Hi Samuel
thanks for the reply and suggestions
i have changed the segments and rings number to 32, 32 and it is hardly move from the gun, using 64,64 the engine died. but reducing it does not gives noticeable difference, may be 5,5 are better. the RotateEntity(stone(stoneNum), 0, 0,-135) are neccessary sometimes such as in 5,5 situation else we will get two streams. i find a funny shape when we use segments,rings = 2,2 it is like throwing a paper.

your suggestion to move the spheres to the start location, but it does not work if the ball have physics, the artillery will work only if the physics initiated once the ball inside the (fire generator) at the top of the gun, the microseconds between loops while we are pressing the fire key make it possible for several balls to arrange themselves as this picture (my theory)
Image
so the physics engine behaviour is to separate them in a big power in every direction, just remove the physics from the Gun and we will see balls exploded in every direction (comment line 41 EntityPhysicBody(GunRed,#PB_Entity_StaticBody ,100)) in the example posted above.
a proof about this balls explosion is the following example about pressing 100 spheres in one place then giving them physics in one loop the result gives us an explosion of the spheres
you should wait a few seconds depends on the pc power for the explosion to take place after pressing space key. if you tried more than 200 will took more and more time and may hange the pc.
Explosion example:

Code: Select all

Declare dropStone(stoneNum.l)

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press once key Space  to throw stones .... F ..to free stones entities and Recharge", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-5, 0, 0, 0)

#stone = 5
Global Dim stone(300)
Global stoneNum

;-Texture
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
LoadTexture(0,"wood.jpg")
LoadTexture(1,"clouds.jpg")

;-Material
CreateMaterial(1,TextureID(0))
SetMaterialColor(1, #PB_Material_AmbientColor, RGB(100,100,100))
CreateMaterial(2,TextureID(0))
SetMaterialColor(2, #PB_Material_AmbientColor, $FFFF00)
MaterialCullingMode(2, #PB_Material_NoCulling )
CreateMaterial(3,TextureID(1))
SetMaterialColor(3, #PB_Material_AmbientColor, RGB(255,255,255))

;- Entities
CreatePlane(1,30,30,20,20,1,1)
plane  = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
EntityPhysicBody(plane, #PB_Entity_StaticBody)   

CreateCube(2, 1)
CreateCylinder(3, 0.7, 6 , 0, 0, 0)

GunRed = CreateEntity(#PB_Any,MeshID(2), MaterialID(2))
ScaleEntity(GunRed,2,1,1)
MoveEntity(GunRed,-7,4,0)
RotateEntity(GunRed, 0, 0,-135)
EntityPhysicBody(GunRed,#PB_Entity_StaticBody ,100)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
;MoveCamera(0,-2,8,18)
MoveCamera(0,-2,8,50)
CameraLookAt(0,-2,5,0)

;-Light
AmbientColor($666666)
CreateLight(0,RGB(160,160,255),200,400,200)
   
;CreateCube(#stone, 0.5)
CreateSphere(#stone, 0.4)

For i = 0 To 100
    stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
    ;MoveEntity(stone(i), -6.4,4.9,0)
    MoveEntity(stone(i), -6.31,4.8,0)
    Next
;- Main loop
Repeat
  Event = WindowEvent()

    ExamineKeyboard()
     
        
    If KeyboardReleased(#PB_Key_Space) ; free the stone entities and recreate them again
      
       For i = 0 To 100
         stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
         MoveEntity(stone(i), -6.31,4.8,0)
         
        Next
        dropStone(100)
        
      EndIf 
      
      If KeyboardReleased(#PB_Key_F)
    
      For i=0 To 100
         FreeEntity(stone(i))
      Next 
    EndIf
 
  ;Render
  RenderWorld()
  FlipBuffers()

   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    

Until Quit = #True Or Event = #PB_Event_CloseWindow

End

Procedure dropStone(stoneNum.l)
  For i=0 To 100 ; numbers of the stones
    
  ;RotateEntity(stone(stoneNum), 0, 0,-135)
  EntityPhysicBody(stone(i),#PB_Entity_BoxBody,1)
  Next  
    
  EndProcedure
  
  
here is a long range artillery :lol: with all ball entities are on the opening of the gun and then every keyboard push gives one ball a physics property, a continous pressing the keyboard generate many balls with physics so they are exploded since they are in a tiny place they are directed in a one stream, the total number of spheres affect the power somehow.

Code: Select all

Declare dropStone(stoneNum.l)

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press Space . to throw stones .... F ..to free stones entities and Recharge", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-5, 0, 0, 0)

#stone = 5
Global Dim stone(3000)
Global stoneNum

;-Texture
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
LoadTexture(0,"wood.jpg")

;-Material
CreateMaterial(1,TextureID(0))
SetMaterialColor(1, #PB_Material_AmbientColor, RGB(100,100,100))
CreateMaterial(2,TextureID(0))
SetMaterialColor(2, #PB_Material_AmbientColor, $FFFF00)
MaterialCullingMode(2, #PB_Material_NoCulling )

;- Entities
CreatePlane(1,30,30,20,20,1,1)
plane  = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
EntityPhysicBody(plane, #PB_Entity_StaticBody)   

CreateCube(2, 1)
CreateCylinder(3, 0.7, 6 , 0, 0, 0)

GunRed = CreateEntity(#PB_Any,MeshID(2), MaterialID(2))
ScaleEntity(GunRed,2,1,1)
MoveEntity(GunRed,-7,4,0)
RotateEntity(GunRed, 0, 0,-135)
EntityPhysicBody(GunRed,#PB_Entity_StaticBody ,100)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
;MoveCamera(0,-2,8,18)
MoveCamera(0,-2,8,70)
CameraLookAt(0,-2,5,0)

;-Light
AmbientColor($666666)
CreateLight(0,RGB(160,160,255),200,400,200)
   
;CreateCube(#stone, 0.5)
CreateSphere(#stone, 0.4)

  For i = 0 To 3000
    stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
    ;MoveEntity(stone(i), -6.4,4.9,0)
    MoveEntity(stone(i), -6.31,4.8,0)
    Next
;- Main loop
Repeat
  Event = WindowEvent()

    ExamineKeyboard()
   
    If KeyboardPushed(#PB_Key_Space)
    ;If KeyboardReleased(#PB_Key_Space)  
      stoneNum+1
      If stoneNum > 3000: stoneNum=0: EndIf
      dropStone(stoneNum)
    EndIf
        
        
    If KeyboardReleased(#PB_Key_F) ; free the stone entities and recreate them again
       For i=0 To 3000
         FreeEntity(stone(i))
         stoneNum=0 : temp = 0
       Next 
       For i = 0 To 3000
         stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
         ;MoveEntity(stone(i), -6.4,4.9,0)
          MoveEntity(stone(i), -6.31,4.8,0)
         
       Next
     
     EndIf
 
  ;Render
  RenderWorld()
  FlipBuffers()

   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    ;If KeyboardPushed(#PB_Key_A)
      ;MessageRequester("", Str(IsEntity(Stone(100))))

    ;EndIf
    
     

Until Quit = #True Or Event = #PB_Event_CloseWindow

End

Procedure dropStone(stoneNum.l)
  
  RotateEntity(stone(stoneNum), 0, 0,-135)
  EntityPhysicBody(stone(stoneNum),#PB_Entity_BoxBody,1)
    
  
  EndProcedure
  
  
Edit: Explosion Example 2
Edit:
the balls explosion are so powerfull that if we put a cylinder with weigh 500 the balls will push it away, in explosions we don't need to be care about its position relative to the gun because it is exploded in left right directions and other directions (depends on many factors). i have succeeded in taking a picture at the moment of explosion from above, the picture support my theory

Image

scene from above: uncomment line 55 for MoveCamera(...)
Image

Code: Select all

Declare dropStone(stonesNumber.l)

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press once key Space  to throw stones .... F ..to free stones entities and Recharge", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-5, 0, 0, 0)

#stone = 5
Global stonesNumber = 150
Global Dim stone(stonesNumber)


;-Texture
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
LoadTexture(0,"wood.jpg")
LoadTexture(1,"clouds.jpg")

;-Material
CreateMaterial(1,TextureID(0))
SetMaterialColor(1, #PB_Material_AmbientColor, RGB(100,100,100))
CreateMaterial(2,TextureID(0))
SetMaterialColor(2, #PB_Material_AmbientColor, $FFFF00)
MaterialCullingMode(2, #PB_Material_NoCulling )
CreateMaterial(3,TextureID(1))
SetMaterialColor(3, #PB_Material_AmbientColor, RGB(255,255,255))
MaterialCullingMode(3, #PB_Material_NoCulling )

;- Entities
CreatePlane(1,30,30,20,20,1,1)
plane  = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
EntityPhysicBody(plane, #PB_Entity_StaticBody)   

CreateCube(2, 1)
CreateCylinder(3, 4, 10 , 0, 0, 0)

; just a very heavy weight 
Cylinder = CreateEntity(#PB_Any,MeshID(3), MaterialID(3))
RotateEntity(Cylinder, 0, -180,0)
MoveEntity(Cylinder,4,6,0)
EntityPhysicBody(Cylinder,#PB_Entity_CylinderBody  ,500)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
;MoveCamera(0,-2,8,18)
MoveCamera(0,-2,8,40)
;MoveCamera(0,0,20,0) ; to see the scene from above the cylinder
CameraLookAt(0,-2,0,0)

;-Light
AmbientColor($666666)
CreateLight(0,RGB(160,160,255),stonesNumber,400,stonesNumber)
   
;CreateCube(#stone, 0.5)
CreateSphere(#stone, 0.4)
  ;just to show the place of the explosion
  stonesPosition = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
  MoveEntity(stonesPosition, -4,4,0)
    
;- Main loop
Repeat
  Event = WindowEvent()

    ExamineKeyboard()
     
        
    If KeyboardReleased(#PB_Key_Space) 
      
       For i = 0 To stonesNumber ; prepare the stones and moving them to the place of explosion
         stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
         MoveEntity(stone(i), -4,4,0)        
        Next
        dropStone(stonesNumber) ; now to give them physics reality at once or almost
        
      EndIf 
      
      If KeyboardReleased(#PB_Key_F) ; free the stone entities
    
      For i=0 To stonesNumber
         FreeEntity(stone(i))
      Next 
    EndIf
 
  ;Render
  RenderWorld()
  FlipBuffers()

   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    

Until Quit = #True Or Event = #PB_Event_CloseWindow

End

Procedure dropStone(stonesNumber.l)
  For i=0 To stonesNumber ; numbers of the stones
  ;RotateEntity(stone(stonesNumber), 0, 0,-135)
  EntityPhysicBody(stone(i),#PB_Entity_BoxBody,1)
  Next  
    
  EndProcedure
Post Reply