Java tutorial
package com.tm4rkus.screens; /** * Copyright 2011 David Kirchner dpk@dpk.net * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * TiledMapHelper can simplify your game's tiled Map operations. You can find * some sample code using this class at my blog: * * http://dpk.net/2011/05/08/libgdx-box2d-tiled-Maps-full-working-example-part-2/ * * Note: This code does have some limitations. It only supports single-layered * Maps. * * This code is based on TiledMapTest.java found at: * http://code.google.com/p/libgdx/ */ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.math.Intersector; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.collision.Ray; import com.badlogic.gdx.scenes.scene2d.Stage; import com.tm4rkus.conquertheempire.Game; import com.tm4rkus.helperclasses.Map; public class MapScreenNew extends Stage { protected OrthographicCamera cam; protected boolean touchDragged = false; private final static int tilesOnSight = 10; private final SpriteBatch spriteBatch; private final ModelBatch modelBatch; private final Matrix4 matrix = new Matrix4(); //private final Map Map = Game.Map; public MapScreenNew() { cam = new OrthographicCamera(tilesOnSight, tilesOnSight * (Gdx.graphics.getHeight() / (float) Gdx.graphics.getWidth())); cam.direction.set((float) -1, -1, 0); cam.position.set((float) ((Map.tiles / 2) - cam.direction.x * 10), (float) (10), (float) (Map.tiles / 2)); cam.near = 1; cam.far = 100; matrix.setToRotation(new Vector3(1, 0, 0), 90); spriteBatch = new SpriteBatch(); spriteBatch.setTransformMatrix(matrix); modelBatch = new ModelBatch(); } long deltaTime = 0; long oldTime = System.currentTimeMillis(); long newTime = System.currentTimeMillis(); public void draw() { if (Game.objectManager.isLoading() && Game.objectManager.update()) { Game.objectManager.getModels(); for (int i = 0; i < 1; i++) { Map.createObject(100, 100); } } if (!Game.objectManager.isLoading()) { oldTime = System.currentTimeMillis(); deltaTime = oldTime - newTime; newTime = System.currentTimeMillis(); act(); // do not forget this one!! Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); cam.update(); cam.apply(Gdx.gl10); spriteBatch.setProjectionMatrix(cam.combined); //spriteBatch.setTransformMatrix(matrix); spriteBatch.begin(); modelBatch.begin(cam); Map.draw(spriteBatch, modelBatch); spriteBatch.end(); modelBatch.end(); super.draw(); } } private static boolean stop = false; public static void stop() { stop = true; } public static void run() { stop = false; } //final Plane Map.xzPlane = new Plane(new Vector3(0, 1, 0), 0); //final Vector3 Map.intersection = new Vector3(); @Override public boolean touchDragged(int x, int y, int pointer) { //move the camera Boolean isTouchDragged = super.touchDragged(x, y, pointer); if (!isTouchDragged && numberOfFingers == 1) { singleTapDragged(x, y); } // pinch to zoom // for pinch-to-zoom if (numberOfFingers == 2) { twoFingersDragged(x, y, pointer); } cam.update(); Map.moved = true; return false; } /** * If no object selected: Select object (or add object to the already selected objects). * If object(s) selected: Send object to touched point on the Map (or attack hostile object at that point) * @param x x-coordinate on the Map * @param z z-coordinate on the Map */ private void singleTap(float x, float z) { // TODO: select object // TODO: send object } /** * Move the camera to scroll over the Map * @param x x-coordinate of the finger on screen * @param y y-coordinate of the finger on screen */ final Vector3 currentSingleTapDrag = new Vector3(); final Vector3 lastSingleTapDrag = new Vector3(-1, -1, -1); final Vector3 deltaSingleTapDrag = new Vector3(); private void singleTapDragged(int x, int y) { Ray pickRay = cam.getPickRay(x, y); Intersector.intersectRayPlane(pickRay, Map.xzPlane, currentSingleTapDrag); if (!(lastSingleTapDrag.x == -1 && lastSingleTapDrag.y == -1 && lastSingleTapDrag.z == -1)) { pickRay = cam.getPickRay(lastSingleTapDrag.x, lastSingleTapDrag.y); Intersector.intersectRayPlane(pickRay, Map.xzPlane, deltaSingleTapDrag); deltaSingleTapDrag.sub(currentSingleTapDrag); cam.position.add(deltaSingleTapDrag.x, 0, deltaSingleTapDrag.z); cam.update(); Ray centerRay = cam.getPickRay(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2); Intersector.intersectRayPlane(centerRay, Map.xzPlane, Map.intersection); float centerX = Map.intersection.x; float centerZ = Map.intersection.z; System.out.println("touchdrag " + centerX); if (centerX < 2) { cam.position.x = (float) (2 - (cam.direction.x * cam.position.y)); } if (centerZ > Map.tiles - 2) { cam.position.z = Map.tiles - 2; } if (centerX > Map.tiles - 2) { cam.position.x = (float) (Map.tiles - 2 - (cam.direction.x * cam.position.y)); } if (centerZ < 2) { cam.position.z = 2; } } lastSingleTapDrag.set(x, y, 0); if (deltaSingleTapDrag.x != 0.0 || deltaSingleTapDrag.y != 0.0 || deltaSingleTapDrag.z != 0.0) { touchDragged = true; } } //end singleTapDragged /** * Create a selection rectangle and select all movable objects within it's range * @param x x-coordinate of the finger on screen * @param y y-coordinate of the finger on screen */ private Vector3 startDoubleTapDrag = new Vector3(); private void doubleTapDragged(float x, float y) { // TODO: create selection rectangle and select all movable objects within it's range } //end doubleTapDragged /** * If both fingers go up: tilt cam * If both fingers go apart: zoom cam * @param x x-coordinate of the finger on screen * @param y y-coordinate of the finger on screen * @param pointer pointer to identify the finger */ private void twoFingersDragged(int x, int y, int pointer) { if (pointer == fingerOnePointer) { fingerOne.set(x, y, 0); } if (pointer == fingerTwoPointer) { fingerTwo.set(x, y, 0); } float xDistance = Math.abs(fingerOne.x - fingerTwo.x); float xChange = xDistance - lastXDistance; float yChange = (fingerOne.y + fingerTwo.y) - (lastY1 + lastY2); if (((fingerOne.y > lastY1 && fingerTwo.y > lastY2) || (fingerOne.y < lastY1 && fingerTwo.y < lastY2)) && (Math.abs(yChange) > Math.abs(xChange))) { tiltCam(yChange); } else { // zoom in and out zoomCam(xChange); } lastXDistance = xDistance; //the method touchdragged registers only one pointer at once, so don't update both if (pointer == fingerTwoPointer) { lastY1 = fingerOne.y; } else if (pointer == fingerOnePointer) { lastY2 = fingerTwo.y; } } /** * Tilt camera to have a more 3-dimensional scene from the side or more 2-dimensional from above (like GTA2 ;P) * @param tiltFactor The Factor the declination changes with */ private void tiltCam(float tiltFactor) { cam.direction.x -= tiltFactor * 0.005; cam.position.x = (float) (centerX - (cam.direction.x * cam.position.y)); cam.update(); // don't tilt too much if (cam.direction.x < (float) -2.2) { cam.direction.x = (float) -2.2; } if (cam.direction.x > (float) -0.1) { cam.direction.x = (float) -0.1; } } /** * Zoom camera to have a wider or a closer view at the scene * @param zoomFactor The Factor the zoom changes with: (zoomFactor > 0) --> closer view ; (zoomFactor < 0) --> wider view */ private void zoomCam(float zoomFactor) { // multiply with cam.zoom to get rid of the different zoom speed, depending on whether it close or not. cam.zoom -= cam.zoom * zoomFactor * 0.005; cam.update(); // don't zoom in/out too much. if (cam.zoom > (float) (1.5)) { cam.zoom = (float) (1.5); } if (cam.zoom < (float) (0.8)) { cam.zoom = (float) (0.8); } touchDragged = true; } private long touchTime; protected long lastTouchUp; public boolean touchUp(int x, int y, int pointer, int button) { boolean isTouchUp = super.touchUp(x, y, pointer, button); lastSingleTapDrag.set(-1, -1, -1); // for pinch-to-zoom if (numberOfFingers == 1) { Vector3 touchPoint = new Vector3(x, y, 0); cam.unproject(touchPoint); if (!touchDragged) { Ray pickRay = cam.getPickRay(Gdx.input.getX(), Gdx.input.getY()); Intersector.intersectRayPlane(pickRay, Map.xzPlane, Map.intersection); //Map.createObject(Map.intersection.x, Map.intersection.z); float isctX = Map.intersection.x; float isctZ = Map.intersection.z; if (isctX >= 0 && isctX < Map.tiles && isctZ >= 0 && isctZ < Map.tiles) { if (System.currentTimeMillis() - touchTime > 200) { touchTime = System.currentTimeMillis(); singleTap(isctX, isctZ); } else { touchTime = 0; //doubleTap(isctX, isctZ); } } lastTouchUp = System.currentTimeMillis(); } touchDragged = false; } numberOfFingers--; // if there were more than 2 fingers on the screen if (numberOfFingers > 1) { numberOfFingers = 0; } // if something was not registered properly if (numberOfFingers < 0) { numberOfFingers = 0; } lastDistance = 0; return false; } @Override public boolean keyDown(int keycode) { super.keyDown(keycode); // TODO Auto-generated method stub return false; } @Override public boolean keyUp(int keycode) { super.keyUp(keycode); return false; } @Override public boolean keyTyped(char character) { super.keyTyped(character); return false; } // for pinch-to-zoom int numberOfFingers = 0; int fingerOnePointer; int fingerTwoPointer; float lastDistance = 0; float lastXDistance = 0; float lastY1 = 0; float lastY2 = 0; float centerX = 0; float centerZ = 0; Vector3 fingerOne = new Vector3(); Vector3 fingerTwo = new Vector3(); @Override public boolean touchDown(int x, int y, int pointer, int button) { boolean isTouchDown = super.touchDown(x, y, pointer, button); if (!isTouchDown) { // for pinch-to-zoom numberOfFingers++; if (numberOfFingers == 1) { fingerOnePointer = pointer; fingerOne.set(x, y, 0); } else if (numberOfFingers == 2) { fingerTwoPointer = pointer; fingerTwo.set(x, y, 0); Ray centerRay = cam.getPickRay(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2); Intersector.intersectRayPlane(centerRay, Map.xzPlane, Map.intersection); centerX = Map.intersection.x; centerZ = Map.intersection.z; float distance = fingerOne.dst(fingerTwo); lastDistance = distance; lastXDistance = Math.abs(fingerOne.x - fingerTwo.x); lastY1 = fingerOne.y; lastY2 = fingerTwo.y; } } return false; } public void pause() { numberOfFingers = 0; } @Override public void dispose() { super.dispose(); } @Override public boolean scrolled(int arg0) { super.scrolled(arg0); return false; } public OrthographicCamera getCam() { return cam; } public void setCam(OrthographicCamera cam) { this.cam = cam; } }