balls_collision.bmx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ' balls_collision.bmx
  2. ' from minib3d examples
  3. Strict
  4. Framework b3d.b3dglgraphics
  5. Import brl.random
  6. Local width%=800,height%=600,depth%=0,Mode%=2,hertz%=60
  7. Graphics3D width,height,depth,Mode,hertz
  8. ' bullet type
  9. Type TBullet
  10. Global list:TList=CreateList()
  11. Global no% ' no of bullets
  12. Field ent:TMesh
  13. Field x#,y#,z#
  14. Field vx#,vy#,vz#
  15. Field life% ' life counter
  16. ' create bullet
  17. Function Shoot(x#,y#,z#,nx#,ny#,nz#)
  18. Local bull:TBullet=New TBullet
  19. no=no+1
  20. bull.ent=CreateSphere()
  21. EntityColor bull.ent,64+Rand(191),64+Rand(191),64+Rand(191)
  22. bull.x#=x#
  23. bull.y#=y#
  24. bull.z#=z#
  25. bull.vx#=nx#
  26. bull.vy#=ny#
  27. bull.vz#=nz#
  28. PositionEntity bull.ent,x#,y#,z#,True
  29. EntityType bull.ent,1
  30. EntityRadius bull.ent,1
  31. ResetEntity bull.ent
  32. ListAddLast(list,bull)
  33. End Function
  34. ' update bullet
  35. Method Update()
  36. ' life counter is over 600, so bullet hasn't collided with anything for a long time - free it
  37. If life>600
  38. ListRemove list,Self
  39. FreeEntity ent
  40. no=no-1
  41. Return
  42. EndIf
  43. life=life+1 ' increase bullet life counter
  44. x#=EntityX(ent)
  45. y#=EntityY(ent)
  46. z#=EntityZ(ent)
  47. ' check to see if the entity collided with the level
  48. Local entity_hit% = CountCollisions(ent)
  49. ' if the entity collided with the level, make it bounce
  50. If entity_hit
  51. ' bullet has collided with level - reset life counter
  52. life=0
  53. ' get the normal of the surface which the entity collided with
  54. Local nx# = CollisionNX#(ent,1)
  55. Local ny# = CollisionNY#(ent,1)
  56. Local nz# = CollisionNZ#(ent,1)
  57. ' compute the dot product of the entity's motion vector and the normal of the surface collided with
  58. Local vdotn# = vx#*nx# + vy#*ny# + vz#*nz#
  59. ' calculate the normal force
  60. Local nfx# = -2.0 * nx# * vdotn#
  61. Local nfy# = -2.0 * ny# * vdotn#
  62. Local nfz# = -2.0 * nz# * vdotn#
  63. ' add the normal force to the direction vector.
  64. vx# = vx# + nfx#
  65. vy# = vy# + nfy#
  66. vz# = vz# + nfz#
  67. EndIf
  68. ' apply gravity
  69. Local GRAVITY#=0.01
  70. vy#=vy#-GRAVITY#
  71. ' update position values
  72. x#=x#+vx#
  73. y#=y#+vy#
  74. z#=z#+vz#
  75. PositionEntity ent,x#,y#,z#
  76. End Method
  77. End Type
  78. Local cam:TCamera=CreateCamera()
  79. PositionEntity cam,0,10,-10
  80. CameraRange cam,.5,500
  81. Local light:TLight=CreateLight(1)
  82. RotateEntity light,90,0,0
  83. Local mesh:TMesh=LoadMesh("media/test.b3d")
  84. ScaleMesh mesh,10,10,10
  85. ' set collision radius and types
  86. EntityRadius cam,1,1
  87. EntityType cam,1
  88. EntityType mesh,2
  89. ' enable collisions
  90. Collisions 1,2,2,2
  91. ' used by fps code
  92. Local old_ms%=MilliSecs()
  93. Local renders%, fps%
  94. While Not KeyDown(KEY_ESCAPE)
  95. ' control camera
  96. MoveEntity cam,KeyDown(KEY_D)-KeyDown(KEY_A),0,KeyDown(KEY_W)-KeyDown(KEY_S)
  97. TurnEntity cam,KeyDown(KEY_DOWN)*2-KeyDown(KEY_UP)*2,KeyDown(KEY_LEFT)*2-KeyDown(KEY_RIGHT)*2,0
  98. ' shoot bullet
  99. If KeyHit(KEY_SPACE)
  100. TFormNormal 0,0,0.05,cam,Null
  101. TBullet.Shoot(EntityX#(cam,True),EntityY#(cam,True),EntityZ#(cam,True),TFormedX(),TFormedY(),TFormedZ())
  102. EndIf
  103. ' update bullets
  104. For Local bull:TBullet=EachIn TBullet.list
  105. bull.Update()
  106. Next
  107. UpdateWorld
  108. RenderWorld
  109. renders=renders+1
  110. ' calculate fps
  111. If MilliSecs()-old_ms>=1000
  112. old_ms=MilliSecs()
  113. fps=renders
  114. renders=0
  115. EndIf
  116. Text 0,0,"FPS: "+fps
  117. Text 0,20,"Press space to shoot a bullet"
  118. Text 0,40,"No. of bullets: "+TBullet.no
  119. Flip
  120. Wend
  121. End