hello
je suis en train de créer un jeu de shot 3D avec JMonkeyEngine et je me heurte à un probleme pour animer mon ennemi :/
j'ai créé une seconde class pour pour ennemi, en me basant sur l'aide precieuse de tutoriels
mais je sais pas comment l'utiliser dans mon Main.java :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | package mygame; import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; import com.jme3.animation.AnimEventListener; import com.jme3.animation.LoopMode; import com.jme3.audio.AudioNode; import com.jme3.collision.CollisionResult; import com.jme3.collision.CollisionResults; import com.jme3.font.BitmapText; import com.jme3.input.MouseInput; import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.material.Material; import com.jme3.math.Ray; import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Sphere; import com.jme3.app.SimpleApplication; import com.jme3.bullet.BulletAppState; import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; import com.jme3.bullet.collision.shapes.CollisionShape; import com.jme3.bullet.control.CharacterControl; import com.jme3.bullet.control.RigidBodyControl; import com.jme3.bullet.util.CollisionShapeFactory; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.KeyTrigger; import com.jme3.light.AmbientLight; import com.jme3.light.DirectionalLight; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import mygame.Personnage; public class Main extends SimpleApplication implements ActionListener { private Spatial sceneModel; private BulletAppState bulletAppState; private RigidBodyControl landscape; private CharacterControl player; private AmbientLight al; private DirectionalLight dl; private Vector3f walkDirection = new Vector3f(); private boolean left = false, right = false, up = false, down = false; private Node shootables; private Geometry mark; private AudioNode audio_gun; private AudioNode audio_nature; private int score = 0; private float base = -18; //Temporary vectors used on each frame. //They here to avoid instanciating new vectors on each frame private Vector3f camDir = new Vector3f(); private Vector3f camLeft = new Vector3f(); // animation private AnimChannel channel; private AnimControl control; Node ennemi; /** Defining the "Shoot" action: Determine what was hit and how to respond. */ private ActionListener actionListener = new ActionListener() { public void onAction(String name, boolean keyPressed, float tpf) { if (name.equals("Shoot") && !keyPressed) { // 1. Reset results list. CollisionResults results = new CollisionResults(); // 2. Aim the ray from cam loc to cam direction. Ray ray = new Ray(cam.getLocation(), cam.getDirection()); // 3. Collect intersections between Ray and Shootables in results list. shootables.collideWith(ray, results); // 4. Print the results System.out.println("----- Collisions? " + results.size() + "-----"); for (int i = 0; i < results.size(); i++) { // For each hit, we know distance, impact point, name of geometry. float dist = results.getCollision(i).getDistance(); Vector3f pt = results.getCollision(i).getContactPoint(); String hit = results.getCollision(i).getGeometry().getName(); System.out.println("* Collision #" + i); System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away."); } // 5. Use the results (we mark the hit object) if (results.size() > 0) { // The closest collision point is what was truly hit: CollisionResult closest = results.getClosestCollision(); // Let's interact - we mark the hit with a red dot. mark.setLocalTranslation(closest.getContactPoint()); rootNode.attachChild(mark); // we add one to the current player score score += 1; } else { // No hits? Then remove the red mark. rootNode.detachChild(mark); } audio_gun.playInstance(); // play each instance once! } } }; public static void main(String[] args) { Main app = new Main(); app.start(); } public void simpleInitApp() { /** Set up Physics */ bulletAppState = new BulletAppState(); stateManager.attach(bulletAppState); //bulletAppState.getPhysicsSpace().enableDebug(assetManager); // We re-use the flyby camera for rotation, while positioning is handled by physics viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); flyCam.setMoveSpeed(100); setUpKeys(); setUpLight(); setDisplayStatView(true); initCrossHairs(); // a "+" in the middle of the screen to help aiming initKeys(); // load custom key mappings initMark(); // a red sphere to mark the hit initAudio(); // the sound we are going to play during an event printPoints(score); // init the display of the player points /** create four colored boxes and a floor to shoot at: */ shootables = new Node("Shootables"); rootNode.attachChild(shootables); shootables.attachChild(makeCube("a Dragon", -4f, base, 1f)); // We load the scene from the zip file and adjust its size. // assetManager.registerLocator("town.zip", ZipLocator.class); sceneModel = assetManager.loadModel("Models/town/main.j3o"); sceneModel.setLocalScale(1.5f); // We set up collision detection for the scene by creating a // compound collision shape and a static RigidBodyControl with mass zero. CollisionShape sceneShape = CollisionShapeFactory.createMeshShape((Node) sceneModel); landscape = new RigidBodyControl(sceneShape, 0); sceneModel.addControl(landscape); // We set up collision detection for the player by creating // a capsule collision shape and a CharacterControl. // The CharacterControl offers extra settings for // size, stepheight, jumping, falling, and gravity. // We also put the player in its starting position. CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); player = new CharacterControl(capsuleShape, 0.05f); player.setJumpSpeed(15); player.setFallSpeed(55); player.setGravity(30); player.setPhysicsLocation(new Vector3f(0, 0, 0)); // We attach the scene and the player to the rootnode and the physics space, // to make them appear in the game world. rootNode.attachChild(sceneModel); bulletAppState.getPhysicsSpace().add(landscape); bulletAppState.getPhysicsSpace().add(player); } /** A floor to show that the "shot" can go through several objects. */ protected Geometry makeFloor() { Box box = new Box(15, base, 15); Geometry floor = new Geometry("the Floor", box); floor.setLocalTranslation(0, 15, 0); Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); // mat1.setColor("Color", ColorRGBA.Gray); floor.setMaterial(mat1); return floor; } /** We create two audio nodes. */ private void initAudio() { /* gun shot sound is to be triggered by a mouse click. */ audio_gun = new AudioNode(assetManager, "Sounds/Effects/gunshot.wav", false); audio_gun.setPositional(false); audio_gun.setLooping(false); audio_gun.setVolume(2); rootNode.attachChild(audio_gun); /* nature sound - keeps playing in a loop. */ audio_nature = new AudioNode(assetManager, "Sounds/Environment/wind.wav", true); audio_nature.setLooping(true); // activate continuous playing audio_nature.setPositional(true); audio_nature.setVolume(3); rootNode.attachChild(audio_nature); audio_nature.play(); // play continuously! } /** A red ball that marks the last spot that was "hit" by the "shot". */ protected void initMark() { Sphere sphere = new Sphere(30, 30, 0.2f); mark = new Geometry("BOOM!", sphere); Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); mark_mat.setColor("Color", ColorRGBA.Red); mark.setMaterial(mark_mat); } /** A centred plus sign to help the player aim. */ protected void initCrossHairs() { guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); BitmapText ch = new BitmapText(guiFont, false); ch.setSize(guiFont.getCharSet().getRenderedSize() * 2); ch.setText("+"); // crosshairs ch.setLocalTranslation( // center settings.getWidth() / 2 - ch.getLineWidth() / 2, settings.getHeight() / 2 + ch.getLineHeight() / 2, 0); guiNode.attachChild(ch); } /** Declaring the "Shoot" action and mapping to its triggers. */ private void initKeys() { inputManager.addMapping("Shoot", new KeyTrigger(KeyInput.KEY_SPACE), // trigger 1: spacebar new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); // trigger 2: left-button click inputManager.addListener(actionListener, "Shoot"); } /** The current player score */ protected void printPoints(int score) { guiNode.detachAllChildren(); guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); BitmapText txt_points = new BitmapText(guiFont, false); txt_points.setSize(guiFont.getCharSet().getRenderedSize() * 2); txt_points.setText("Score : " + score); txt_points.setLocalTranslation( settings.getWidth() / 2 - txt_points.getLineWidth() / 2, txt_points.getLineHeight(), 0); guiNode.attachChild(txt_points); } /** A cube object for target practice */ protected Spatial makeCube(String name, float x, float y, float z) { // Charge un modèle de test_data (ogrexml + matériel + texture) Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml"); ninja.scale(0.05f, 0.05f, 0.05f); ninja.rotate(0.0f, -3.0f, 0.0f); ninja.setLocalTranslation(x, y, z); return ninja; } private void setUpLight() { // We add light so we see the scene al = new AmbientLight(); al.setColor(ColorRGBA.White.mult(0.66f)); rootNode.addLight(al); dl = new DirectionalLight(); dl.setColor(ColorRGBA.White); dl.setDirection(new Vector3f(0f, 0f, 0f).normalizeLocal()); rootNode.addLight(dl); } /** We over-write some navigational key mappings here, so we can * add physics-controlled walking and jumping: */ private void setUpKeys() { inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_Q)); inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D)); inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_Z)); inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S)); inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE)); inputManager.addListener(this, "Left"); inputManager.addListener(this, "Right"); inputManager.addListener(this, "Up"); inputManager.addListener(this, "Down"); inputManager.addListener(this, "Jump"); } /** These are our custom actions triggered by key presses. * We do not walk yet, we just keep track of the direction the user pressed. */ public void onAction(String binding, boolean isPressed, float tpf) { if (binding.equals("Left")) { left = isPressed; } else if (binding.equals("Right")) { right = isPressed; } else if (binding.equals("Up")) { up = isPressed; } else if (binding.equals("Down")) { down = isPressed; } else if (binding.equals("Jump")) { if (isPressed) { player.jump(); } } } /** * This is the main event loop--walking happens here. * We check in which direction the player is walking by interpreting * the camera direction forward (camDir) and to the side (camLeft). * The setWalkDirection() command is what lets a physics-controlled player walk. * We also make sure here that the camera moves with player. */ @Override public void simpleUpdate(float tpf) { camDir.set(cam.getDirection()).multLocal(0.6f); camLeft.set(cam.getLeft()).multLocal(0.4f); walkDirection.set(0, 0, 0); if (left) { walkDirection.addLocal(camLeft); } if (right) { walkDirection.addLocal(camLeft.negate()); } if (up) { walkDirection.addLocal(camDir); } if (down) { walkDirection.addLocal(camDir.negate()); } player.setWalkDirection(walkDirection); cam.setLocation(player.getPhysicsLocation()); dl.setDirection(cam.getDirection()); printPoints(score); initCrossHairs(); } } |
(je devrait l'utiliser dans Make Cube)
et voici Personnage.java :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | package mygame; import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; import com.jme3.animation.AnimEventListener; import com.jme3.animation.LoopMode; import com.jme3.app.SimpleApplication; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.KeyTrigger; import com.jme3.light.DirectionalLight; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.scene.Node; /** Sample 7 - how to load an OgreXML model and play an animation, * using channels, a controller, and an AnimEventListener. */ public class Personnage extends SimpleApplication implements AnimEventListener { private AnimChannel channel; private AnimControl control; Node player; private ActionListener actionListener = new ActionListener() { public void onAction(String name, boolean keyPressed, float tpf) { if (name.equals("Walk") && !keyPressed) { if (!channel.getAnimationName().equals("Walk")){ channel.setAnim("Walk", 0.50f); channel.setLoopMode(LoopMode.Cycle); } } } }; public static void main(String[] args) { Personnage app = new Personnage(); app.start(); } @Override public void simpleInitApp() { viewPort.setBackgroundColor(ColorRGBA.LightGray); initKeys(); DirectionalLight dl = new DirectionalLight(); dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal()); rootNode.addLight(dl); player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); player.setLocalScale(0.5f); rootNode.attachChild(player); control = player.getControl(AnimControl.class); control.addListener(this); channel = control.createChannel(); channel.setAnim("stand"); } public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { if (animName.equals("Walk")) { channel.setAnim("stand", 0.50f); channel.setLoopMode(LoopMode.DontLoop); channel.setSpeed(1f); } } public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { // unused } /** Custom Keybinding: Map named actions to inputs. */ private void initKeys() { inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE)); inputManager.addListener(actionListener, "Walk"); } } |
de plus, j'aimerai faire un cycle jour nuit dans la methode SimpleUpdate de Main.java, mais je vois pas trop comment faire varier 'al', car je ne dispose que de constantes (ColorRGBA.White par exemple)
Merci à vous !
+0
-2