Mudanças entre as edições de "Android Games: Skyfire"

De Aulas
 
(7 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 68: Linha 68:
 
= Actor.java =
 
= Actor.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
Linha 78: Linha 78:
 
     MyGdxGame game;
 
     MyGdxGame game;
 
     Sprite sprite;
 
     Sprite sprite;
 +
    int SPEED = 10;
 
     boolean dead = false;
 
     boolean dead = false;
  
Linha 87: Linha 88:
  
 
     void execute() {
 
     void execute() {
         // TO IMPLEMENT
+
         // To implement
 
     }
 
     }
  
     void run() {
+
     float clamp(float value, float min, float max) {
        if (game.gamePause) return;
 
        execute();
 
        sprite.setX(clamp(sprite.getX(), 0, game.w - sprite.getWidth()));
 
    }
 
 
 
    void draw() {
 
        sprite.draw(game.batch);
 
    }
 
 
 
    static float clamp(float value, float min, float max) {
 
 
         if (value < min) return min;
 
         if (value < min) return min;
 
         if (value > max) return max;
 
         if (value > max) return max;
Linha 110: Linha 101:
 
         return Intersector.overlaps(
 
         return Intersector.overlaps(
 
                 sprite.getBoundingRectangle(),
 
                 sprite.getBoundingRectangle(),
                 other.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);
 
     }
 
     }
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Linha 120: Linha 123:
 
Implementação da colisão de retângulos.
 
Implementação da colisão de retângulos.
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
private boolean spriteCollide(Sprite a, Sprite b) {
 
private boolean spriteCollide(Sprite a, Sprite b) {
 
float x = a.getX();
 
float x = a.getX();
Linha 143: Linha 146:
 
= Enemy.java =
 
= Enemy.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
Linha 153: Linha 156:
 
     int direction;
 
     int direction;
  
     Enemy(float x, float y, Texture texture, MyGdxGame game) {
+
     Enemy(Texture texture, MyGdxGame game) {
         super(x, y, texture, game);
+
         super(game.rand.nextInt(game.w - texture.getWidth()), game.h + 100, texture, game);
 
         direction = game.rand.nextInt(2);
 
         direction = game.rand.nextInt(2);
 
     }
 
     }
Linha 181: Linha 184:
 
= Ship.java =
 
= Ship.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
Linha 196: Linha 199:
 
     void execute() {
 
     void execute() {
 
         if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
 
         if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
             sprite.translateX(-10);
+
             sprite.setX(clamp(sprite.getX() - SPEED, 0, game.w));
         } else if (Gdx.input.isKeyPressed((Input.Keys.RIGHT))) {
+
         } else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
             sprite.translateX(10);
+
             sprite.setX(clamp(sprite.getX() + SPEED, 0, game.w - sprite.getWidth()));
 
         }
 
         }
 
         if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
 
         if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
             game.shot(
+
             game.news.add(new Bomb(
                     sprite.getX() + (sprite.getWidth() / 2f),
+
                     sprite.getX() + (sprite.getWidth() / 2f) - (game.textureBomb.getWidth() / 2f),
                     sprite.getY() + sprite.getHeight() + 2);
+
                     sprite.getY() + sprite.getHeight(),
 +
                    game.textureBomb, game));
 +
            game.sndBomb.play();
 
         }
 
         }
         for (Actor a : game.actors) {
+
         for (Actor a : game.actor) {
             if (collide(a)) {
+
             if (collide(a) && a instanceof Enemy) {
                dead = true;
+
                 a.explode();
                 a.dead = true;
+
                 explode();
                game.explosion(sprite.getX(), sprite.getY());
+
                 game.gameOver = true;
                 game.explosion(a.sprite.getX(), a.sprite.getY());
+
                break;
                 game.finished = true;
 
 
             }
 
             }
 
         }
 
         }
Linha 220: Linha 224:
 
= Bomb.java =
 
= Bomb.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
Linha 228: Linha 232:
 
     Bomb(float x, float y, Texture texture, MyGdxGame game) {
 
     Bomb(float x, float y, Texture texture, MyGdxGame game) {
 
         super(x, y, texture, game);
 
         super(x, y, texture, game);
        game.sndBomb.play();
 
 
     }
 
     }
  
Linha 235: Linha 238:
 
         sprite.translateY(5);
 
         sprite.translateY(5);
 
         if (sprite.getY() > game.h) dead = true;
 
         if (sprite.getY() > game.h) dead = true;
         for (Actor a : game.actors) {
+
         for (Actor a : game.actor) {
 
             if (collide(a) && a instanceof Enemy) {
 
             if (collide(a) && a instanceof Enemy) {
 +
                a.explode();
 
                 dead = true;
 
                 dead = true;
                a.dead = true;
 
                game.explosion(a.sprite.getX(), a.sprite.getY());
 
 
                 game.score++;
 
                 game.score++;
 +
                break;
 
             }
 
             }
 
         }
 
         }
Linha 249: Linha 252:
 
= Explosion.java =
 
= Explosion.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
 
import com.badlogic.gdx.graphics.Texture;
 
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
 
  
 
import java.util.List;
 
import java.util.List;
  
public class Explosion extends Actor {
+
class Explosion extends Actor {
 +
    List<Texture> textures;
 +
    int count = 0;
 +
    int maxCount = 3;
 
     int position = 0;
 
     int position = 0;
    int counter = 0;
 
    int max = 3;
 
    List<Texture> textures;
 
    Sprite sprite;
 
  
 
     Explosion(float x, float y, List<Texture> textures, MyGdxGame game) {
 
     Explosion(float x, float y, List<Texture> textures, MyGdxGame game) {
 
         super(x, y, textures.get(0), game);
 
         super(x, y, textures.get(0), game);
 
         this.textures = textures;
 
         this.textures = textures;
        sprite = new Sprite(textures.get(position));
 
        sprite.setPosition(x, y);
 
 
         game.sndExplosion.play();
 
         game.sndExplosion.play();
 
     }
 
     }
Linha 274: Linha 273:
 
     @Override
 
     @Override
 
     void execute() {
 
     void execute() {
         counter++;
+
         count++;
         if (counter > max) {
+
         if (count > maxCount) {
 +
            count = 0;
 
             position++;
 
             position++;
            counter = 0;
 
        }
 
        if (position >= textures.size()) {
 
            dead = true;
 
 
         }
 
         }
    }
+
         if (position >= textures.size()) dead = true;
 
+
         else sprite.setTexture(textures.get(position));
    @Override
 
    void draw() {
 
         if (dead) return;
 
         sprite.setTexture(textures.get(position));
 
        sprite.draw(game.batch);
 
 
     }
 
     }
 
}
 
}
Linha 295: Linha 286:
 
= MyGdxGame.java =
 
= MyGdxGame.java =
  
<syntaxhighlight lang=java line>
+
<syntaxhighlight lang=java>
 
package com.mygdx.game;
 
package com.mygdx.game;
  
Linha 304: Linha 295:
 
import com.badlogic.gdx.audio.Sound;
 
import com.badlogic.gdx.audio.Sound;
 
import com.badlogic.gdx.graphics.Color;
 
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
 
 
import com.badlogic.gdx.graphics.Texture;
 
import com.badlogic.gdx.graphics.Texture;
 
import com.badlogic.gdx.graphics.g2d.BitmapFont;
 
import com.badlogic.gdx.graphics.g2d.BitmapFont;
Linha 315: Linha 305:
 
public class MyGdxGame extends ApplicationAdapter {
 
public class MyGdxGame extends ApplicationAdapter {
 
     SpriteBatch batch;
 
     SpriteBatch batch;
    Sound sndBomb;
 
    Sound sndExplosion;
 
    Music music;
 
    Texture background;
 
 
     Texture textureShip;
 
     Texture textureShip;
 
     Texture textureEnemy;
 
     Texture textureEnemy;
 
     Texture textureBomb;
 
     Texture textureBomb;
    Texture texturePause;
 
 
     Texture textureGameOver;
 
     Texture textureGameOver;
     List<Texture> textureExplosions = new ArrayList<>();
+
     List<Texture> texturesExplosion = new ArrayList<>();
     Background bk;
+
     int w, h;
 +
    BackGround background;
 
     BitmapFont font;
 
     BitmapFont font;
     List<Actor> actors = new ArrayList<>();
+
     List<Actor> actor = new ArrayList<>();
 
     List<Actor> news = new ArrayList<>();
 
     List<Actor> news = new ArrayList<>();
    int w, h;
 
 
     Random rand = new Random();
 
     Random rand = new Random();
     int enemyCounter = 0;
+
     Sound sndBomb;
     int enemyMax = 50;
+
     Sound sndExplosion;
     int score;
+
     Music music;
     boolean gamePause = false;
+
     boolean gameOver = false;
     boolean isPlaying = true;
+
     int score = 0;
     boolean finished = false;
+
    int countEnemy = 0;
 +
     int maxCountEnemy = 100;
  
 
     @Override
 
     @Override
Linha 343: Linha 329:
 
         h = Gdx.graphics.getHeight();
 
         h = Gdx.graphics.getHeight();
 
         batch = new SpriteBatch();
 
         batch = new SpriteBatch();
 
+
         background = new BackGround(new Texture("background.png"), this);
         background = new Texture("background.png");
 
 
         textureShip = new Texture("ship.png");
 
         textureShip = new Texture("ship.png");
 
         textureEnemy = new Texture("enemy.png");
 
         textureEnemy = new Texture("enemy.png");
 
         textureBomb = new Texture("bomb.png");
 
         textureBomb = new Texture("bomb.png");
        texturePause = new Texture("paused.png");
 
 
         textureGameOver = new Texture("gameover.png");
 
         textureGameOver = new Texture("gameover.png");
         textureExplosions.add(new Texture("explosion_0.png"));
+
         texturesExplosion.add(new Texture("explosion_0.png"));
         textureExplosions.add(new Texture("explosion_1.png"));
+
         texturesExplosion.add(new Texture("explosion_1.png"));
         textureExplosions.add(new Texture("explosion_2.png"));
+
         texturesExplosion.add(new Texture("explosion_2.png"));
         textureExplosions.add(new Texture("explosion_1.png"));
+
         texturesExplosion.add(new Texture("explosion_1.png"));
         textureExplosions.add(new Texture("explosion_0.png"));
+
         texturesExplosion.add(new Texture("explosion_0.png"));
        bk = new Background(background, this);
 
        actors.add(new Ship(
 
                w / 2f - textureShip.getWidth() / 2f, 10,
 
                textureShip, this));
 
        font = new BitmapFont(
 
                Gdx.files.internal("verdana.fnt"),
 
                Gdx.files.internal("verdana.png"), false);
 
        font.setColor(Color.BLACK);
 
 
         sndBomb = Gdx.audio.newSound(Gdx.files.internal("bomb.wav"));
 
         sndBomb = Gdx.audio.newSound(Gdx.files.internal("bomb.wav"));
 
         sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
 
         sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
 
         music = Gdx.audio.newMusic(Gdx.files.internal("music.ogg"));
 
         music = Gdx.audio.newMusic(Gdx.files.internal("music.ogg"));
 
         music.setLooping(true);
 
         music.setLooping(true);
 +
        music.setVolume(0.7f);
 
         music.play();
 
         music.play();
 +
        font = new BitmapFont(
 +
                Gdx.files.internal("verdana.fnt"),
 +
                Gdx.files.internal("verdana.png"), false);
 +
        font.setColor(Color.BLACK);
 +
        start();
 
     }
 
     }
  
     public void execute() {
+
     private void start() {
 +
        gameOver = false;
 +
        score = 0;
 +
        actor.clear();
 +
        news.clear();
 +
        actor.add(new Ship((w / 2f) - (textureShip.getWidth() / 2f),
 +
                10, textureShip, this));
 +
    }
 +
 
 +
    private void execute() {
 
         if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
 
         if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
 
             Gdx.app.exit();
 
             Gdx.app.exit();
         } else if (Gdx.input.isKeyJustPressed(Input.Keys.M)) {
+
         }
            if (music.isPlaying()) {
+
        if (gameOver) {
                music.stop();
+
             if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) {
                isPlaying = false;
+
                 start();
             } else {
 
                music.play();
 
                isPlaying = true;
 
            }
 
        } else if (Gdx.input.isKeyJustPressed(Input.Keys.P)) {
 
            gamePause = !gamePause;
 
            if (gamePause) {
 
                music.stop();
 
            } else if (isPlaying) {
 
                 music.play();
 
 
             }
 
             }
 
         }
 
         }
         if (finished) {
+
         for (Actor a : actor) a.execute();
            if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) {
+
        background.execute();
                finished = false;
+
        stagehandWork();
                actors.clear();
+
    }
                actors.add(new Ship(
+
 
                        w / 2f - textureShip.getWidth() / 2f, 10,
+
    private void enemyGenerator() {
                        textureShip, this));
+
        countEnemy++;
                score = 0;           }
+
        if (countEnemy > maxCountEnemy) {
 +
            actor.add(new Enemy(textureEnemy, this));
 +
            countEnemy = 0;
 +
            maxCountEnemy = 20 + rand.nextInt(50);
 
         }
 
         }
         bk.run();
+
    }
         for (Actor a : actors) a.run();
+
 
         enemies();
+
    private void stagehandWork() {
         clean();
+
         enemyGenerator();
 +
        List<Actor> aux = actor;
 +
        actor = new ArrayList<>();
 +
         for (Actor a : aux) if (!a.dead) actor.add(a);
 +
         actor.addAll(news);
 +
         news.clear();
 
     }
 
     }
  
Linha 407: Linha 396:
 
     public void render() {
 
     public void render() {
 
         execute();
 
         execute();
        Gdx.gl.glClearColor(1, 0, 0, 1);
 
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
 
 
         batch.begin();
 
         batch.begin();
         bk.draw(batch);
+
         background.draw();
         for (Actor a : actors) a.draw();
+
         for (Actor a : actor) a.draw();
 
         font.draw(batch, "SCORE: " + score, 1, h);
 
         font.draw(batch, "SCORE: " + score, 1, h);
         if (gamePause) {
+
         if (gameOver) {
             batch.draw(texturePause,
+
             batch.draw(textureGameOver, (w / 2f) - (textureGameOver.getWidth() / 2f), 200);
                    w / 2f - texturePause.getWidth() / 2f, h / 2f);
 
        }
 
        if (finished) {
 
            batch.draw(textureGameOver,
 
                    w / 2f - textureGameOver.getWidth() / 2f, h / 2f);
 
 
         }
 
         }
 
         batch.end();
 
         batch.end();
    }
 
 
    void enemies() {
 
        if (gamePause) return;
 
        enemyCounter++;
 
        if (enemyCounter > enemyMax) {
 
            actors.add(new Enemy(
 
                    rand.nextInt(w - textureEnemy.getWidth()), h + 50,
 
                    textureEnemy, this));
 
            enemyCounter = 0;
 
            enemyMax = 30 + rand.nextInt(50);
 
        }
 
    }
 
 
    void shot(float x, float y) {
 
        news.add(new Bomb(x - (textureBomb.getWidth() / 2f), y, textureBomb, this));
 
    }
 
 
    void explosion(float x, float y) {
 
        news.add(new Explosion(x, y, textureExplosions, this));
 
    }
 
 
    void clean() {
 
        List<Actor> aux = actors;
 
        actors = new ArrayList<>();
 
        for (Actor a : aux) if (!a.dead) actors.add(a);
 
        actors.addAll(news);
 
        news.clear();
 
 
     }
 
     }
  
 
     @Override
 
     @Override
 
     public void dispose() {
 
     public void dispose() {
 +
        batch.dispose();
 
         background.dispose();
 
         background.dispose();
         batch.dispose();
+
         textureEnemy.dispose();
 +
        textureShip.dispose();
 +
        textureBomb.dispose();
 +
        font.dispose();
 
     }
 
     }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Edição atual tal como às 18h11min de 3 de novembro de 2022

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

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MyGdxGame extends ApplicationAdapter {
    SpriteBatch batch;
    Texture textureShip;
    Texture textureEnemy;
    Texture textureBomb;
    Texture textureGameOver;
    List<Texture> texturesExplosion = new ArrayList<>();
    int w, h;
    BackGround background;
    BitmapFont font;
    List<Actor> actor = new ArrayList<>();
    List<Actor> news = new ArrayList<>();
    Random rand = new Random();
    Sound sndBomb;
    Sound sndExplosion;
    Music music;
    boolean gameOver = false;
    int score = 0;
    int countEnemy = 0;
    int maxCountEnemy = 100;

    @Override
    public void create() {
        w = Gdx.graphics.getWidth();
        h = Gdx.graphics.getHeight();
        batch = new SpriteBatch();
        background = new BackGround(new Texture("background.png"), this);
        textureShip = new Texture("ship.png");
        textureEnemy = new Texture("enemy.png");
        textureBomb = new Texture("bomb.png");
        textureGameOver = new Texture("gameover.png");
        texturesExplosion.add(new Texture("explosion_0.png"));
        texturesExplosion.add(new Texture("explosion_1.png"));
        texturesExplosion.add(new Texture("explosion_2.png"));
        texturesExplosion.add(new Texture("explosion_1.png"));
        texturesExplosion.add(new Texture("explosion_0.png"));
        sndBomb = Gdx.audio.newSound(Gdx.files.internal("bomb.wav"));
        sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
        music = Gdx.audio.newMusic(Gdx.files.internal("music.ogg"));
        music.setLooping(true);
        music.setVolume(0.7f);
        music.play();
        font = new BitmapFont(
                Gdx.files.internal("verdana.fnt"),
                Gdx.files.internal("verdana.png"), false);
        font.setColor(Color.BLACK);
        start();
    }

    private void start() {
        gameOver = false;
        score = 0;
        actor.clear();
        news.clear();
        actor.add(new Ship((w / 2f) - (textureShip.getWidth() / 2f),
                10, textureShip, this));
    }

    private void execute() {
        if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
            Gdx.app.exit();
        }
        if (gameOver) {
            if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) {
                start();
            }
        }
        for (Actor a : actor) a.execute();
        background.execute();
        stagehandWork();
    }

    private void enemyGenerator() {
        countEnemy++;
        if (countEnemy > maxCountEnemy) {
            actor.add(new Enemy(textureEnemy, this));
            countEnemy = 0;
            maxCountEnemy = 20 + rand.nextInt(50);
        }
    }

    private void stagehandWork() {
        enemyGenerator();
        List<Actor> aux = actor;
        actor = new ArrayList<>();
        for (Actor a : aux) if (!a.dead) actor.add(a);
        actor.addAll(news);
        news.clear();
    }

    @Override
    public void render() {
        execute();
        batch.begin();
        background.draw();
        for (Actor a : actor) a.draw();
        font.draw(batch, "SCORE: " + score, 1, h);
        if (gameOver) {
            batch.draw(textureGameOver, (w / 2f) - (textureGameOver.getWidth() / 2f), 200);
        }
        batch.end();
    }

    @Override
    public void dispose() {
        batch.dispose();
        background.dispose();
        textureEnemy.dispose();
        textureShip.dispose();
        textureBomb.dispose();
        font.dispose();
    }
}