Hello Collision - tutorial feedback

http://jmonkeyengine.com/wiki/doku.php/jme3:beginner:hello_collision



First solid draft of collision tutorial… Please test and send feedback… there is a second method that can be used, maybe I post the other version too…

Looking good, maybe you should put more attention the fact that a CompoundCollisionShape with MeshCollisionShapes as children is created and that MeshCollisionsShapes are only for static objects. The CollisionShapeFactory should be understood rather than be a "black box" that throws out some collision shape :wink:

Cheers,

Normen

I did mention that it's a static, but I added more info now, what about this?


To use collision detection, you want to turn the gameScene spatial into a PhysicsNode. A PhysicsNode takes two arguments: the Spatial and its Collision Shape.

JME3 offers a CollisionShapeFactory that precalculates a mesh-accurate collision shape for a Spatial. We choose to generate a CompoundCollisionShape, which has MeshCollisionShapes as its children. This type of collision shape is optimized for immobile objects such as terrain, houses, or whole shooter levels. Now you can create the PhysicsNode out of the collision shape and the model.

Sounds good :slight_smile:

zathras said:

http://jmonkeyengine.com/wiki/doku.php/jme3:beginner:hello_collision

First solid draft of collision tutorial... Please test and send feedback... there is a second method that can be used, maybe I post the other version too...


can not find the zip file.

Ť≠¶ŚĎä: Failed to open zip file: town.zip
java.io.FileNotFoundException: town.zip (Á≥ĽÁĽüśČ嚳挹įśĆáŚģöÁöĄśĖᚼ∂„Äā)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:114)
        at com.jme3.asset.plugins.ZipLocator.setRootPath(ZipLocator.java:45)
        at com.jme3.asset.ImplHandler.tryLocate(ImplHandler.java:89)
        at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:155)
        at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:282)
        at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:292)
        at jme3test.helloworld.HelloCollision.simpleInitApp(HelloCollision.java:54)
        at com.jme3.app.SimpleBulletApplication.initialize(SimpleBulletApplication.java:261)
        at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:102)
        at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:147)
        at java.lang.Thread.run(Thread.java:619)
2010-8-16 12:48:18 com.jme3.app.Application handleError
šł•ťáć: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
        at com.jme3.asset.plugins.ZipLocator.locate(ZipLocator.java:53)
        at com.jme3.asset.ImplHandler.tryLocate(ImplHandler.java:91)
        at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:155)
        at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:282)
        at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:292)
        at jme3test.helloworld.HelloCollision.simpleInitApp(HelloCollision.java:54)
        at com.jme3.app.SimpleBulletApplication.initialize(SimpleBulletApplication.java:261)
        at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:102)
        at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:147)
        at java.lang.Thread.run(Thread.java:619)
Java Result: -1073741819

Did you get jme from the svn, or did you download the alpha? Have a look at this post: http://www.jmonkeyengine.com/forum/index.php?topic=12444.msg105028#msg105028

i have a problem, forgive me i am still a noob…

i copied and pasted the code from the tutorial into jMonkeyPlatform, then downloaded 'town.zip' and placed it into my project's root directory but when attempting to run file i get this error:



Aug 16, 2010 8:09:17 AM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.SecurityException: sealing violation: package org.lwjgl.openal is sealed

        at java.net.URLClassLoader.defineClass(URLClassLoader.java:234)

        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)

        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)

        at java.security.AccessController.doPrivileged(Native Method)

        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

        at com.jme3.audio.lwjgl.LwjglAudioRenderer.initialize(LwjglAudioRenderer.java:106)

        at com.jme3.app.Application.initAudio(Application.java:119)

        at com.jme3.app.Application.initialize(Application.java:329)

        at com.jme3.app.SimpleBulletApplication.initialize(SimpleBulletApplication.java:224)

        at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:102)

        at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:147)

        at java.lang.Thread.run(Thread.java:619)

BUILD SUCCESSFUL (total time: 3 seconds)





i see it is a handleError which probably means i put the zip file in the wrong place, but i also see an error regarding org.lwjgl.openal which i have never seen before.

could my recent updating of jMP be causing my troubles? i attempted to try some of the other tutorials which have worked for me in the past but they are giving me the same error now. i'm guessing my problem is not really with this sample code alone, but i am lost and could really use some guidance.

I just dropped the tutorial in and got it working after I nabbed that town.zip, so I haven't gotten too intimate with it yet. But, one thing I noticed right off the bat that I thought was odd, is that if you point the camera above the horizon and move forward, the player (you), seem to be hopping. I assume this is because the flycam is still operating, so you're basically thrusting yourself at an angle in the air. The opposite happens when looking down, your forward movement slows to a crawl the further you look down.



Not sure if this was intended. If it was, just ignore this ;p

tehflah said:

I just dropped the tutorial in and got it working after I nabbed that town.zip, so I haven't gotten too intimate with it yet. But, one thing I noticed right off the bat that I thought was odd, is that if you point the camera above the horizon and move forward, the player (you), seem to be hopping. I assume this is because the flycam is still operating, so you're basically thrusting yourself at an angle in the air. The opposite happens when looking down, your forward movement slows to a crawl the further you look down.

Not sure if this was intended. If it was, just ignore this ;p

Its the normal behaviour of the physics character. If you look at the code the walkdirection is a vector that is taken from the camera direction. If you wanted to avoid that you'd simply have to eliminate the y component and normalize the vector before applying it as walkdirection.

Playing with the tutorial even further and attempting to adapt the ideas to work in my game engine so far I've ran into a few funny snags. I'm attempting to apply this tutorial to a fixed camera, 3rd person game. Fixed camera being that the camera is always 45 degrees of the character. First time user of the built in physics because I need collision detection on the walls. I had the gravity collision working by hand, and was sorta waiting for a way to do collision by hand as well, since I'm not really interested in anything more than simple collisions with wall/level geometry. But meh, if this works, may as well not reinvent the wheel eh?


  1. For this setup, is a PhysicsNode be more suitable than using a PhysicsCharacterNode? Almost seems to me the character version is well suited for 1st person. Using it in 3rd person view is, different… :smiley: I haven't explored the possibilities of the PhysicsNode yet however.


  2. There's some, for a lack of a better term, "jitter" on the character now and again. Is this normal?


  3. I’m using some awfully high values for velocities now just to get the character moving. I’m using a setup similar to the old Flag Rush, with max velocities around 10. For this setup I had to ramp them up to 60 to get closer to the old speed, and I still think I need to add more. Probably going to need a metric crapton of weight added to get the drift right too… heh.



    For the simple cylinder character vs boxes for a level, the collisions seem to be spot on though. I’m just sad that I had to throw out all my old gravity code  :P



    EDIT/UPDATE: I played with number 2 a bit trying to figure that one out. If I change the simpleUpdate line for the camera to ‚Äėcam.setLocation(player.getLocalTranslation().addLocal(5, 2.5f, 5));‚Äô and add a wireframe material to the physics volume, I observed the jitter on the node even in the helloCollision tutorial. (Gotta turn the camera to face the volume of course to see it) The volume jitters erratically, causing ‚ÄúTEMPORAL ANOMALIES‚ÄĚ ¬©, along the same area that the jitter is currently occurring at. IE. The jitter doesn‚Äôt move the whole rendering of the volume, usually just a section of it. And the rendering behind/near it on other objects seems to be affected as well. At least in the tutorial level. - Anything attached to the PhysicsCharacterNode will also experience this jitter effect.



    I tried simply having the model for the player not attached to the node and match the location of the node instead, but the model ends up getting away from the node. Still fooling with this, but I‚Äôll probably drop it as it‚Äôs really unwieldy to work with in this manner. derp derp, I accidently had it still attached and was translating it twice. That explains that ¬†:P This actually works fairly decent now. The camera follows the model just fine, and the physics model has this ‚Äėrubber band‚Äô-ish effect inside the model, but that shouldn‚Äôt be a huge deal. Detaching the model from the Character Node actually fixes the below problem because the physics volume won‚Äôt be drawn normally. - I‚Äôll try to put together a working demo of this built on the helloCollision tutorial. Post in a bit.



    One other thing that I noticed that I’m curious about. I always have the camera pointing directly at the player. What I noticed with the PhysicsCharacterNode is that if I get enough velocity on the player object, the camera points to a point behind the player’s model, as if it’s pointing at where it WAS (stale data?). Is the camera updated before the physics simulation is calculated? If so, that makes sense. This issue is fairly easy to compensate for though in my/user’s code. I was planning on implementing the opposite effect where the camera leads the player anyway.  :P



    Thanks for all your work on the physics sim and tutorial guys!  8)

I wasn't sure if there was a max message length so I'm making this a reply as the code section is sorta beefy.



The camera lagging issue went away with this example too, so the camera update issue is probably on my end. Either way, this shows a way to implement a 3rd person type setup. It's messy code though, but it shows that it can be done. If the box is attached to the physics node, it will jitter with the physics volume.



To experience the jitter on the model. 3 lines need to be modified. They have been marked with comment blocks all containing the word "JITTER" (For easy location). The jitter still causes a noticable jitter on the rendering of the scene.


package com.flah.tutorials;

import com.jme3.app.SimpleBulletApplication;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.nodes.PhysicsCharacterNode;
import com.jme3.bullet.nodes.PhysicsNode;
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.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
 
/**
 * Example 9 - How to make walls and floors solid.
 * This version uses Physics and a custom Action Listener.
 * @author normen, with edits by Zathras
 */
public class HelloCollisionMod
  extends SimpleBulletApplication
  implements ActionListener {
 
  private Spatial gameScene;
  private LifeformMod player;
  private Geometry playerModel;
  private Vector3f walkDirection = new Vector3f();
  private boolean left = false, right = false, up = false, down = false;
 
  public static void main(String[] args) {
    HelloCollisionMod app = new HelloCollisionMod();
    app.start();
  }
 
  public void simpleInitApp() {
    renderer.setBackgroundColor(ColorRGBA.Cyan);
 
    flyCam.setEnabled(false);
    setupKeys();
 
    // We add a light so we see the scene
    DirectionalLight dl = new DirectionalLight();
    dl.setColor(ColorRGBA.White.clone().multLocal(2));
    dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalize());
    rootNode.addLight(dl);
 
    // We load the scene from the zip file and adjust its size.
    assetManager.registerLocator("town.zip", ZipLocator.class.getName());
    gameScene = assetManager.loadModel("main.scene");
    gameScene.setLocalScale(2f);
 
    // We set up collision detection for the scene by creating a
    // compound collision shape and a physics node.
    CompoundCollisionShape sceneShape = CollisionShapeFactory.createMeshCompoundShape((Node) gameScene);
    PhysicsNode levelNode = new PhysicsNode(gameScene, sceneShape, 0);
 
    Box box = new Box(Vector3f.ZERO, 1, .5f, 1);
    playerModel = new Geometry("PlayerBox", box);
    Material playerMat = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");
   playerMat.setColor("m_Color", ColorRGBA.Magenta);
   playerModel.setMaterial(playerMat);
   
   /** COMMENT THIS OUT TO SEE JITTER **/
   rootNode.attachChild(playerModel);
   /** COMMENT OUT ABOVE TO SEE JITTER **/
   
    // We set up collision detection for the player by creating
    // a capsule collision shape and a physics character node.
    // The physics character node offers extra settings for
    // size, stepheight, jumping, falling, and gravity.
    // We also put the player in its starting position.
    player = new LifeformMod(new Vector3f(box.xExtent, box.yExtent, box.zExtent),
          0.5f, "PlayerCharacter", playerModel, rootNode);
    player.setMovementProperties(100, 150, 100, 2.2f, 60, 40);
    Material wireMat = new Material(assetManager, "Common/MatDefs/Misc/WireColor.j3md");
   wireMat.setColor("m_Color", ColorRGBA.Red);
   player.attachDebugShape(wireMat);
    player.setJumpSpeed(20);
    player.setFallSpeed(30);
    player.setGravity(30);
    player.setMaxSlope(FastMath.PI/4);
    player.setLocalTranslation(new Vector3f(0, 10, 0));
    player.updateGeometricState();
 
    // We attach the scene and the player to the rootNode and the physics space,
    // to make them appear in the game world.
    rootNode.attachChild(levelNode);
    rootNode.attachChild(player);
    rootNode.updateGeometricState();
    getPhysicsSpace().add(levelNode);
    getPhysicsSpace().add(player);
  }
 
  /** We over-write some navigational key mappings here, so we can
   * add physics-controlled walking and jumping: */
  private void setupKeys() {
    inputManager.addMapping("Lefts",  new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("Ups",    new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("Downs",  new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("Jumps",  new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addListener(this, "Lefts");
    inputManager.addListener(this, "Rights");
    inputManager.addListener(this, "Ups");
    inputManager.addListener(this, "Downs");
    inputManager.addListener(this, "Jumps");
  }
 
  /** 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 value, float tpf) {
    if (binding.equals("Lefts")) {
      if (value) { left = true; }  else { left = false; }
    } else if (binding.equals("Rights")) {
      if (value) { right = true; } else { right = false; }
    } else if (binding.equals("Ups")) {
      if (value) { up = true; } else { up = false; }
    } else if (binding.equals("Downs")) {
      if (value) { down = true; }  else { down = false; }
    } else if (binding.equals("Jumps")) {
      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) {
    walkDirection.set(0, 0, 0);
    if(left)  {player.turn(tpf, 1);}
    if(right) {player.turn(tpf, -1);}
    if(up)    {player.forward(tpf);}
    if(down)  {player.backpedal(tpf);}
     player.update(tpf);
     System.out.println("LOC: " + player.getLocalTranslation());
     cam.setLocation(player.getLocalTranslation().addLocal(5, 5, 5));
     cam.lookAt(player.getWorldTranslation(), Vector3f.UNIT_Y);
  }
 
  public class LifeformMod extends PhysicsCharacterNode {

      /** Geometry **/
      private Geometry model;

      /** Movement Physics **/
      private float weight;
      private float velocity;
      private float acceleration;
      private float braking;
      private float turnRate;

      private float maxSpeed;
      private float minSpeed;
      private boolean isRunning = false;

      public LifeformMod(Vector3f collisionExtents, float step,
            String nodeName, Geometry model, Node floorRootNode) {
//         super(new BoxCollisionShape(collisionExtents), step);
//         super(new CapsuleCollisionShape(collisionExtents.x, .1f, 1), step);
//         super(new CylinderCollisionShape(collisionExtents, 1), step);
         super(new SphereCollisionShape(collisionExtents.x), step);
         setModel(model);
         this.setGravity(30);
         this.setFallSpeed(30);
         this.setJumpSpeed(20);
      }

      public void update(float tpf) {
         drift(tpf);
         Vector3f nextMove = new Vector3f();
         nextMove.set(model.getLocalRotation().getRotationColumn(2, null).mult(velocity * tpf));
         setWalkDirection(nextMove);
//         System.out.println("Next Move : " + nextMove);
         
         /** COMMENT THIS OUT IF YOU WANT TO SEE JITTER **/
         model.setLocalTranslation(this.getLocalTranslation());
         /** COMMENT ABOVE OUT IF YOU WANT TO SEE JITTER **/
         
         System.out.println("Velocity  : " + velocity);
//         System.out.println("Pos       : " + this.getLocalTranslation());
         System.out.println("


");
      }

      public void resetPlayer() {
         this.setLocalTranslation(Vector3f.ZERO);
      }

      public void setModel(Geometry model) {
         if(this.model != null) {
            this.detachChild(this.model);
         }
         this.model = model;
         /** UNCOMMENT THIS IF YOU WANT TO SEE JITTER **/
//         this.attachChild(this.model);
         /** UNCOMMENT ABOVE IF YOU WANT TO SEE JITTER **/
      }

      public Geometry getModel() {
         return model;
      }

      /**
       * Quick method to set all of the movement attributes of this character.
       * @param w Weight
       * @param v Velocity
       * @param a Acceleration Rate
       * @param b Braking Rate
       * @param tr Turning Rate
       * @param maxS Maximum Speed (Moving forwards)
       * @param minS Minimum Speed (Moving backwards)
       */
      public void setMovementProperties(float w, float a, float b, float tr, float maxS, float minS) {
         this.weight = w;
         this.acceleration = a;
         this.braking = b;
         this.turnRate = tr;
         this.maxSpeed = maxS;
         this.minSpeed = minS;
      }

      public void forward(float tpf) {
         if(onGround()) {
            velocity += tpf * acceleration;
            if(isRunning && velocity > maxSpeed * 2) {
               velocity = maxSpeed * 2;
            }
            else if(!isRunning && velocity > maxSpeed) {
               velocity = maxSpeed;
            }
         }
      }

      public void backpedal(float tpf) {
         if(onGround()) {
            velocity -= tpf * braking;
            if(velocity < -minSpeed) {
               velocity = -minSpeed;
            }
         }
      }

      public void turn(float tpf, int direction) {
         model.rotate(0, direction * turnRate * tpf, 0);
      }

      public void jump(float tpf) {
         jump();
      }

      private void drift(float tpf) {
         float driftWeight = weight;
         if(!onGround()) {
            driftWeight = weight * .05f;
         }
         else {
            driftWeight = weight;
         }
         if(velocity < -FastMath.FLT_EPSILON) {
            velocity += (driftWeight/5) * tpf;
            if(velocity > 0) {
               velocity = 0;
            }
         }
         else if(velocity > FastMath.FLT_EPSILON) {
            velocity -= (driftWeight/5) * tpf;
            if(velocity < 0) {
               velocity = 0;
            }
         }
      }
   }
}

Hey there,



tutorial was fine for me. Except that it crashed earlier (NullPointerException). That has since been fixed after I updated my working copy. However, it is still detecting hits twice on some elements.



For example,


Collisions? 2
* Collision #0
  You shot the Sherrif at (-0.64527005, 1.5598298, -1.0), 11.128766 wu away.
* Collision #1
  You shot the Sherrif at (-0.7625919, 1.8434353, -3.0), 13.152178 wu away.
Collisions? 2
* Collision #0
  You shot a Dragon at (-1.9101039, 0.46635997, 2.0), 8.238082 wu away.
* Collision #1
  You shot a Dragon at (-2.38763, 0.58294994, 0.0), 10.297603 wu away.

Is this a bug (if yes where do I go to report it), if not then what am I missing? :)

Cheers
Waffle
Waffle said:

Hey there,

tutorial was fine for me. Except that it crashed earlier (NullPointerException). That has since been fixed after I updated my working copy. However, it is still detecting hits twice on some elements.

For example,

Collisions? 2
* Collision #0
  You shot the Sherrif at (-0.64527005, 1.5598298, -1.0), 11.128766 wu away.
* Collision #1
  You shot the Sherrif at (-0.7625919, 1.8434353, -3.0), 13.152178 wu away.
Collisions? 2
* Collision #0
  You shot a Dragon at (-1.9101039, 0.46635997, 2.0), 8.238082 wu away.
* Collision #1
  You shot a Dragon at (-2.38763, 0.58294994, 0.0), 10.297603 wu away.

Is this a bug (if yes where do I go to report it), if not then what am I missing? :)

Cheers
Waffle

Its not a bug. You're shooting a ray through a box, the ray passes through two sides of the box, so you get two collisions.

Aha that makes sense.



That means the output image in the tutorial will need to be updated, as it only shows 1 collision per object.



Much Thanks :slight_smile:

Waffle

Hi, where must I put the town.zip file?



Currently I drag and dropped it into Project Assets -> Scenes



But for that to work I have to change my locator:

[java]assetManager.registerLocator(‚ÄúC:/Documents and Settings/tjorriemorrie/jMonkeyProjects/9 Hello Collision/assets/Scenes/town.zip‚ÄĚ, ZipLocator.class.getName());[/java]



I’m sure that is wrong. What is the root and how do I reference it relatively?



What happens when you have a lot of maps in your game? Isn’t it better to put them in the assets folder? Am I misunderstanding what a scene is?



Secondly, looking at the comic, how do I edit the town.zip in the scenecomposer?

The demo only uses a zip because it would be too much data that we have to pack into the jME download. Generally you would deliver your assets with the game jar files.

tjorriemorrie said:
Hi, where must I put the town.zip file?


I added more details to the tutorial. For this example, it is expected to be on the same level as the src/, assets/ and build.xml. (I put it there, because if you run the ample code from the svn check-out jme/jmetests, the file is already there. If you don't use the check-out, you have to copy it there.)

tjorriemorrie said:
Currently I drag and dropped it into Project Assets -> Scenes

But for that to work I have to change my locator:
[java]assetManager.registerLocator("C:/Documents and Settings/tjorriemorrie/jMonkeyProjects/9 Hello Collision/assets/Scenes/town.zip", ZipLocator.class.getName());[/java]
I'm sure that is wrong. What is the root and how do I reference it relatively?


The locator looks into the assets directory by default, if you put stuff there, you should not need to register it again. Also I'd recommend using registering relative paths not absolute ones (absolute patsh only work for one person -- you). ;) You could use:

[java] assetManager.registerLocator("assets/Scenes/town.zip", ZipLocator.class.getName());
Spatial gameLevel = assetManager.loadModel("main.scene");[/java]

tjorriemorrie said:What happens when you have a lot of maps in your game? Isn't it better to put them in the assets folder? Am I misunderstanding what a scene is?


Yes, if you had many you'd put them in subfolders of the assets folder. Then they'll end up being included in the distributable JAR.

You only register a new locator if, for example, you want to add a new directory to the assetmanager where your users can place extra files (custom scenes like this town.zip or anything) to load.

tjorriemorrie said:Secondly, looking at the comic, how do I edit the town.zip in the scenecomposer?


Unzip it first. :) Then you use the right-click menu to convert it to binary. Then open the binary (.j3o) in the scenecomposer.

Hi,

I have run through the above tutorial and everything works fine on the PC.

But when I try to run it on my phone, it’s not finding the .zip file and throws an exception.

How do I force the town.zip file to be part of the executable .jar? (or .apk actually)

I have the file in assets/Scenes.



Thanks in advance.



duinui

Unzip it in assets/scenes

Thanks for the reply.

I unzipped it in assets/scenes.

Commented out:

assetManager.registerLocator(‚Äúassets/Scenes/town.zip‚ÄĚ, ZipLocator.class.getName());

and changed

sceneModel = assetManager.loadModel(‚Äúmain.scene‚ÄĚ);

to

sceneModel = assetManager.loadModel(‚ÄúScenes/main.scene‚ÄĚ);

to get it to compile.

Again it still works fine on the PC, the .apk got bigger (41mB) so I thought it was gonna work.

But the Asset manager threw an exception again, so it (the phone) is still not managing to load the assets correctly.