Android Games: The Tank
De Aulas
Links relacionados: Jogos Digitais
Recursos
Vector2D.java
package com.mygdx.game;
class Vector2D {
private double x;
private double y;
Vector2D() {
x = 0.0f;
y = 0.0f;
}
Vector2D(double x, double y) {
this.x = x;
this.y = y;
}
// Retorna o tamanho do vetor
static double grad2radians(double grad) {
return (grad / 180) * Math.PI;
}
// Soma dois vetores e retorna um terceiro
public static double radians2grad(double radians) {
return (radians * 180) / Math.PI;
}
// Soma o atual vetor com os valores de um outro
double size() {
return Math.sqrt((x * x) + (y * y));
}
public Vector2D sum(Vector2D a, Vector2D b) {
return new Vector2D(a.getX() + b.getX(), a.getY() + b.getY());
}
void sumTo(Vector2D other) {
x += other.getX();
y += other.getY();
}
public Vector2D multiply(double value) {
return new Vector2D(x * value, y * value);
}
public void multiplyTo(double value) {
x *= value;
y *= value;
}
// Normaliza o vetor, transformando seu tamanho para 1
public Vector2D divide(double value) {
return new Vector2D(x / value, y / value);
}
// Angulos
private void divideBy(double value) {
x /= value;
y /= value;
}
public void normalize() {
divideBy(size());
}
public Vector2D bySizeAndAngle(double size, double angle) {
return new Vector2D(Math.cos(size) * size, Math.sin(size) * size);
}
void rotate(double angle) {
// Executa as operações de sin e cos apenas uma vez,
// economizando processamento.
double s = Math.sin(angle);
double c = Math.cos(angle);
double newX = (x * c) - (y * s);
double newY = (x * s) + (y * c);
x = newX;
y = newY;
}
private double dot(Vector2D other) {
return (x * other.x) + (y * other.y);
}
public double angleBetween(Vector2D other) {
double dp = dot(other);
if (dp >= 1.0) {
dp = 1.0f;
} else if (dp <= -1.0) {
dp = -1.0f;
}
double angPi = (float) Math.acos(dp);
return dot(other) > 0 ? -angPi : angPi;
}
double getX() {
return x;
}
void setX(double x) {
this.x = x;
}
double getY() {
return y;
}
void setY(double y) {
this.y = y;
}
}
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.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import java.util.Locale;
public class MyGdxGame extends ApplicationAdapter {
private final int canePosX = 26;
private final int groundPosY = 100;
private SpriteBatch batch;
private Sprite ball;
private Sprite tank;
private Sprite cane;
private Texture background;
private BitmapFont verdana;
private Vector2D vecBall;
private Vector2D vecGravity;
private Vector2D vecWind;
private Sound sndShoot;
private Sound sndExplosion;
private double force;
private boolean shooting;
@Override
public void create() {
batch = new SpriteBatch();
sndExplosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav"));
sndShoot = Gdx.audio.newSound(Gdx.files.internal("shoot.wav"));
verdana = new BitmapFont(Gdx.files.internal("verdana.fnt"), false);
verdana.setColor(0, 0, 0, 1);
background = new Texture("background.png");
tank = new Sprite(new Texture("tank.png"));
tank.setPosition(100, groundPosY);
cane = new Sprite(new Texture("cane.png"));
cane.setPosition(100 + canePosX, groundPosY + 18);
cane.setOrigin(0, 1);
ball = new Sprite(new Texture("ball.png"));
ball.setPosition(0, groundPosY);
force = 20.0f;
vecBall = new Vector2D(0.0f, force);
vecGravity = new Vector2D(0.0f, -0.98f);
vecWind = new Vector2D(0.0f, 0.0f);
shooting = false;
}
private void execute() {
if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) {
Gdx.app.exit();
}
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
tank.setX(tank.getX() + 1);
} else if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
tank.setX(tank.getX() - 1);
}
if (Gdx.input.isKeyJustPressed(Input.Keys.MINUS)) {
force--;
} else if (Gdx.input.isKeyJustPressed(Input.Keys.EQUALS)) {
force++;
}
if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
if (cane.getRotation() < 90) cane.rotate(0.5f);
} else if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
if (cane.getRotation() > 0) cane.rotate(-0.5f);
}
if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_UP)) {
vecWind.setX(vecWind.getX() + 0.01f);
} else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_DOWN)) {
vecWind.setX(vecWind.getX() - 0.01f);
}
if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) {
if (!shooting) {
shooting = true;
ball.setPosition(cane.getX(), cane.getY());
vecBall.setX(force);
vecBall.setY(0.0f);
vecBall.rotate(Vector2D.grad2radians(cane.getRotation()));
sndShoot.play();
}
}
cane.setX(tank.getX() + canePosX);
if (shooting) {
vecBall.sumTo(vecGravity);
vecBall.sumTo(vecWind);
ball.setX(ball.getX() + (float) vecBall.getX());
ball.setY(ball.getY() + (float) vecBall.getY());
if (ball.getY() <= groundPosY) {
shooting = false;
ball.setY(groundPosY);
sndExplosion.play();
}
}
}
@Override
public void render() {
execute();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(background, 0, 0);
verdana.draw(batch, "Angle: "
+ String.format(Locale.US, "%.0f", cane.getRotation()), 5, 480);
verdana.draw(batch, "Force: "
+ String.format(Locale.US, "%.0f", force), 5, 450);
verdana.draw(batch, "Wind : "
+ String.format(Locale.US, "%.0f", (vecWind.getX()) * 100), 4, 420);
ball.draw(batch);
cane.draw(batch);
tank.draw(batch);
batch.end();
sleep(20);
}
private void sleep(int timer) {
try {
Thread.sleep(timer);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void dispose() {
batch.dispose();
ball.getTexture().dispose();
tank.getTexture().dispose();
cane.getTexture().dispose();
}
}