10-day android game development (3)-create the first android game

Source: Internet
Author: User
Document directory
  • Abstract
  • Build a project
  • Encoding
  • Deployment
  • Summary
Abstract

With the previous learning foundation, we can start to develop games. Of course, at this stage, we only focus on learning.

The following is a game called Star guard, a great standalone game. The screen is very loving and difficult, but you can play with unlimited life.

The upper, lower, left, and right mouse of the keyboard are controlled, X is fired, and Z jumps.

What we need to do today is to build a stage and create a Project Skeleton.

The final result looks like this:

Of course, it can be deployed on both mobile phones and PCs.

If you are too lazy to build a project, you can simply use the project you created last time. If you want to create a new project, you can use GDX-setup-UI quickly. Import three projects in eclipse. It looks like this: the project we mainly write is test-GDX-game. The other two are basically unknown. Create corresponding packages under the project, including controller, model, screens, and view. here I have used some MVC knowledge and briefly mentioned that the purpose of the MVC model is to implement a dynamic program design, so that subsequent modifications and extensions of the program are simplified, and make reuse of a part of the program possible. In addition, this mode simplifies the complexity to make the program structure more intuitive. The software system also gives the functions of each basic part by separating its basic parts. Professionals can use their own expertise groups:
(Controller)-responsible for forwarding requests and processing requests.
(View)-graphic interface design by the interface designer.
(Model)-programmers compile the functions (Implementing algorithms and so on) of the program, database experts conduct data management and database design (can implement specific functions ). Encode the model. Here there are three models to be created: Block, Bob, and world ). Block. Java
package com.me.testgdxgame.model;import com.badlogic.gdx.math.Rectangle;import com.badlogic.gdx.math.Vector2;public class Block {public static final float SIZE = 1f;Vector2 position = new Vector2();Rectangle bounds = new Rectangle();public Block(Vector2 pos) {this.position = pos;this.bounds.setX(pos.x);this.bounds.setY(pos.y);this.bounds.width = SIZE;this.bounds.height = SIZE;}public Vector2 getPosition() {return position;}public Rectangle getBounds() {return bounds;}}
Vector2 is a two-dimensional Vector class in libgdx. Bounds is used for collision detection. Bob. Java
package com.me.testgdxgame.model;import com.badlogic.gdx.math.Rectangle;import com.badlogic.gdx.math.Vector2;public class Bob {public enum State {IDLE, WALKING, JUMPING, DYING}public static final float SPEED = 4f;// unit per secondstatic final float JUMP_VELOCITY = 1f;public static final float SIZE = 0.5f; // half a unitVector2 position = new Vector2();Vector2 acceleration = new Vector2();Vector2 velocity = new Vector2();Rectangle bounds = new Rectangle();Statestate = State.IDLE;booleanfacingLeft = true;floatstateTime = 0;public Bob(Vector2 position) {this.position = position;this.bounds.height = SIZE;this.bounds.width = SIZE;}public boolean isFacingLeft() {return facingLeft;}public void setFacingLeft(boolean facingLeft) {this.facingLeft = facingLeft;}public Vector2 getPosition() {return position;}public Vector2 getAcceleration() {return acceleration;}public Vector2 getVelocity() {return velocity;}public Rectangle getBounds() {return bounds;}public State getState() {return state;}public void setState(State newState) {this.state = newState;}public float getStateTime() {return stateTime;}public void update(float delta) {//stateTime += delta;//position.add(velocity.tmp().mul(delta)); position.add(velocity.cpy().mul(delta));}}

Bob has many attributes, such as speed and location. The Code is also very simple. World. Java

package com.me.testgdxgame.model;import java.util.ArrayList;import com.badlogic.gdx.math.Vector2;import com.badlogic.gdx.utils.Array;public class World {/** The blocks making up the world **/ArrayList<Block> blocks = new ArrayList();/** Our player controlled hero **/Bob bob;// Getters -----------public ArrayList<Block>  getBlocks() {return blocks;}public Bob getBob() {return bob;}// --------------------public World() {createDemoWorld();}private void createDemoWorld() {bob = new Bob(new Vector2(7, 2));for (int i = 0; i < 10; i++) {  blocks.add(new Block(new Vector2(i, 0))); blocks.add(new Block(new Vector2(i, 6))); if (i > 2)blocks.add(new Block(new Vector2(i, 1)));}blocks.add(new Block(new Vector2(9, 2)));blocks.add(new Block(new Vector2(9, 3)));blocks.add(new Block(new Vector2(9, 4)));blocks.add(new Block(new Vector2(9, 5)));blocks.add(new Block(new Vector2(6, 3)));blocks.add(new Block(new Vector2(6, 4)));blocks.add(new Block(new Vector2(6, 5)));}}

World includes maps and characters. The class in viewview is mainly responsible for rendering. First, add two textures to the project. Put it under asset/data of the android project. Note: the length and width of a texture map must be a power of 2, for example, 64 × 64,128 × 128 .. otherwise, it cannot be loaded. The official explanation is a bug of OpenGL, which cannot be solved.

package com.me.testgdxgame.view;import com.me.testgdxgame.*;import com.me.testgdxgame.model.Block;import com.me.testgdxgame.model.Bob;import com.me.testgdxgame.model.World;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.graphics.Color;import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.OrthographicCamera;import com.badlogic.gdx.graphics.Texture;import com.badlogic.gdx.graphics.g2d.SpriteBatch;import com.badlogic.gdx.graphics.glutils.ShapeRenderer;import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;import com.badlogic.gdx.math.Rectangle;public class WorldRenderer {private World world;private OrthographicCamera cam;private SpriteBatch spriteBatch;private boolean debug=false;private int width;private int height;private float ppuX; // pixels per unit on the X axisprivate float ppuY; // pixels per unit on the Y axisprivate static final float CAMERA_WIDTH = 10f;private static final float CAMERA_HEIGHT = 7f;/** Textures **/private Texture bobTexture;private Texture blockTexture;/** for debug rendering **/ShapeRenderer debugRenderer = new ShapeRenderer();public WorldRenderer(World world) {this.world = world;this.cam = new OrthographicCamera(10, 7);this.cam.position.set(5, 3.5f, 0);this.cam.update();spriteBatch=new SpriteBatch();loadTextures();}public void setSize (int w, int h) {this.width = w;this.height = h;ppuX = (float)width / CAMERA_WIDTH;ppuY = (float)height / CAMERA_HEIGHT;}private void loadTextures(){bobTexture=new Texture(Gdx.files.internal("data/bob_01.png"));blockTexture=new Texture(Gdx.files.internal("data/block.png"));}public void render() {spriteBatch.begin();drawBlocks();drawBob();spriteBatch.end();if(debug) drawDebug();}private void  drawBlocks(){for (Block block : world.getBlocks()) {spriteBatch.draw(blockTexture, block.getPosition().x * ppuX, block.getPosition().y * ppuY, Block.SIZE * ppuX, Block.SIZE * ppuY);}}private void drawBob(){Bob bob = world.getBob();spriteBatch.draw(bobTexture, bob.getPosition().x * ppuX, bob.getPosition().y * ppuY, Bob.SIZE * ppuX, Bob.SIZE * ppuY);}private void drawDebug(){// render blocksdebugRenderer.setProjectionMatrix(cam.combined);debugRenderer.begin(ShapeType.Rectangle);for (Block block : world.getBlocks()) {Rectangle rect = block.getBounds();float x1 = block.getPosition().x + rect.x;float y1 = block.getPosition().y + rect.y;debugRenderer.setColor(new Color(1, 0, 0, 1));debugRenderer.rect(x1, y1, rect.width, rect.height);}// render BobBob bob = world.getBob();Rectangle rect = bob.getBounds();float x1 = bob.getPosition().x + rect.x;float y1 = bob.getPosition().y + rect.y;debugRenderer.setColor(new Color(0, 1, 0, 1));debugRenderer.rect(x1, y1, rect.width, rect.height);debugRenderer.end();}}

There are several classes to explain: orthographiccamera: orthogonal coordinate system camerta. Used to set the camera. In the later stage, the person needs to be fixed in the middle of the camera's viewport and move with the person. Shaperenderer: used for drawing, including textures, lines, points, and rectangles. Spritebatch: responsible for loading, managing, and drawing textures. There is a drawdebug () in this class that can be used to draw without adding a texture. The result is as follows: the Controller class is used to process input. Worldcontroller. Java

package com.me.testgdxgame.controller;import java.util.HashMap;import java.util.Map;import com.me.testgdxgame.model.Bob;import com.me.testgdxgame.model.Bob.State;import com.me.testgdxgame.model.World;public class WorldController {enum Keys{LEFT,RIGHT,JUMP,FIRE}private World world;private Bob bob;static Map<Keys,Boolean> keys = new HashMap<WorldController.Keys,Boolean>();static {keys.put(Keys.LEFT, false);keys.put(Keys.RIGHT, false);keys.put(Keys.JUMP, false);keys.put(Keys.FIRE, false);};public WorldController(World w){world=w;bob=world.getBob();}//Key presses and touchespublic void leftPressed(){keys.get(keys.put(Keys.LEFT, true));}public void rightPressed() {keys.get(keys.put(Keys.RIGHT, true));}public void jumpPressed() {keys.get(keys.put(Keys.JUMP, true));}public void firePressed() {keys.get(keys.put(Keys.FIRE, false));}public void leftReleased() {keys.get(keys.put(Keys.LEFT, false));}public void rightReleased() {keys.get(keys.put(Keys.RIGHT, false));}public void jumpReleased() {keys.get(keys.put(Keys.JUMP, false));}public void fireReleased() {keys.get(keys.put(Keys.FIRE, false));}public void update(float delta){processInput();bob.update(delta);}private void processInput(){if(keys.get(Keys.LEFT)){bob.setFacingLeft(true);bob.setState(State.WALKING);bob.getVelocity().x=-Bob.SPEED;}if (keys.get(Keys.RIGHT)) {// left is pressedbob.setFacingLeft(false);bob.setState(State.WALKING);bob.getVelocity().x = Bob.SPEED;}// need to check if both or none direction are pressed, then Bob is idleif ((keys.get(Keys.LEFT) && keys.get(Keys.RIGHT)) ||(!keys.get(Keys.LEFT) && !(keys.get(Keys.RIGHT)))) {bob.setState(State.IDLE);// acceleration is 0 on the xbob.getAcceleration().x = 0;// horizontal speed is 0bob.getVelocity().x = 0;}}}

The screen MVC is available, and then the screen is ready. A game usually has many screens, such as the welcome screen, game screen, parameter setting screen, and game end screen. Today we are making a game screen. Add the gamescreen class to the screens package.

package com.me.testgdxgame.screens;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.Input.Keys;import com.badlogic.gdx.InputProcessor;import com.badlogic.gdx.Screen;import com.badlogic.gdx.graphics.GL10;import com.me.testgdxgame.controller.WorldController;import com.me.testgdxgame.model.World;import com.me.testgdxgame.view.WorldRenderer;public class GameScreen implements Screen ,InputProcessor{private WorldRenderer renderer;private World world;private WorldController controller;private int width, height;@Overridepublic void render(float delta) {// TODO Auto-generated method stubGdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);controller.update(delta);renderer.render();}@Overridepublic void resize(int width, int height) {// TODO Auto-generated method stubrenderer.setSize(width, height);this.width=width;this.height=height;}@Overridepublic void show() {// TODO Auto-generated method stubworld = new World();renderer = new WorldRenderer(world);controller=new WorldController(world);Gdx.input.setInputProcessor(this);}@Overridepublic void hide() {// TODO Auto-generated method stubGdx.input.setInputProcessor(null);}@Overridepublic void pause() {// TODO Auto-generated method stub}@Overridepublic void resume() {// TODO Auto-generated method stub}@Overridepublic void dispose() {// TODO Auto-generated method stubGdx.input.setInputProcessor(null);}@Overridepublic boolean keyDown(int keycode) {// TODO Auto-generated method stubif (keycode == Keys.LEFT)controller.leftPressed();if (keycode == Keys.RIGHT)controller.rightPressed();if (keycode == Keys.Z)controller.jumpPressed();if (keycode == Keys.X)controller.firePressed();return true;}@Overridepublic boolean keyUp(int keycode) {// TODO Auto-generated method stubif (keycode == Keys.LEFT)controller.leftReleased();if (keycode == Keys.RIGHT)controller.rightReleased();if (keycode == Keys.Z)controller.jumpReleased();if (keycode == Keys.X)controller.fireReleased();return true;}@Overridepublic boolean keyTyped(char character) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean touchDown(int x, int y, int pointer, int button) {// TODO Auto-generated method stubif (x < width / 2 && y > height / 2) {controller.leftPressed();}if (x > width / 2 && y > height / 2) {controller.rightPressed();}return false;}@Overridepublic boolean touchUp(int x, int y, int pointer, int button) {// TODO Auto-generated method stubif (x < width / 2 && y > height / 2) {controller.leftReleased();}if (x > width / 2 && y > height / 2) {controller.rightReleased();}return true;}@Overridepublic boolean touchDragged(int screenX, int screenY, int pointer) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean mouseMoved(int screenX, int screenY) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean scrolled(int amount) {// TODO Auto-generated method stubreturn false;}}

This class implements the screen and inputprocessor interfaces. Inputprocessor is used to accept touch events and button events. You do not need to modify the project for deploying the desktop version. The main function is as follows:

public class Main {public static void main(String[] args) {LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();cfg.title = "test-gdx-game";cfg.useGL20 = false;cfg.width = 1024;cfg.height = 600;new LwjglApplication(new TestGdxGame(), cfg);}}

Right-click main. Java and choose run as> JAVA application. Android to modify mainactiviy:

public class MainActivity extends AndroidApplication {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();        cfg.useGL20 = false;                initialize(new TestGdxGame(), cfg);    }}

Run as-> Android Application. to sum up, the stage and code framework have been set up, and the following can be added later :. line collision. animation. high-Level camera (the angle of view can be constantly changed ). sound effect. improved input. more gamescreen will be available in the next tutorial. Source code download

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.