OSDN Git Service

added platformer example, not done yet, grrr collision detection
authorMario Zechner <contact@badlogicgames.com>
Thu, 21 Feb 2013 09:05:15 +0000 (10:05 +0100)
committerMario Zechner <contact@badlogicgames.com>
Thu, 21 Feb 2013 09:05:15 +0000 (10:05 +0100)
14 files changed:
tests/gdx-tests-android/.classpath
tests/gdx-tests-android/assets/data/maps/tiled/isometric_grass_and_water.png [moved from tests/gdx-tests-android/assets/data/maps/isometric_grass_and_water.png with 100% similarity]
tests/gdx-tests-android/assets/data/maps/tiled/isometric_grass_and_water.tmx [moved from tests/gdx-tests-android/assets/data/maps/isometric_grass_and_water.tmx with 100% similarity]
tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/koalio.png [new file with mode: 0755]
tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/level1.tmx [new file with mode: 0755]
tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/tileSet.png [new file with mode: 0755]
tests/gdx-tests-android/assets/data/maps/tiled/tiles.png [moved from tests/gdx-tests-android/assets/data/maps/tiles.png with 100% similarity]
tests/gdx-tests-android/assets/data/maps/tiled/tiles.tmx [moved from tests/gdx-tests-android/assets/data/maps/tiles.tmx with 100% similarity]
tests/gdx-tests-android/assets/data/maps/tiled/tiles.tsx [moved from tests/gdx-tests-android/assets/data/maps/tiles.tsx with 100% similarity]
tests/gdx-tests-lwjgl/src/com/badlogic/gdx/tests/lwjgl/LwjglDebugStarter.java
tests/gdx-tests/src/com/badlogic/gdx/tests/TiledMapAssetManagerTest.java
tests/gdx-tests/src/com/badlogic/gdx/tests/TiledMapDirectLoaderTest.java
tests/gdx-tests/src/com/badlogic/gdx/tests/bench/TiledMapBench.java
tests/gdx-tests/src/com/badlogic/gdx/tests/superkoalio/SuperKoalio.java [new file with mode: 0755]

index 738053d..fad05fb 100644 (file)
@@ -12,5 +12,6 @@
        <classpathentry combineaccessrules="false" exported="true" kind="src" path="/gdx-controllers"/>\r
        <classpathentry combineaccessrules="false" exported="true" kind="src" path="/gdx-controllers-android"/>\r
        <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>\r
        <classpathentry kind="output" path="bin/classes"/>\r
 </classpath>\r
diff --git a/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/koalio.png b/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/koalio.png
new file mode 100755 (executable)
index 0000000..1bdca3e
Binary files /dev/null and b/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/koalio.png differ
diff --git a/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/level1.tmx b/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/level1.tmx
new file mode 100755 (executable)
index 0000000..c5aa58c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" width="212" height="20" tilewidth="16" tileheight="16">
+ <tileset firstgid="1" name="tileSet-hd" tilewidth="16" tileheight="16">
+  <image source="tileSet.png" trans="fe80fe" width="256" height="256"/>
+ </tileset>
+ <layer name="background" width="212" height="20">
+  <data encoding="base64" compression="zlib">
+   eJzt19dSFEEUgOE1oKiYQDGhmEWMqChBUcxZQcWIVUbMVQgiKlClYkQvMMcL0BcwPKD/XGjh1jA7sz0z3bt9/qrvjp09vbN0zyYSkiRJkiRJkiSF0XP04AVeWvTekr/kHgXrEz7jC75a9N6Sv+QeSQPrQz++4bvmWdItG9ZgQnLWqvcDP/ELvzXPkm7ZsAYTkrNWsiWbz2Bb1m7q88EQDMUwDEcORmAkcjFK32j/CvrZhXUGm3rPvLLl+cPU54OJyEcBJmEyCjEFUzEtwLWi2ht1fXam3jMp/aI+v+dgLuZhPhZgIRahBIsDXMuWvdErW563MrWov6NlWIXVWINyrMU6VKAygvfM5mRPsbtabMYWbMU2bMcO7MSuQV6Xh7EYF8OM2Vym/EaTc9dfdajHIRzGETTgKI7huMtrZqAIMzELxbFMGk6jMSbx/34wXuM8mfIbTc5df53BWZzDeVzARTThEi4n/X0plmAplmE5VmBlTPOqNj3hvh/M9vHaEziJU2jE6WhGdG2wfWBCgGvonN9JdQ1e88e1tlRraMZNtKAVt9CG22jHnaTrVaEa67EBNdiITT7nGbhmHansB1dwFddwHTcimtEtlX3gbzrnd1Jdg9f8ca0t1Rru4wEeohuP8BhP8BTPkq63G3uwF/uwHwdw0Mcsuu+nk8p+cBf30IFOdEUzomthPBfonN9JdQ1e88e1tlRr6MUrvMYbvMU7vMcHfEy6nsr/k+776ZSp86s+Fzjp/vxV12DC+RTGfZD0p7IPmJLqGkw4n8K+D38A4ca3xw==
+  </data>
+ </layer>
+ <layer name="walls" width="212" height="20">
+  <data encoding="base64" compression="zlib">
+   eJzt1+ENgyAQhmE2bTdoN4AJ7Mr1hySEchwIisX3SS61USgl9yVoDAAAAAAAAAAAAAAAAPZwoxdwko9S0rOu4Tdrx0rr8ffcVqn7s7FbAWhjDXkCerCGPJ3BjV4ADhdn6cp5ctF3fx4PP0d7rPXsOF+P/+aUuXPPS9fxPKWkdyvPCteauHf39HH4vrlnv1NZunKejqJloCYjr7Xejeu5q1QmSvox1btn97KUpZnyVJoDLQM1GVm2Qp1cJnI9KfWuNrb1HBGOz2VppjyV5kDLQE1GyFO9kkyk+jLXu9rY1nOEH69l6cg8LdRP9dgb9rjvflL/W16POVrnmaHutA9faJk07A==
+  </data>
+ </layer>
+</map>
diff --git a/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/tileSet.png b/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/tileSet.png
new file mode 100755 (executable)
index 0000000..939276a
Binary files /dev/null and b/tests/gdx-tests-android/assets/data/maps/tiled/super-koalio/tileSet.png differ
index 20d85a4..49e5017 100644 (file)
@@ -25,6 +25,7 @@ import com.badlogic.gdx.tests.TideMapDirectLoaderTest;
 import com.badlogic.gdx.tests.TiledMapAssetManagerTest;\r
 import com.badlogic.gdx.tests.TiledMapDirectLoaderTest;\r
 import com.badlogic.gdx.tests.bench.TiledMapBench;\r
+import com.badlogic.gdx.tests.superkoalio.SuperKoalio;\r
 import com.badlogic.gdx.tests.utils.GdxTest;\r
 import com.badlogic.gdx.utils.SharedLibraryLoader;\r
 \r
@@ -37,7 +38,7 @@ public class LwjglDebugStarter {
                new SharedLibraryLoader("../../extensions/gdx-controllers/gdx-controllers-desktop/libs/gdx-controllers-desktop-natives.jar").load("gdx-controllers-desktop");\r
                new SharedLibraryLoader("../../gdx/libs/gdx-natives.jar").load("gdx");\r
 \r
-               GdxTest test = new InputTest();\r
+               GdxTest test = new SuperKoalio();\r
                LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();\r
                config.useGL20 = test.needsGL20();\r
                new LwjglApplication(test, config);\r
index 5ecab6a..531898f 100644 (file)
@@ -42,9 +42,9 @@ public class TiledMapAssetManagerTest extends GdxTest {
                
                assetManager = new AssetManager();
                assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
-               assetManager.load("data/maps/isometric_grass_and_water.tmx", TiledMap.class);
+               assetManager.load("data/maps/tiled/isometric_grass_and_water.tmx", TiledMap.class);
                assetManager.finishLoading();
-               map = assetManager.get("data/maps/isometric_grass_and_water.tmx");
+               map = assetManager.get("data/maps/tiled/isometric_grass_and_water.tmx");
                renderer = new IsometricTiledMapRenderer(map, 1f / 64f);
        }
 
index 7dd0bd0..e254b6f 100755 (executable)
@@ -36,7 +36,7 @@ public class TiledMapDirectLoaderTest extends GdxTest {
                font = new BitmapFont();\r
                batch = new SpriteBatch();\r
                \r
-               map = new TmxMapLoader().load("data/maps/tiles.tmx");\r
+               map = new TmxMapLoader().load("data/maps/tiled/super-koalio/level1.tmx");\r
                renderer = new OrthogonalTiledMapRenderer(map, 1f / 32f);\r
        }\r
 \r
index c593d46..59c178e 100644 (file)
@@ -48,7 +48,7 @@ public class TiledMapBench extends GdxTest {
                batch = new SpriteBatch();
                
                {
-                       tiles = new Texture(Gdx.files.internal("data/maps/tiles.png"));
+                       tiles = new Texture(Gdx.files.internal("data/maps/tiled/tiles.png"));
                        TextureRegion[][] splitTiles = TextureRegion.split(tiles, 32, 32);
                        map = new TiledMap();
                        MapLayers layers = map.getLayers();
diff --git a/tests/gdx-tests/src/com/badlogic/gdx/tests/superkoalio/SuperKoalio.java b/tests/gdx-tests/src/com/badlogic/gdx/tests/superkoalio/SuperKoalio.java
new file mode 100755 (executable)
index 0000000..b91fce0
--- /dev/null
@@ -0,0 +1,259 @@
+package com.badlogic.gdx.tests.superkoalio;\r
+\r
+import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.Input.Keys;\r
+import com.badlogic.gdx.graphics.GL10;\r
+import com.badlogic.gdx.graphics.OrthographicCamera;\r
+import com.badlogic.gdx.graphics.Texture;\r
+import com.badlogic.gdx.graphics.g2d.Animation;\r
+import com.badlogic.gdx.graphics.g2d.SpriteBatch;\r
+import com.badlogic.gdx.graphics.g2d.TextureRegion;\r
+import com.badlogic.gdx.graphics.glutils.ShapeRenderer;\r
+import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;\r
+import com.badlogic.gdx.maps.tiled.TiledMap;\r
+import com.badlogic.gdx.maps.tiled.TiledMapTile;\r
+import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;\r
+import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;\r
+import com.badlogic.gdx.maps.tiled.TmxMapLoader;\r
+import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;\r
+import com.badlogic.gdx.math.Rectangle;\r
+import com.badlogic.gdx.math.Vector2;\r
+import com.badlogic.gdx.tests.utils.GdxTest;\r
+import com.badlogic.gdx.utils.Array;\r
+import com.badlogic.gdx.utils.Pool;\r
+\r
+/**\r
+ * Super Mario Brothers like platformer, using a tile map build\r
+ * via <a href="http://www.mapeditor.org/>Tiled</a> and a tileset\r
+ * and sprites by <a href="http://www.vickiwenderlich.com/">Vicky Wenderlich</a>\r
+ * @author mzechner\r
+ *\r
+ */\r
+public class SuperKoalio extends GdxTest {\r
+       \r
+       private static class Koala {\r
+               private static float WIDTH;\r
+               private static float HEIGHT;\r
+               private static float MAX_VELOCITY = 10f;\r
+               private static float WALK_VELOCITY = 2f;\r
+               private static float JUMP_VELOCITY = 40f;\r
+               private static float DAMPING = 0.87f;\r
+               \r
+               enum State {\r
+                       Standing,\r
+                       Walking,\r
+                       Jumping\r
+               }\r
+               \r
+               final Vector2 position = new Vector2();\r
+               final Vector2 velocity = new Vector2();\r
+               State state = State.Walking;\r
+               float stateTime = 0;\r
+               boolean facesRight = true;\r
+               boolean grounded = false;\r
+       }\r
+       \r
+       private TiledMap map;\r
+       private OrthogonalTiledMapRenderer renderer;\r
+       private OrthographicCamera camera;\r
+       private Texture koalaTexture;\r
+       private Animation stand;\r
+       private Animation walk;\r
+       private Animation jump;\r
+       private Koala koala;\r
+       private Pool<Rectangle> rectPool = new Pool<Rectangle>() {\r
+               @Override\r
+               protected Rectangle newObject () {\r
+                       return new Rectangle();\r
+               }\r
+       };\r
+       private Array<Rectangle> tiles = new Array<Rectangle>();\r
+       \r
+       private static final float GRAVITY = -2.5f;\r
+       \r
+       @Override\r
+       public void create () {\r
+               // load the koala frames, split them, and assign them to Animations\r
+               koalaTexture = new Texture("data/maps/tiled/super-koalio/koalio.png"); \r
+               TextureRegion[] regions = TextureRegion.split(koalaTexture, 18, 26)[0];\r
+               stand = new Animation(0, regions[0]);\r
+               jump = new Animation(0, regions[1]);\r
+               walk = new Animation(0.15f, regions[2], regions[3], regions[4]);\r
+               walk.setPlayMode(Animation.LOOP_PINGPONG);\r
+               \r
+               // figure out the width and height of the koala for collision\r
+               // detection and rendering by converting a koala frames pixel\r
+               // size into world units (1 unit == 16 pixels)\r
+               Koala.WIDTH = 1 / 16f * regions[0].getRegionWidth();\r
+               Koala.HEIGHT = 1 / 16f * regions[0].getRegionHeight();\r
+               \r
+               // load the map, set the unit scale to 1/16 (1 unit == 16 pixels)\r
+               map = new TmxMapLoader().load("data/maps/tiled/super-koalio/level1.tmx");\r
+               renderer = new OrthogonalTiledMapRenderer(map, 1 / 16f);\r
+               \r
+               // create an orthographic camera, shows us 30x20 units of the world\r
+               camera = new OrthographicCamera();\r
+               camera.setToOrtho(false, 30, 20);\r
+               camera.update();\r
+               \r
+               // create the Koala we want to move around the world\r
+               koala = new Koala();\r
+               koala.position.set(10, 2);\r
+       }\r
+\r
+       @Override\r
+       public void render () {\r
+               // clear the screen\r
+               Gdx.gl.glClearColor(0.7f, 0.7f, 1.0f, 1);\r
+               Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);\r
+               \r
+               // get the delta time\r
+               float deltaTime = Gdx.graphics.getDeltaTime();\r
+               \r
+               // update the koala (process input, collision detection, position update)\r
+               updateKoala(deltaTime);\r
+               \r
+               // let the camera follow the koala, x-axis only\r
+               camera.position.x = koala.position.x;\r
+               camera.update();\r
+               \r
+               // set the tile map rendere view based on what the\r
+               // camera sees and render the map\r
+               renderer.setView(camera);\r
+               renderer.render();\r
+               \r
+               // render the koala\r
+               renderKoala(deltaTime);\r
+       }\r
+       \r
+       private void updateKoala(float deltaTime) {\r
+               koala.stateTime += deltaTime;\r
+               \r
+               // check input and apply to velocity & state\r
+               if(Gdx.input.isKeyPressed(Keys.SPACE) & koala.grounded) {\r
+                       koala.velocity.y += Koala.JUMP_VELOCITY;\r
+                       koala.state = Koala.State.Jumping;\r
+                       koala.grounded = false;\r
+               }\r
+               \r
+               if(Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A)) {\r
+                       koala.velocity.x -= Koala.WALK_VELOCITY;\r
+                       if(koala.state != Koala.State.Jumping) koala.state = Koala.State.Walking;\r
+                       koala.facesRight = false;\r
+               }\r
+               \r
+               if(Gdx.input.isKeyPressed(Keys.RIGHT) || Gdx.input.isKeyPressed(Keys.D)) {\r
+                       koala.velocity.x += Koala.WALK_VELOCITY;\r
+                       if(koala.state != Koala.State.Jumping) koala.state = Koala.State.Walking;\r
+                       koala.facesRight = true;\r
+               }\r
+               \r
+               // apply gravity if we are falling\r
+               koala.velocity.add(0, GRAVITY);\r
+               \r
+               // multiply by delta time so we know how far we go\r
+               // in this frame\r
+               koala.velocity.mul(deltaTime);\r
+               \r
+               // perform collision detection & response based on the current\r
+               // position and velocity. Collision detection will clamp the\r
+               // velocity if necessary and move the koala out of tiles\r
+               Rectangle koalaRect = rectPool.obtain();\r
+               System.out.println("frame");\r
+               koalaRect.set(koala.position.x, koala.position.y, Koala.WIDTH, Koala.HEIGHT);\r
+               \r
+               koalaRect.y += koala.velocity.y;\r
+               for (Rectangle rect: getCollidingTiles(koala.position, 0, koala.velocity.y)) {\r
+                       if (koalaRect.overlaps(rect)) {\r
+                               System.out.println("coll y");\r
+                               if (koala.velocity.y < 0) {\r
+                                       koalaRect.y = rect.y + rect.height + 0.001f;\r
+                                       koala.grounded = true;\r
+                               } else if(koala.velocity.y > 0 ){\r
+                                       koalaRect.y = rect.y - rect.height - 0.001f;\r
+                               }\r
+                               koala.velocity.y = 0;\r
+                       }\r
+               }\r
+               koala.position.set(koalaRect.x, koalaRect.y);\r
+\r
+               koalaRect.x += koala.velocity.x;\r
+               for (Rectangle rect: getCollidingTiles(koala.position, koala.velocity.x, 0)) {\r
+                       if (koalaRect.overlaps(rect)) {\r
+                               System.out.println("coll x");\r
+                               if (koala.velocity.x < 0) {\r
+                                       koalaRect.x = rect.x + rect.width + 0.001f;\r
+                               } else if(koala.velocity.x > 0){\r
+                                       koalaRect.x = rect.x - rect.width - 0.001f;\r
+                               }\r
+                               koala.velocity.x = 0;\r
+                               koala.state = Koala.State.Standing;\r
+                       }\r
+               }\r
+               koala.position.set(koalaRect.x, koalaRect.y);\r
+\r
+               // unscale the velocity by the inverse delta time and set \r
+               // the latest position\r
+               koala.velocity.mul(1/deltaTime);\r
+               \r
+               // free the koala rectangle\r
+               rectPool.free(koalaRect);\r
+               \r
+               // Apply damping to the velocity on the x-axis so we don't\r
+               // walk infinitely once a key was pressed\r
+               koala.velocity.x *= Koala.DAMPING;\r
+       }\r
+       \r
+       private Array<Rectangle> getCollidingTiles(Vector2 position, float velocityX, float velocityY) {\r
+               // figure out the tiles within which the koala is moving in the current timestep\r
+               int startX, startY, endX, endY;\r
+               if(velocityX < 0) startX = (int)(position.x + velocityX);\r
+               else startX = (int)position.x;\r
+               if(velocityY < 0) startY = (int)(position.y + velocityY);\r
+               else startY = (int)position.y;\r
+               endX = (int)(startX + Koala.WIDTH + Math.abs(velocityX));\r
+               endY = (int)(startY + Koala.HEIGHT + Math.abs(velocityY));\r
+               \r
+               // get all the tiles that overlap this area\r
+               TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().getLayer(1);\r
+               rectPool.freeAll(tiles);\r
+               tiles.clear();\r
+               for(int y = startY; y <= endY; y++) {\r
+                       for(int x = startX; x <= endX; x++) {\r
+                               Cell cell = layer.getCell(x, y);\r
+                               if(cell.getTile() != null) {\r
+                                       Rectangle rect = rectPool.obtain();\r
+                                       rect.set(x, y, 1, 1);\r
+                                       tiles.add(rect);\r
+                               }\r
+                       }\r
+               }\r
+               return tiles;\r
+       }\r
+       \r
+       private void renderKoala(float deltaTime) {\r
+               // based on the koala state, get the animation frame\r
+               TextureRegion frame = null;\r
+               switch(koala.state) {\r
+                       case Standing: frame = stand.getKeyFrame(koala.stateTime); break;\r
+                       case Walking: frame = walk.getKeyFrame(koala.stateTime); break;\r
+                       case Jumping: frame = jump.getKeyFrame(koala.stateTime); break; \r
+               }\r
+               \r
+               // draw the koala, depending on the current velocity\r
+               // on the x-axis, draw the koala facing either right\r
+               // or left\r
+               SpriteBatch batch = renderer.getSpriteBatch();\r
+               batch.begin();\r
+               if(koala.facesRight) {\r
+                       batch.draw(frame, koala.position.x, koala.position.y, Koala.WIDTH, Koala.HEIGHT);\r
+               } else {\r
+                       batch.draw(frame, koala.position.x + Koala.WIDTH, koala.position.y, -Koala.WIDTH, Koala.HEIGHT);\r
+               }\r
+               batch.end();\r
+       }\r
+\r
+       @Override\r
+       public void dispose () {\r
+       }\r
+}\r