Android Games: Midori no Tabi

De Aulas

Links relacionados: Jogos Digitais

Recursos

DesktopLauncher

 1package com.mygdx.game.desktop;
 2
 3import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
 4import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
 5import com.mygdx.game.MyGdxGame;
 6
 7public class DesktopLauncher {
 8	public static void main (String[] arg) {
 9		LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
10		config.height = 400;
11		config.width = 800;
12		config.title = "Midori no Tabi";
13		new LwjglApplication(new MyGdxGame(), config);
14	}
15}

MultiScroll.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.graphics.Texture;
 4import com.badlogic.gdx.graphics.g2d.Sprite;
 5import com.badlogic.gdx.graphics.g2d.TextureRegion;
 6
 7import java.util.ArrayList;
 8import java.util.List;
 9
10class MultiScroll {
11    private MyGdxGame game;
12    private Actor actor;
13    private List<Sprite> img = new ArrayList<Sprite>();
14
15    MultiScroll(Actor actor, MyGdxGame game) {
16        this.actor = actor;
17        this.game = game;
18    }
19
20    void run() {
21        game.x = actor.x - (game.w / 2) + (actor.w / 2);
22        if (game.x < 0) {
23            game.x = 0;
24        } else if (game.x > game.worldWidth - game.w) {
25            game.x = game.worldWidth - game.w;
26        }
27    }
28
29    void draw(int x) {
30        int w = game.w;
31        Sprite sprite_0 = img.get(0);
32        int w0 = (int) sprite_0.getWidth() * 2;
33        for (int i = img.size() - 1; i > 0; i--) {
34            Sprite sprite_i = img.get(i);
35            int wi = (int) sprite_i.getWidth() * 2;
36            int xi = x * (wi - w) / (w0 - w);
37            sprite_i.setPosition(-xi, 0);
38            sprite_i.draw(game.batch);
39        }
40        sprite_0.setPosition(-x, 0);
41        sprite_0.draw(game.batch);
42    }
43
44    void setActor(Actor actor) {
45        this.actor = actor;
46    }
47
48    void add(Texture texture, int x, int y, int w, int h) {
49        Sprite sprite = new Sprite(new TextureRegion(texture, x, y, w, h));
50        sprite.setOrigin(0, 0);
51        sprite.setScale(2f);
52        img.add(sprite);
53    }
54}

Actor.java

  1package com.mygdx.game;
  2
  3import com.badlogic.gdx.graphics.g2d.Sprite;
  4import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  5import com.badlogic.gdx.graphics.g2d.TextureRegion;
  6import com.badlogic.gdx.math.Intersector;
  7
  8class Actor {
  9    static final int WALK = 0;
 10    static final int PAIN = 1;
 11    static final int HIT = 2;
 12    static final int JUMP = 3;
 13    static final int DIE = 4;
 14    static final float G = 0.99f;
 15    static final int LEFT = 0;
 16    static final int RIGHT = 1;
 17    static final int SPEED = 4;
 18    private static final int animationMax = 4;
 19    int w, h; // Width and height of actor
 20    int x, y; // Actors position on scenario
 21    int action;
 22    int direction;
 23    boolean jumping = false;
 24    boolean dead = false;
 25    MyGdxGame game;
 26    private int animation;
 27    private int step;
 28    private int W, H; // Width and height of spritesheet
 29    private Sprite sprite; // Actor sprite
 30    private int stepMax = 8;
 31    private TextureRegion texture; // Actors spritesheet
 32    private float vectorG = 0;
 33    private boolean hitting = false;
 34    private boolean dying = false;
 35
 36    Actor(TextureRegion reg, int x, int y, MyGdxGame game) {
 37        this.game = game;
 38        texture = reg;
 39        W = texture.getRegionWidth();
 40        H = texture.getRegionHeight();
 41        w = W / stepMax;
 42        h = H / 10;
 43        this.x = x;
 44        this.y = y;
 45        vectorG = 0;
 46        direction = RIGHT;
 47        sprite = new Sprite(new TextureRegion(texture, 0, 0, w, h));
 48        sprite.setPosition(x - game.x, y);
 49    }
 50
 51    void execute() {
 52    }
 53
 54    void run() {
 55        gravity();
 56        if (dead) return;
 57        if (isDying()) return;
 58        if (y < 10) die();
 59        hitAction();
 60        execute();
 61    }
 62
 63    void move(int dir) {
 64        if (dying || hitting) return;
 65        direction = dir;
 66        if (direction == LEFT) {
 67            if (game.isFree(x + (w / 2) - 20, y)) {
 68                x -= SPEED;
 69                updateAnimation();
 70            }
 71        } else {
 72            if (game.isFree(x + (w / 2) + 20, y)) {
 73                x += SPEED;
 74                updateAnimation();
 75            }
 76        }
 77    }
 78
 79    private void updateAnimation() {
 80        animation++;
 81        if (animation > animationMax) {
 82            animation = 0;
 83            step++;
 84            if (step >= stepMax - 1) step = 0;
 85            if (!jumping) action = WALK;
 86        }
 87    }
 88
 89    void draw(SpriteBatch batch) {
 90        sprite.setRegion(texture, w * step, (action * h * 2) + (direction * h), w, h);
 91        sprite.setPosition(x - game.x, y);
 92        sprite.draw(batch);
 93    }
 94
 95    void jump() {
 96        if (jumping || hitting) return;
 97        jumping = true;
 98        action = JUMP;
 99        step = 3;
100        y += 10;
101        vectorG = -15;
102    }
103
104    void hit() {
105        if (jumping || hitting) return;
106        step = 0;
107        action = HIT;
108        hitting = true;
109        animation = 0;
110    }
111
112    private void hitAction() {
113        if (hitting) {
114            animation++;
115            if (animation > animationMax) {
116                animation = 0;
117                step++;
118                if (step == 5) {
119                    step = 0;
120                    hitting = false;
121                }
122            }
123        }
124    }
125
126    void die() {
127        if (dying) return;
128        step = 0;
129        action = DIE;
130        dying = true;
131        animation = 0;
132    }
133
134    private boolean isDying() {
135        if (!dying) return false;
136        action = DIE;
137        animation++;
138        if (animation > animationMax) {
139            animation = 0;
140            step++;
141            if (step >= 4) {
142                dying = false;
143                dead = true;
144                step = 4;
145            }
146        }
147        return true;
148    }
149
150    private void gravity() {
151        boolean out = false;
152        int middle = w / 2;
153        if (game.isFree(x + middle, y - 1)) {
154            vectorG += G;
155            y -= vectorG;
156            out = true;
157        }
158        if (!game.isFree(x + middle, y)) {
159            while (!game.isFree(x + middle, y)) {
160                y++;
161            }
162            vectorG = 0;
163            jumping = false;
164            action = WALK;
165            out = false;
166        }
167        if (!out && jumping) jumping = false;
168    }
169
170    boolean isHole(int dir) {
171        if (dir == LEFT) return game.isFree(x + (w / 2) - SPEED, y - 10);
172        else return game.isFree(x + (w / 2) + SPEED, y - 10);
173    }
174
175    void play(String name) {
176        if (!jumping && !hitting && onScreen()) {
177            game.sounds.get(name).play();
178        }
179    }
180
181    private boolean onScreen() {
182        return (x - game.x < game.w) && (x - game.x + w > 0);
183    }
184
185    boolean collide(Actor other) {
186        return this != other && !this.dead && !other.dead &&
187                (Intersector.overlaps(
188                        sprite.getBoundingRectangle(),
189                        other.sprite.getBoundingRectangle()));
190    }
191}

Fly.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.graphics.g2d.TextureRegion;
 4
 5import java.util.Random;
 6
 7class Fly extends Actor {
 8    private Random rand = new Random();
 9    private int count = 0;
10    private int max = 20;
11
12    Fly(TextureRegion reg, int x, int y, MyGdxGame game) {
13        super(reg, x, y, game);
14    }
15
16    @Override
17    void execute() {
18        count++;
19        if (count > max) {
20            count = 0;
21            max = rand.nextInt(30) + 10;
22            direction = rand.nextInt(2);
23            if (y < 200) {
24                play("fly");
25                jump();
26            }
27        }
28        move(direction);
29    }
30}

Goop.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.graphics.g2d.TextureRegion;
 4
 5import java.util.Random;
 6
 7class Goop extends Actor {
 8    private Random rand = new Random();
 9    private int count = 0;
10    private int max = 20;
11
12    Goop(TextureRegion reg, int x, int y, MyGdxGame game) {
13        super(reg, x, y, game);
14    }
15
16    @Override
17    void execute() {
18        count++;
19        if (count > max) {
20            count = 0;
21            max = rand.nextInt(30) + 10;
22            direction = rand.nextInt(2);
23            play("goop");
24        }
25        if (!isHole(direction)) move(direction);
26    }
27}

Avatar.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.Gdx;
 4import com.badlogic.gdx.Input;
 5import com.badlogic.gdx.graphics.g2d.TextureRegion;
 6
 7class Avatar extends Actor {
 8    Avatar(TextureRegion reg, int x, int y, MyGdxGame game) {
 9        super(reg, x, y, game);
10    }
11
12    @Override
13    void execute() {
14        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
15            move(LEFT);
16        } else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
17            move(RIGHT);
18        }
19        if (Gdx.input.isKeyJustPressed(Input.Keys.UP)) {
20            play("jump");
21            jump();
22        }
23        if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
24            play("kick");
25            hit();
26        }
27        for (Actor a : game.actors) {
28            if (collide(a)) {
29                if (action == HIT) a.die();
30                else die();
31            }
32        }
33    }
34}

MyGdxGame.java

  1package com.mygdx.game;
  2
  3import com.badlogic.gdx.ApplicationAdapter;
  4import com.badlogic.gdx.Gdx;
  5import com.badlogic.gdx.Input;
  6import com.badlogic.gdx.audio.Music;
  7import com.badlogic.gdx.audio.Sound;
  8import com.badlogic.gdx.graphics.Color;
  9import com.badlogic.gdx.graphics.GL20;
 10import com.badlogic.gdx.graphics.Pixmap;
 11import com.badlogic.gdx.graphics.Texture;
 12import com.badlogic.gdx.graphics.g2d.Sprite;
 13import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 14import com.badlogic.gdx.graphics.g2d.TextureRegion;
 15
 16import java.util.ArrayList;
 17import java.util.HashMap;
 18import java.util.List;
 19import java.util.Map;
 20
 21public class MyGdxGame extends ApplicationAdapter {
 22    Map<String, Sound> sounds = new HashMap<String, Sound>();
 23    List<Actor> actors = new ArrayList<Actor>();
 24    int x, w, h, worldWidth;
 25    SpriteBatch batch;
 26    private Texture sprites;
 27    private MultiScroll scenario;
 28    private Avatar avatar;
 29    private Sprite gameOver;
 30    private Music music;
 31    private Pixmap mask;
 32    private int actorIndex;
 33
 34    @Override
 35    public void create() {
 36        worldWidth = 4096;
 37        w = Gdx.graphics.getWidth();
 38        h = Gdx.graphics.getHeight();
 39
 40        batch = new SpriteBatch();
 41        mask = new Pixmap(Gdx.files.internal("swampmask.png"));
 42        sprites = new Texture("spritesheets.png");
 43        gameOver = new Sprite(new TextureRegion(sprites, 512, 400, 512, 100));
 44        gameOver.setPosition((w / 2) - (gameOver.getWidth() / 2), (h / 2) - (gameOver.getHeight() / 2));
 45
 46        sounds.put("kick", Gdx.audio.newSound(Gdx.files.internal("kick.wav")));
 47        sounds.put("jump", Gdx.audio.newSound(Gdx.files.internal("jump.wav")));
 48        sounds.put("goop", Gdx.audio.newSound(Gdx.files.internal("goop.wav")));
 49        sounds.put("fly", Gdx.audio.newSound(Gdx.files.internal("fly.wav")));
 50
 51        TextureRegion textureAvatar = new TextureRegion(sprites, 640, 800, 696, 1020);
 52        TextureRegion textureGoop = new TextureRegion(sprites, 0, 800, 635, 1000);
 53        TextureRegion textureFly = new TextureRegion(sprites, 1024, 200, 672, 600);
 54
 55        actors.add(avatar = new Avatar(textureAvatar, 200, 100, this));
 56        actors.add(new Goop(textureGoop, 458, 100, this));
 57        actors.add(new Goop(textureGoop, 1090, 220, this));
 58        actors.add(new Goop(textureGoop, 2040, 100, this));
 59        actors.add(new Fly(textureFly, 3600, 300, this));
 60
 61        scenario = new MultiScroll(actors.get(actorIndex), this);
 62        scenario.add(sprites, 0, 0, 2048, 200);
 63        scenario.add(sprites, 0, 200, 1024, 200);
 64        scenario.add(sprites, 0, 400, 512, 200);
 65
 66        music = Gdx.audio.newMusic(Gdx.files.internal("Music07a02.mp3"));
 67        music.setLooping(true);
 68        music.play();
 69    }
 70
 71    private void execute() {
 72        if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
 73            Gdx.app.exit();
 74        } else if (Gdx.input.isKeyJustPressed(Input.Keys.M)) {
 75            if (music.isPlaying()) music.stop();
 76            else music.play();
 77        }
 78        if (Gdx.input.isKeyJustPressed(Input.Keys.TAB)) {
 79            actorIndex++;
 80            if (actorIndex >= actors.size()) {
 81                actorIndex = 0;
 82            }
 83            scenario.setActor(actors.get(actorIndex));
 84        }
 85        for (Actor m : actors) m.run();
 86        scenario.run();
 87    }
 88
 89    @Override
 90    public void render() {
 91        execute();
 92        Gdx.gl.glClearColor(0, 0, 0, 1);
 93        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
 94        batch.begin();
 95        scenario.draw(x);
 96        for (Actor a : actors) a.draw(batch);
 97        if (avatar.dead) gameOver.draw(batch);
 98        batch.end();
 99    }
100
101    boolean isFree(int px, int py) {
102        Color color = new Color();
103        Color.rgb888ToColor(color, mask.getPixel(px / 2, mask.getHeight() - (py / 2)));
104        return color.r > 0.5f && color.g > 0.5f && color.b > 0.5f;
105    }
106
107    @Override
108    public void dispose() {
109        batch.dispose();
110        sprites.dispose();
111        mask.dispose();
112        music.dispose();
113        for (Map.Entry<String, Sound> entry : sounds.entrySet()) {
114            entry.getValue().dispose();
115        }
116    }
117}