Android Games: Skyfire

De Aulas
Revisão de 18h09min de 3 de novembro de 2022 por Admin (discussão | contribs) (→‎Enemy.java)

Links relacionados: Jogos Digitais

Videoaula

Youtube

Recursos

Background.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.Texture;

public class BackGround {
    MyGdxGame game;
    Texture texture;
    int ya, yb;
    int SPEED = 2;

    BackGround(Texture texture, MyGdxGame game) {
        this.game = game;
        this.texture = texture;
        ya = 0;
        yb = texture.getHeight();
    }

    void execute() {
        ya -= SPEED;
        yb -= SPEED;
        if (ya <= -texture.getHeight()) {
            ya = yb + texture.getHeight();
        }
        if (yb <= -texture.getHeight()) {
            yb = ya + texture.getHeight();
        }
    }

    void draw() {
        game.batch.draw(texture, 0, ya);
        game.batch.draw(texture, 0, yb);
    }

    void dispose() {
        texture.dispose();
    }
}

Actor.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Intersector;

public class Actor {
    MyGdxGame game;
    Sprite sprite;
    int SPEED = 10;
    boolean dead = false;

    Actor(float x, float y, Texture texture, MyGdxGame game) {
        this.game = game;
        this.sprite = new Sprite(texture);
        this.sprite.setPosition(x, y);
    }

    void execute() {
        // To implement
    }

    float clamp(float value, float min, float max) {
        if (value < min) return min;
        if (value > max) return max;
        return value;
    }

    boolean collide(Actor other) {
        if (this == other) return false;
        return Intersector.overlaps(
                sprite.getBoundingRectangle(),
                other.sprite.getBoundingRectangle()
        );
    }

    void explode() {
        dead = true;
        game.news.add(new Explosion(
                sprite.getX() + (sprite.getWidth() / 2f) - (game.texturesExplosion.get(0).getWidth() / 2f),
                sprite.getY() + (sprite.getHeight() / 2f) - (game.texturesExplosion.get(0).getWidth() / 2f),
                game.texturesExplosion, game));
    }

    void draw() {
        sprite.draw(game.batch);
    }
}

Colisão BoundingBox

Implementação da colisão de retângulos.

	private boolean spriteCollide(Sprite a, Sprite b) {
		float x = a.getX();
		float y = a.getY();
		float w = a.getWidth();
		float h = a.getHeight();
		return pointCollide(x, y, b) ||
				pointCollide(x + w, y, b) ||
				pointCollide(x, y + h, b) ||
				pointCollide(x + w, y + h, b);
	}

	private boolean pointCollide(float px, float py, Sprite s) {
		float x = s.getX();
		float y = s.getY();
		float w = s.getWidth();
		float h = s.getHeight();
		return (px > x && px < x + w && py > y && py < y + h);
	}

Enemy.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.Texture;

public class Enemy extends Actor {
    static final int RIGHT = 0;
    static final int LEFT = 1;
    int direction;

    Enemy(Texture texture, MyGdxGame game) {
        super(game.rand.nextInt(game.w - texture.getWidth()), game.h + 100, texture, game);
        direction = game.rand.nextInt(2);
    }

    @Override
    void execute() {
        sprite.translateY(-5);
        if (direction == RIGHT) {
            sprite.translateX(5);
            if (sprite.getX() + sprite.getWidth() > game.w) {
                direction = LEFT;
            }
        } else {
            sprite.translateX(-5);
            if (sprite.getX() < 0) {
                direction = RIGHT;
            }
        }
        if (sprite.getY() + sprite.getHeight() < 0) {
            dead = true;
        }
    }
}

Ship.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.Gdx;
 4import com.badlogic.gdx.Input;
 5import com.badlogic.gdx.graphics.Texture;
 6
 7public class Ship extends Actor {
 8    Ship(float x, float y, Texture texture, MyGdxGame game) {
 9        super(x, y, texture, game);
10    }
11
12    @Override
13    void execute() {
14        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
15            sprite.translateX(-10);
16        } else if (Gdx.input.isKeyPressed((Input.Keys.RIGHT))) {
17            sprite.translateX(10);
18        }
19        if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
20            game.shot(
21                    sprite.getX() + (sprite.getWidth() / 2f),
22                    sprite.getY() + sprite.getHeight() + 2);
23        }
24        for (Actor a : game.actors) {
25            if (collide(a)) {
26                dead = true;
27                a.dead = true;
28                game.explosion(sprite.getX(), sprite.getY());
29                game.explosion(a.sprite.getX(), a.sprite.getY());
30                game.finished = true;
31            }
32        }
33    }
34}

Bomb.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.graphics.Texture;
 4
 5public class Bomb extends Actor {
 6    Bomb(float x, float y, Texture texture, MyGdxGame game) {
 7        super(x, y, texture, game);
 8        game.sndBomb.play();
 9    }
10
11    @Override
12    void execute() {
13        sprite.translateY(5);
14        if (sprite.getY() > game.h) dead = true;
15        for (Actor a : game.actors) {
16            if (collide(a) && a instanceof Enemy) {
17                dead = true;
18                a.dead = true;
19                game.explosion(a.sprite.getX(), a.sprite.getY());
20                game.score++;
21            }
22        }
23    }
24}

Explosion.java

 1package com.mygdx.game;
 2
 3import com.badlogic.gdx.graphics.Texture;
 4import com.badlogic.gdx.graphics.g2d.Sprite;
 5
 6import java.util.List;
 7
 8public class Explosion extends Actor {
 9    int position = 0;
10    int counter = 0;
11    int max = 3;
12    List<Texture> textures;
13    Sprite sprite;
14
15    Explosion(float x, float y, List<Texture> textures, MyGdxGame game) {
16        super(x, y, textures.get(0), game);
17        this.textures = textures;
18        sprite = new Sprite(textures.get(position));
19        sprite.setPosition(x, y);
20        game.sndExplosion.play();
21    }
22
23    @Override
24    void execute() {
25        counter++;
26        if (counter > max) {
27            position++;
28            counter = 0;
29        }
30        if (position >= textures.size()) {
31            dead = true;
32        }
33    }
34
35    @Override
36    void draw() {
37        if (dead) return;
38        sprite.setTexture(textures.get(position));
39        sprite.draw(game.batch);
40    }
41}

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.Texture;
 11import com.badlogic.gdx.graphics.g2d.BitmapFont;
 12import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 13
 14import java.util.ArrayList;
 15import java.util.List;
 16import java.util.Random;
 17
 18public class MyGdxGame extends ApplicationAdapter {
 19    SpriteBatch batch;
 20    Sound sndBomb;
 21    Sound sndExplosion;
 22    Music music;
 23    Texture background;
 24    Texture textureShip;
 25    Texture textureEnemy;
 26    Texture textureBomb;
 27    Texture texturePause;
 28    Texture textureGameOver;
 29    List<Texture> textureExplosions = new ArrayList<>();
 30    Background bk;
 31    BitmapFont font;
 32    List<Actor> actors = new ArrayList<>();
 33    List<Actor> news = new ArrayList<>();
 34    int w, h;
 35    Random rand = new Random();
 36    int enemyCounter = 0;
 37    int enemyMax = 50;
 38    int score;
 39    boolean gamePause = false;
 40    boolean isPlaying = true;
 41    boolean finished = false;
 42
 43    @Override
 44    public void create() {
 45        w = Gdx.graphics.getWidth();
 46        h = Gdx.graphics.getHeight();
 47        batch = new SpriteBatch();
 48
 49        background = new Texture("background.png");
 50        textureShip = new Texture("ship.png");
 51        textureEnemy = new Texture("enemy.png");
 52        textureBomb = new Texture("bomb.png");
 53        texturePause = new Texture("paused.png");
 54        textureGameOver = new Texture("gameover.png");
 55        textureExplosions.add(new Texture("explosion_0.png"));
 56        textureExplosions.add(new Texture("explosion_1.png"));
 57        textureExplosions.add(new Texture("explosion_2.png"));
 58        textureExplosions.add(new Texture("explosion_1.png"));
 59        textureExplosions.add(new Texture("explosion_0.png"));
 60        bk = new Background(background, this);
 61        actors.add(new Ship(
 62                w / 2f - textureShip.getWidth() / 2f, 10,
 63                textureShip, this));
 64        font = new BitmapFont(
 65                Gdx.files.internal("verdana.fnt"),
 66                Gdx.files.internal("verdana.png"), false);
 67        font.setColor(Color.BLACK);
 68        sndBomb = Gdx.audio.newSound(Gdx.files.internal("bomb.wav"));
 69        sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
 70        music = Gdx.audio.newMusic(Gdx.files.internal("music.ogg"));
 71        music.setLooping(true);
 72        music.play();
 73    }
 74
 75    public void execute() {
 76        if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
 77            Gdx.app.exit();
 78        } else if (Gdx.input.isKeyJustPressed(Input.Keys.M)) {
 79            if (music.isPlaying()) {
 80                music.stop();
 81                isPlaying = false;
 82            } else {
 83                music.play();
 84                isPlaying = true;
 85            }
 86        } else if (Gdx.input.isKeyJustPressed(Input.Keys.P)) {
 87            gamePause = !gamePause;
 88            if (gamePause) {
 89                music.stop();
 90            } else if (isPlaying) {
 91                music.play();
 92            }
 93        }
 94        if (finished) {
 95            if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) {
 96                finished = false;
 97                actors.clear();
 98                actors.add(new Ship(
 99                        w / 2f - textureShip.getWidth() / 2f, 10,
100                        textureShip, this));
101                score = 0;            }
102        }
103        bk.run();
104        for (Actor a : actors) a.run();
105        enemies();
106        clean();
107    }
108
109    @Override
110    public void render() {
111        execute();
112        Gdx.gl.glClearColor(1, 0, 0, 1);
113        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
114        batch.begin();
115        bk.draw(batch);
116        for (Actor a : actors) a.draw();
117        font.draw(batch, "SCORE: " + score, 1, h);
118        if (gamePause) {
119            batch.draw(texturePause,
120                    w / 2f - texturePause.getWidth() / 2f, h / 2f);
121        }
122        if (finished) {
123            batch.draw(textureGameOver,
124                    w / 2f - textureGameOver.getWidth() / 2f, h / 2f);
125        }
126        batch.end();
127    }
128
129    void enemies() {
130        if (gamePause) return;
131        enemyCounter++;
132        if (enemyCounter > enemyMax) {
133            actors.add(new Enemy(
134                    rand.nextInt(w - textureEnemy.getWidth()), h + 50,
135                    textureEnemy, this));
136            enemyCounter = 0;
137            enemyMax = 30 + rand.nextInt(50);
138        }
139    }
140
141    void shot(float x, float y) {
142        news.add(new Bomb(x - (textureBomb.getWidth() / 2f), y, textureBomb, this));
143    }
144
145    void explosion(float x, float y) {
146        news.add(new Explosion(x, y, textureExplosions, this));
147    }
148
149    void clean() {
150        List<Actor> aux = actors;
151        actors = new ArrayList<>();
152        for (Actor a : aux) if (!a.dead) actors.add(a);
153        actors.addAll(news);
154        news.clear();
155    }
156
157    @Override
158    public void dispose() {
159        background.dispose();
160        batch.dispose();
161    }
162}