HelloPhysics.java 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * Copyright (c) 2009-2021 jMonkeyEngine
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. package jme3test.helloworld;
  33. import com.jme3.app.SimpleApplication;
  34. import com.jme3.asset.TextureKey;
  35. import com.jme3.bullet.BulletAppState;
  36. import com.jme3.bullet.control.RigidBodyControl;
  37. import com.jme3.font.BitmapText;
  38. import com.jme3.input.MouseInput;
  39. import com.jme3.input.controls.ActionListener;
  40. import com.jme3.input.controls.MouseButtonTrigger;
  41. import com.jme3.material.Material;
  42. import com.jme3.math.Vector2f;
  43. import com.jme3.math.Vector3f;
  44. import com.jme3.scene.Geometry;
  45. import com.jme3.scene.shape.Box;
  46. import com.jme3.scene.shape.Sphere;
  47. import com.jme3.scene.shape.Sphere.TextureMode;
  48. import com.jme3.texture.Texture;
  49. import com.jme3.texture.Texture.WrapMode;
  50. /**
  51. * Example 12 - how to give objects physical properties so they bounce and fall.
  52. * @author base code by double1984, updated by zathras
  53. */
  54. public class HelloPhysics extends SimpleApplication {
  55. public static void main(String args[]) {
  56. HelloPhysics app = new HelloPhysics();
  57. app.start();
  58. }
  59. /** Prepare the Physics Application State (jBullet) */
  60. private BulletAppState bulletAppState;
  61. /** Prepare Materials */
  62. private Material wall_mat;
  63. private Material stone_mat;
  64. private Material floor_mat;
  65. /** Prepare geometries for bricks and cannon balls. */
  66. private static final Box box;
  67. private static final Sphere sphere;
  68. private static final Box floor;
  69. /** dimensions used for bricks and wall */
  70. private static final float brickLength = 0.48f;
  71. private static final float brickWidth = 0.24f;
  72. private static final float brickHeight = 0.12f;
  73. static {
  74. /* Initialize the cannonball geometry */
  75. sphere = new Sphere(32, 32, 0.4f, true, false);
  76. sphere.setTextureMode(TextureMode.Projected);
  77. /* Initialize the brick geometry */
  78. box = new Box(brickLength, brickHeight, brickWidth);
  79. box.scaleTextureCoordinates(new Vector2f(1f, .5f));
  80. /* Initialize the floor geometry */
  81. floor = new Box(10f, 0.1f, 5f);
  82. floor.scaleTextureCoordinates(new Vector2f(3, 6));
  83. }
  84. @Override
  85. public void simpleInitApp() {
  86. /* Set up Physics Game */
  87. bulletAppState = new BulletAppState();
  88. stateManager.attach(bulletAppState);
  89. /* Configure cam to look at scene */
  90. cam.setLocation(new Vector3f(0, 4f, 6f));
  91. cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y);
  92. /* Initialize the scene, materials, inputs, and physics space */
  93. initInputs();
  94. initMaterials();
  95. initWall();
  96. initFloor();
  97. initCrossHairs();
  98. }
  99. /** Add InputManager action: Left click triggers shooting. */
  100. private void initInputs() {
  101. inputManager.addMapping("shoot",
  102. new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  103. inputManager.addListener(actionListener, "shoot");
  104. }
  105. /**
  106. * Every time the shoot action is triggered, a new cannon ball is produced.
  107. * The ball is set up to fly from the camera position in the camera direction.
  108. */
  109. final private ActionListener actionListener = new ActionListener() {
  110. @Override
  111. public void onAction(String name, boolean keyPressed, float tpf) {
  112. if (name.equals("shoot") && !keyPressed) {
  113. makeCannonBall();
  114. }
  115. }
  116. };
  117. /** Initialize the materials used in this scene. */
  118. public void initMaterials() {
  119. wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  120. TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
  121. key.setGenerateMips(true);
  122. Texture tex = assetManager.loadTexture(key);
  123. wall_mat.setTexture("ColorMap", tex);
  124. stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  125. TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
  126. key2.setGenerateMips(true);
  127. Texture tex2 = assetManager.loadTexture(key2);
  128. stone_mat.setTexture("ColorMap", tex2);
  129. floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  130. TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
  131. key3.setGenerateMips(true);
  132. Texture tex3 = assetManager.loadTexture(key3);
  133. tex3.setWrap(WrapMode.Repeat);
  134. floor_mat.setTexture("ColorMap", tex3);
  135. }
  136. /** Make a solid floor and add it to the scene. */
  137. public void initFloor() {
  138. Geometry floor_geo = new Geometry("Floor", floor);
  139. floor_geo.setMaterial(floor_mat);
  140. floor_geo.setLocalTranslation(0, -0.1f, 0);
  141. this.rootNode.attachChild(floor_geo);
  142. /* Make the floor physical with mass 0.0f! */
  143. RigidBodyControl floor_phy = new RigidBodyControl(0.0f);
  144. floor_geo.addControl(floor_phy);
  145. bulletAppState.getPhysicsSpace().add(floor_phy);
  146. }
  147. /** This loop builds a wall out of individual bricks. */
  148. public void initWall() {
  149. float startpt = brickLength / 4;
  150. float height = 0;
  151. for (int j = 0; j < 15; j++) {
  152. for (int i = 0; i < 6; i++) {
  153. Vector3f vt =
  154. new Vector3f(i * brickLength * 2 + startpt, brickHeight + height, 0);
  155. makeBrick(vt);
  156. }
  157. startpt = -startpt;
  158. height += 2 * brickHeight;
  159. }
  160. }
  161. /** This method creates one individual physical brick. */
  162. private void makeBrick(Vector3f loc) {
  163. /* Create a brick geometry and attach it to the scene graph. */
  164. Geometry brick_geo = new Geometry("brick", box);
  165. brick_geo.setMaterial(wall_mat);
  166. rootNode.attachChild(brick_geo);
  167. /* Position the brick geometry. */
  168. brick_geo.setLocalTranslation(loc);
  169. /* Make brick physical with a mass > 0. */
  170. RigidBodyControl brick_phy = new RigidBodyControl(2f);
  171. /* Add physical brick to physics space. */
  172. brick_geo.addControl(brick_phy);
  173. bulletAppState.getPhysicsSpace().add(brick_phy);
  174. }
  175. /** This method creates one individual physical cannon ball.
  176. * By default, the ball is accelerated and flies
  177. * from the camera position in the camera direction.*/
  178. public void makeCannonBall() {
  179. /* Create a cannonball geometry and attach to scene graph. */
  180. Geometry ball_geo = new Geometry("cannon ball", sphere);
  181. ball_geo.setMaterial(stone_mat);
  182. rootNode.attachChild(ball_geo);
  183. /* Position the cannonball. */
  184. ball_geo.setLocalTranslation(cam.getLocation());
  185. /* Make the ball physical with a mass > 0.0f */
  186. RigidBodyControl ball_phy = new RigidBodyControl(1f);
  187. /* Add physical ball to physics space. */
  188. ball_geo.addControl(ball_phy);
  189. bulletAppState.getPhysicsSpace().add(ball_phy);
  190. /* Accelerate the physical ball to shoot it. */
  191. ball_phy.setLinearVelocity(cam.getDirection().mult(25));
  192. }
  193. /** A plus sign used as crosshairs to help the player with aiming.*/
  194. protected void initCrossHairs() {
  195. setDisplayStatView(false);
  196. //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  197. BitmapText ch = new BitmapText(guiFont, false);
  198. ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
  199. ch.setText("+"); // fake crosshairs :)
  200. ch.setLocalTranslation( // center
  201. settings.getWidth() / 2,
  202. settings.getHeight() / 2, 0);
  203. guiNode.attachChild(ch);
  204. }
  205. }