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();
	}
}