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}