LGDX 2D Level Editor - ALPHA 1 - Stress test

Any community contributions to libgdx go here! Some may get included in the core API when permission is granted.

Re: LibGDX 2D Level Editor - ALPHA 1 - Stress test

Postby adeluiz » Mon Mar 28, 2011 5:52 pm

Thanks in advance for sharing your work.

I've try it on Mac Osx Snow Leopard. Everything OK until I select the preview texture button (top left), and when I try to deselect it, it freezes. Here is the code on the java console:

28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] 28-mar-2011 19:17:25 leveleditor.ui.ImagePanel setImageFromFile
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] GRAVE: null
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] javax.imageio.IIOException: Can't read input file!
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.imageio.ImageIO.read(ImageIO.java:1275)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at leveleditor.ui.ImagePanel.setImageFromFile(ImagePanel.java:50)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at leveleditor.ui.ImagePanel.setImageFromFile(ImagePanel.java:33)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at leveleditor.ui.MainWindow.res_files_listValueChanged(MainWindow.java:1162)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at leveleditor.ui.MainWindow.access$3600(MainWindow.java:33)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at leveleditor.ui.MainWindow$38.valueChanged(MainWindow.java:1006)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.JList.fireSelectionValueChanged(JList.java:1795)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1809)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:442)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.JList.setSelectionInterval(JList.java:2065)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.plaf.basic.BasicListUI$Handler.adjustSelection(BasicListUI.java:2727)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.plaf.basic.BasicListUI$Handler.mousePressed(BasicListUI.java:2683)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.plaf.basic.BasicListUI$MouseInputHandler.mousePressed(BasicListUI.java:1497)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at com.apple.laf.AquaListUI$MouseInputHandler.mousePressed(AquaListUI.java:109)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:263)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Component.processMouseEvent(Component.java:6371)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Component.processEvent(Component.java:6139)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Container.processEvent(Container.java:2085)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Component.dispatchEventImpl(Component.java:4736)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Container.dispatchEventImpl(Container.java:2143)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Component.dispatchEvent(Component.java:4566)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4621)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4279)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4212)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Container.dispatchEventImpl(Container.java:2129)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Window.dispatchEventImpl(Window.java:2478)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.Component.dispatchEvent(Component.java:4566)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:680)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue.access$000(EventQueue.java:86)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue$1.run(EventQueue.java:639)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue$1.run(EventQueue.java:637)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.security.AccessController.doPrivileged(Native Method)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue$2.run(EventQueue.java:653)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue$2.run(EventQueue.java:651)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.security.AccessController.doPrivileged(Native Method)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventQueue.dispatchEvent(EventQueue.java:650)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] 28-mar-2011 19:17:25 leveleditor.ui.ImagePanel setImageFromFile
28/03/11 19:17:25 [0x0-0x742742].com.apple.JarLauncher[13820] GRAVE: null
adeluiz
 
Posts: 6
Joined: Mon Mar 28, 2011 5:13 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby Obli » Tue Mar 29, 2011 12:39 pm

Thanks for all the bug reports. I'm putting a strong effort to enhance the reliability of the application and ease debug through error dumps. If it works fine on my computers, it doesn't mean that it will work everywhere (I'm still learning this fact XD).

I'll open the source code in a google code repository before any libgdx extension integration, to ease issue tracking. New versions are to be expected quite soon, but I've got a LOT of work at the lab, sorry for the delays.
Obli
 
Posts: 616
Joined: Mon Jan 10, 2011 6:18 pm
Location: Bordeaux, France

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby jbrin » Tue Mar 29, 2011 11:43 pm

Hi Obli, can you talk a bit about the shape exporter? The level loader has been working nicely to create/import the static objects for my levels, but how does the it work when it comes to shapes since they have to be able to move? If you could post a code sample that shows the intended way of working with shapes (from importing to rendering movement) it would be really helpful.

Oh also, I'm not sure if this has been mentioned, but do you have any thoughts as to how rendering animated shapes might work? (Blargh: Feature creep!)

Thanks. :)
-Jason
jbrin
 
Posts: 71
Joined: Thu Dec 30, 2010 9:16 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby jbrin » Wed Mar 30, 2011 12:18 am

My bad, rendering shapes is pretty straight forward. :oops:

Code: Select all
//Loading
ImportHelper importer = new ImportHelper();
ShapeModel goomba = importer.loadShape(Gdx.files.internal(FILEPATH_GOOMBA));

//Rendering
goomba.getFillMesh().render(GL10.GL_TRIANGLES);
-Jason
jbrin
 
Posts: 71
Joined: Thu Dec 30, 2010 9:16 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby Obli » Wed Mar 30, 2011 7:59 am

Code: Select all
//Loading
ImportHelper importer = new ImportHelper();
ShapeModel goomba = importer.loadShape(Gdx.files.internal(FILEPATH_GOOMBA));

//Rendering
goomba.filltexDef.getTexture().bind();
goomba.getFillMesh().render(GL10.GL_TRIANGLES);

goomba.borderTexDef.getTexture().bind();
goomba.getBorderMesh().render(GL10.GL_TRIANGLES);


Actually, there is no real difference between a LevelModel and a ShapeModel. A LevelModel is just a container for multiple ShapeModels :)
The only difference is that when you export a Shape, its vertex coordinates are offset so its mass center is located at (0, 0), in order for you to move it easily.
Obli
 
Posts: 616
Joined: Mon Jan 10, 2011 6:18 pm
Location: Bordeaux, France

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby jbrin » Wed Mar 30, 2011 8:28 am

That makes the code so clean, thank you!
-Jason
jbrin
 
Posts: 71
Joined: Thu Dec 30, 2010 9:16 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby Saurav » Wed Mar 30, 2011 3:55 pm

OK, really dumb newbie question here. How would I use this to interact with box2d? Let's say I want to use this tool to define my level, and then I have characters that need to move around the level based on touch input, collide with the objects in the level, and so on. I currently have a Model class that contains the box2d world. My input handler sends in the touch coordinates, then my Model computes forces based on the positions of the critters, and applies forces accordingly. Then I step the world, and rendering is just drawing all the objects at their current positions.

How does that map onto using this tool? I think I can figure out how to load a level, and how to draw it. But I'm not too clear on how to build a box2d world from the loaded model. Also, if the world is moving the objects around, how does that work with rendering through the model?

Maybe I'm supposed to use the model only for the static objects? So if I can somehow send them into box2d, then I can render them straight from the model, since they won't move. And the moving critters get rendered based on their positions in the box2d world?
Saurav
 
Posts: 623
Joined: Sun Feb 27, 2011 7:59 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby jbrin » Wed Mar 30, 2011 7:55 pm

You can get the position and angle from your Box2D Body, then shift and rotate by these values via glTranslatef and glRotatef.

Code: Select all
/* Get position and angle from the B2D Body*/
final Rectangle box = shapeModel.boundingBox;
final Vector2 pos = body.getPosition().sub(box.getWidth() / 2, box.getHeight() / 2);
final float ang = body.getAngle() * MathUtils.radiansToDegrees;

/* Render */
gl.glPushMatrix();
gl.glTranslatef(pos.x, pos.y, 0);
gl.glRotatef(ang, 0, 0, 1);
shapeModel.fillTexDef.getTexture().bind();
shapeModel.getFillMesh().render(GL10.GL_TRIANGLES);
gl.glPopMatrix();


There was an extra step above to get the ShapeModel's bounding box, which is used to center the mesh on to the Box2D body. When you're using the level editor, you'll need to set the body center to the bottom left corner of your Shape (recall that mesh coordinates originate at the bottom left), otherwise you may get an undesirable tiling effect.
-Jason
jbrin
 
Posts: 71
Joined: Thu Dec 30, 2010 9:16 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby Saurav » Wed Mar 30, 2011 8:25 pm

OK, I'll have to digest that, so far I've been using Sprites to draw my bodies. But I think that still leaves the question, after I load up a model, how do I get the bodies into the world?
Saurav
 
Posts: 623
Joined: Sun Feb 27, 2011 7:59 pm

Re: LGDX 2D Level Editor - ALPHA 1 - Stress test

Postby jbrin » Wed Mar 30, 2011 10:28 pm

Basically, you will need to get the list of PolygonShape coordinates from the ShapeModel.

Whenever you draw a shape in the LibGDX editor a ShapeModel is created. The ShapeModel stores a list of vertices, among other things, that describes all the triangles in the mesh. To create a Box2D body, you will only need the vertices that describe the collision body.

Back in the editor, when you lasso a list of vertices using the "Set Collision Mask" tool, a representation of the collision body is generated and stored in the ShapeModel. A collision body is stored as a list of indices that reference the list of vertices in the ShapeModel. The goal here is to use the list of indices to extract the list of vertices and then load those vertices into our PolygonShape.

Here's the code:
Code: Select all
    /**
     * Build the list of vertices for each collision body from the ShapeModel.
     *
     * @param shapeModel The ShapeModel that contains the list of B2Shape vertices.
     * @return A list of vertices to be loaded into the B2Shape.
     **/
    private Vector2[][] buildVerticesList(final ShapeModel shapeModel) {
        final List<Vector2> shapeVertices = shapeModel.points;
        final List<int[]> indicesList = shapeModel.collisionBodies;
        final int indicesListSz = indicesList.size();
        final Vector2[][] verticesList = new Vector2[indicesListSz][];
       
        //Build list of vertices for each collision body
        for (int i = 0; i < indicesListSz; i++) {
            final int[] indices = indicesList.get(i);
            final int indicesLen = indices.length;
           
            if (indicesLen == 0) continue;
           
            //Build list of vertices for a single collision body
            final Vector2[] vertices = new Vector2[indicesLen];
            for (int j = 0; j < indicesLen; j++) {
                vertices[j] = shapeVertices.get(indices[j]);
            }
           
            verticesList[i] = vertices;
        }
       
        return verticesList;
    }


You can then set the Vector2[][] that is returned to set the Shapes for each fixture.

For example:
Code: Select all
    private void createFixtures(final ShapeModel shapeModel, final Body body) {
        final PolygonShape shape = new PolygonShape();
        final FixtureDef fd = new FixtureDef();
       
        final Vector2[][] verticesList = buildVerticesList(shapeModel);
       
        for (final Vector2[] vertices : verticesList) {
            shape.set(vertices);
            fd.shape = shape;
            body.createFixture(fd);
        }
       
        shape.dispose();
    }
-Jason
jbrin
 
Posts: 71
Joined: Thu Dec 30, 2010 9:16 pm

PreviousNext

Return to Libgdx Contributions

Who is online

Users browsing this forum: No registered users and 1 guest