1 /* 2 * Copyright (c) 2009-2010 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 33 package jme3test.bullet; 34 35 import com.jme3.app.SimpleApplication; 36 import com.jme3.asset.plugins.HttpZipLocator; 37 import com.jme3.asset.plugins.ZipLocator; 38 import com.jme3.bullet.BulletAppState; 39 import com.jme3.bullet.PhysicsSpace; 40 import com.jme3.bullet.collision.shapes.SphereCollisionShape; 41 import com.jme3.bullet.control.RigidBodyControl; 42 import com.jme3.bullet.objects.PhysicsCharacter; 43 import com.jme3.input.KeyInput; 44 import com.jme3.input.controls.ActionListener; 45 import com.jme3.input.controls.KeyTrigger; 46 import com.jme3.light.AmbientLight; 47 import com.jme3.light.DirectionalLight; 48 import com.jme3.material.MaterialList; 49 import com.jme3.math.ColorRGBA; 50 import com.jme3.math.Vector3f; 51 import com.jme3.scene.Node; 52 import com.jme3.scene.plugins.ogre.OgreMeshKey; 53 import java.io.File; 54 55 public class TestQ3 extends SimpleApplication implements ActionListener { 56 57 private BulletAppState bulletAppState; 58 private Node gameLevel; 59 private PhysicsCharacter player; 60 private Vector3f walkDirection = new Vector3f(); 61 private static boolean useHttp = false; 62 private boolean left=false,right=false,up=false,down=false; 63 64 public static void main(String[] args) { 65 File file = new File("quake3level.zip"); 66 if (!file.exists()) { 67 useHttp = true; 68 } 69 TestQ3 app = new TestQ3(); 70 app.start(); 71 } 72 73 public void simpleInitApp() { 74 bulletAppState = new BulletAppState(); 75 stateManager.attach(bulletAppState); 76 flyCam.setMoveSpeed(100); 77 setupKeys(); 78 79 this.cam.setFrustumFar(2000); 80 81 DirectionalLight dl = new DirectionalLight(); 82 dl.setColor(ColorRGBA.White.clone().multLocal(2)); 83 dl.setDirection(new Vector3f(-1, -1, -1).normalize()); 84 rootNode.addLight(dl); 85 86 AmbientLight am = new AmbientLight(); 87 am.setColor(ColorRGBA.White.mult(2)); 88 rootNode.addLight(am); 89 90 // load the level from zip or http zip 91 if (useHttp) { 92 assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/quake3level.zip", HttpZipLocator.class.getName()); 93 } else { 94 assetManager.registerLocator("quake3level.zip", ZipLocator.class.getName()); 95 } 96 97 // create the geometry and attach it 98 MaterialList matList = (MaterialList) assetManager.loadAsset("Scene.material"); 99 OgreMeshKey key = new OgreMeshKey("main.meshxml", matList); 100 gameLevel = (Node) assetManager.loadAsset(key); 101 gameLevel.setLocalScale(0.1f); 102 103 // add a physics control, it will generate a MeshCollisionShape based on the gameLevel 104 gameLevel.addControl(new RigidBodyControl(0)); 105 106 player = new PhysicsCharacter(new SphereCollisionShape(5), .01f); 107 player.setJumpSpeed(20); 108 player.setFallSpeed(30); 109 player.setGravity(30); 110 111 player.setPhysicsLocation(new Vector3f(60, 10, -60)); 112 113 rootNode.attachChild(gameLevel); 114 115 getPhysicsSpace().addAll(gameLevel); 116 getPhysicsSpace().add(player); 117 } 118 119 private PhysicsSpace getPhysicsSpace(){ 120 return bulletAppState.getPhysicsSpace(); 121 } 122 123 @Override 124 public void simpleUpdate(float tpf) { 125 Vector3f camDir = cam.getDirection().clone().multLocal(0.6f); 126 Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f); 127 walkDirection.set(0,0,0); 128 if(left) 129 walkDirection.addLocal(camLeft); 130 if(right) 131 walkDirection.addLocal(camLeft.negate()); 132 if(up) 133 walkDirection.addLocal(camDir); 134 if(down) 135 walkDirection.addLocal(camDir.negate()); 136 player.setWalkDirection(walkDirection); 137 cam.setLocation(player.getPhysicsLocation()); 138 } 139 140 private void setupKeys() { 141 inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); 142 inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); 143 inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); 144 inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); 145 inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); 146 inputManager.addListener(this,"Lefts"); 147 inputManager.addListener(this,"Rights"); 148 inputManager.addListener(this,"Ups"); 149 inputManager.addListener(this,"Downs"); 150 inputManager.addListener(this,"Space"); 151 } 152 153 public void onAction(String binding, boolean value, float tpf) { 154 155 if (binding.equals("Lefts")) { 156 if(value) 157 left=true; 158 else 159 left=false; 160 } else if (binding.equals("Rights")) { 161 if(value) 162 right=true; 163 else 164 right=false; 165 } else if (binding.equals("Ups")) { 166 if(value) 167 up=true; 168 else 169 up=false; 170 } else if (binding.equals("Downs")) { 171 if(value) 172 down=true; 173 else 174 down=false; 175 } else if (binding.equals("Space")) { 176 player.jump(); 177 } 178 } 179 } 180