Android Games: Skyfire

De Aulas
Revisão de 18h11min de 3 de novembro de 2022 por Admin (discussão | contribs) (→‎MyGdxGame.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

package com.mygdx.game;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;

public class Ship extends Actor {
    Ship(float x, float y, Texture texture, MyGdxGame game) {
        super(x, y, texture, game);
    }

    @Override
    void execute() {
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            sprite.setX(clamp(sprite.getX() - SPEED, 0, game.w));
        } else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            sprite.setX(clamp(sprite.getX() + SPEED, 0, game.w - sprite.getWidth()));
        }
        if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
            game.news.add(new Bomb(
                    sprite.getX() + (sprite.getWidth() / 2f) - (game.textureBomb.getWidth() / 2f),
                    sprite.getY() + sprite.getHeight(),
                    game.textureBomb, game));
            game.sndBomb.play();
        }
        for (Actor a : game.actor) {
            if (collide(a) && a instanceof Enemy) {
                a.explode();
                explode();
                game.gameOver = true;
                break;
            }
        }
    }
}

Bomb.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.Texture;

public class Bomb extends Actor {
    Bomb(float x, float y, Texture texture, MyGdxGame game) {
        super(x, y, texture, game);
    }

    @Override
    void execute() {
        sprite.translateY(5);
        if (sprite.getY() > game.h) dead = true;
        for (Actor a : game.actor) {
            if (collide(a) && a instanceof Enemy) {
                a.explode();
                dead = true;
                game.score++;
                break;
            }
        }
    }
}

Explosion.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.Texture;

import java.util.List;

class Explosion extends Actor {
    List<Texture> textures;
    int count = 0;
    int maxCount = 3;
    int position = 0;

    Explosion(float x, float y, List<Texture> textures, MyGdxGame game) {
        super(x, y, textures.get(0), game);
        this.textures = textures;
        game.sndExplosion.play();
    }

    @Override
    void execute() {
        count++;
        if (count > maxCount) {
            count = 0;
            position++;
        }
        if (position >= textures.size()) dead = true;
        else sprite.setTexture(textures.get(position));
    }
}

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.Texture;
 10import com.badlogic.gdx.graphics.g2d.BitmapFont;
 11import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 12
 13import java.util.ArrayList;
 14import java.util.List;
 15import java.util.Random;
 16
 17public class MyGdxGame extends ApplicationAdapter {
 18    SpriteBatch batch;
 19    Texture textureShip;
 20    Texture textureEnemy;
 21    Texture textureBomb;
 22    Texture textureGameOver;
 23    List<Texture> texturesExplosion = new ArrayList<>();
 24    int w, h;
 25    BackGround background;
 26    BitmapFont font;
 27    List<Actor> actor = new ArrayList<>();
 28    List<Actor> news = new ArrayList<>();
 29    Random rand = new Random();
 30    Sound sndBomb;
 31    Sound sndExplosion;
 32    Music music;
 33    boolean gameOver = false;
 34    int score = 0;
 35    int countEnemy = 0;
 36    int maxCountEnemy = 100;
 37
 38    @Override
 39    public void create() {
 40        w = Gdx.graphics.getWidth();
 41        h = Gdx.graphics.getHeight();
 42        batch = new SpriteBatch();
 43        background = new BackGround(new Texture("background.png"), this);
 44        textureShip = new Texture("ship.png");
 45        textureEnemy = new Texture("enemy.png");
 46        textureBomb = new Texture("bomb.png");
 47        textureGameOver = new Texture("gameover.png");
 48        texturesExplosion.add(new Texture("explosion_0.png"));
 49        texturesExplosion.add(new Texture("explosion_1.png"));
 50        texturesExplosion.add(new Texture("explosion_2.png"));
 51        texturesExplosion.add(new Texture("explosion_1.png"));
 52        texturesExplosion.add(new Texture("explosion_0.png"));
 53        sndBomb = Gdx.audio.newSound(Gdx.files.internal("bomb.wav"));
 54        sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
 55        music = Gdx.audio.newMusic(Gdx.files.internal("music.ogg"));
 56        music.setLooping(true);
 57        music.setVolume(0.7f);
 58        music.play();
 59        font = new BitmapFont(
 60                Gdx.files.internal("verdana.fnt"),
 61                Gdx.files.internal("verdana.png"), false);
 62        font.setColor(Color.BLACK);
 63        start();
 64    }
 65
 66    private void start() {
 67        gameOver = false;
 68        score = 0;
 69        actor.clear();
 70        news.clear();
 71        actor.add(new Ship((w / 2f) - (textureShip.getWidth() / 2f),
 72                10, textureShip, this));
 73    }
 74
 75    private void execute() {
 76        if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
 77            Gdx.app.exit();
 78        }
 79        if (gameOver) {
 80            if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) {
 81                start();
 82            }
 83        }
 84        for (Actor a : actor) a.execute();
 85        background.execute();
 86        stagehandWork();
 87    }
 88
 89    private void enemyGenerator() {
 90        countEnemy++;
 91        if (countEnemy > maxCountEnemy) {
 92            actor.add(new Enemy(textureEnemy, this));
 93            countEnemy = 0;
 94            maxCountEnemy = 20 + rand.nextInt(50);
 95        }
 96    }
 97
 98    private void stagehandWork() {
 99        enemyGenerator();
100        List<Actor> aux = actor;
101        actor = new ArrayList<>();
102        for (Actor a : aux) if (!a.dead) actor.add(a);
103        actor.addAll(news);
104        news.clear();
105    }
106
107    @Override
108    public void render() {
109        execute();
110        batch.begin();
111        background.draw();
112        for (Actor a : actor) a.draw();
113        font.draw(batch, "SCORE: " + score, 1, h);
114        if (gameOver) {
115            batch.draw(textureGameOver, (w / 2f) - (textureGameOver.getWidth() / 2f), 200);
116        }
117        batch.end();
118    }
119
120    @Override
121    public void dispose() {
122        batch.dispose();
123        background.dispose();
124        textureEnemy.dispose();
125        textureShip.dispose();
126        textureBomb.dispose();
127        font.dispose();
128    }
129}