Advertisement

Tanks2D 2Player Turn Basic

Started by May 14, 2014 07:03 PM
1 comment, last by fdauria 10 years, 8 months ago
It is very difficult to get sprite sheet: (

Stage.java

package juego;

import java.awt.image.ImageObserver;

public interface Stage extends ImageObserver {
	public static final int WIDTH	= 800;
	public static final int HEIGHT	= 544;
	public static final int PLAY_HEIGHT	= 544;
	
	public SpriteCache getSpriteCache();
	public SoundCache getSoundCache();
	
	public void addBala(Actor a);
	public void terminarTurno();
	public void gameOver();
}
Main.java


package juego;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.Transparency;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends Canvas implements Stage, KeyListener{
	private BufferStrategy strategy;
	private SpriteCache spriteCache;
	private SoundCache soundCache;
	
	private int segundos;
	private int turno = 0;
	private ArrayList jugadores;
	private ArrayList bala;
	
	private long usedTime; //Fps
	
	private boolean gameEnded = false;
	private BufferedImage background, backgroundTile;;
	
	public Main(){
		spriteCache = new SpriteCache();
		soundCache	= new SoundCache();
		
		JFrame ventana  = new JFrame("Guerra de tanques");
		JPanel panel	= (JPanel) ventana.getContentPane();
		setBounds(0,0,Stage.WIDTH,Stage.HEIGHT);
		panel.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT));
		//panel.setBackground(Color.black);
		panel.setLayout(null);
		panel.add(this);
		
		ventana.setBounds(0, 0, Stage.WIDTH, Stage.HEIGHT);
		ventana.setVisible(true);
		 
		ventana.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		ventana.setResizable(false);
		
		createBufferStrategy(2);
		strategy = getBufferStrategy(); 
		
		requestFocus();
		addKeyListener(this);
		setIgnoreRepaint(true);
	}
	
	public static void main(String[] args){
		
		final Main main = new Main();
				
		Thread thread1 = new Thread () {
		  public void run () {
			  main.PlayGame();
		  }
		};
		
		Thread thread2 = new Thread () {
		  public void run () {
			  main.empezarContador();
		  }
		};
		thread1.start();
		thread2.start();	
	}
	
	public class Tarea extends Thread{
		public Tarea(String str){
			super(str);
		}
	}
	
	public void PlayGame(){
		usedTime = 1000;
		initWorld();
		while(isVisible() && !gameEnded && !jugadores.isEmpty()){
			long startTime = System.currentTimeMillis();
			updateWorld();
			checkCollisions();
			paintWorld();
			usedTime = System.currentTimeMillis() - startTime;
			do{
				Thread.yield();
			}while(System.currentTimeMillis() - startTime < 17);								
		}
		
		paintGameOver();
	}
	
	public void initWorld(){
		jugadores = new ArrayList();
		for(int i = 1; i <= 2; i++){
			Jugador j = new Jugador(this);
			j.setY(Stage.HEIGHT - 200);
			j.setX((int)(Math.random() * Stage.WIDTH) );
			jugadores.add(j);
		}
		
		bala = new ArrayList();
		
		backgroundTile = spriteCache.getSprite("fondo.jpg");
		background = spriteCache.createCompatible(Stage.WIDTH,Stage.HEIGHT+backgroundTile.getHeight(),Transparency.OPAQUE);
		Graphics2D g = (Graphics2D)background.getGraphics();
		g.setPaint( new TexturePaint( backgroundTile,new Rectangle(0,0,backgroundTile.getWidth(),backgroundTile.getHeight())));
		g.fillRect(0,0,background.getWidth(),background.getHeight());
	}
	
	public void updateWorld(){
		for(int i = 0; i< jugadores.size(); i++){
			Jugador j = (Jugador)jugadores.get(i);
			
			if(j.isMarkedForRemoval()){
				jugadores.remove(i);
			}else{
				j.act();
			}
		}
		
		if(!bala.isEmpty()){
			Bala b = (Bala)bala.get(0);
			b.act();
		}
	}
	
	public void paintWorld(){
		Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
		
		g.drawImage(background, 0, 0, Stage.WIDTH, Stage.HEIGHT, 0, 0, Stage.WIDTH, Stage.HEIGHT, this);
		//g.setColor(Color.black);
		//g.fillRect(0, 0, Stage.WIDTH, Stage.HEIGHT);
		
		for(int i = 0; i< jugadores.size(); i++){
			Jugador j = (Jugador)jugadores.get(i);
			j.paint(g);
		}
		
		if(!bala.isEmpty()){
			Bala b = (Bala)bala.get(0);
			b.paint(g);
		}
		
		paintStatus(g);
		
		strategy.show();
	}

	public void paintStatus(Graphics2D g){
		paintOptions(g);
		paintShields(g);
	}
	
	public void paintOptions(Graphics2D g){
		Jugador j = (Jugador) jugadores.get(turno);
		g.setFont(new Font("Arial",Font.BOLD,30));
		g.setPaint(Color.white);
		g.drawString("Angulo: " + j.getAngleBala()  , 0 , 30);
		
		g.setFont(new Font("Arial",Font.BOLD,30));
		g.setPaint(Color.white);
		g.drawString("Speed: " + j.getSpeedBala()  , 0 , 60);
		
		g.setFont(new Font("Arial",Font.BOLD,30));
		g.setPaint(Color.white);
		g.drawString("" + segundos , Stage.WIDTH / 2 , 30);
	}
	
	public void paintShields(Graphics2D g){
			Jugador j1 = (Jugador) jugadores.get(0);
			g.setPaint(Color.red);
			g.fillRect(100, Stage.PLAY_HEIGHT, j1.MAX_SHIELDS, 100);
			g.setPaint(Color.blue);
			g.fillRect(10 + j1.MAX_SHIELDS-j1.getShields(), Stage.PLAY_HEIGHT-60, j1.getShields(), 20);

			Jugador j2 = (Jugador) jugadores.get(1);
			g.setPaint(Color.red);
			g.fillRect(100, Stage.PLAY_HEIGHT, j2.MAX_SHIELDS, 100);
			g.setPaint(Color.blue);
			g.fillRect(Stage.WIDTH - 20 - j2.MAX_SHIELDS , Stage.PLAY_HEIGHT-60, j2.getShields(), 20);			
		}

	public void paintGameOver(){
		Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,Stage.WIDTH,Stage.HEIGHT);
		
		g.setFont( new Font("Arial",Font.BOLD,36));
		g.setColor(Color.white);
		g.drawString("Perdiste",10 ,Stage.HEIGHT -40);
		strategy.show();
	}
	
	public void addBala(Actor a) {
		bala.add(a);	
	}	
	
	public void checkCollisions(){
		if(!bala.isEmpty()){
			Bala b = (Bala)bala.get(0);
			Rectangle balaBounds = b.getBounds();
			
			for(int i = 0; i < jugadores.size(); i++){
				Actor a1 = (Actor)jugadores.get(i);
				Rectangle r1 = a1.getBounds();
				if(r1.intersects(balaBounds)){
					b.collision(a1);
					a1.collision(b);
				}
			}
		}
	}	
	
	public void keyPressed(KeyEvent e) {
		Jugador j = (Jugador) jugadores.get(turno);
		j.keyPressed(e);
	}
	
	public void keyReleased(KeyEvent e) {
		Jugador j = (Jugador) jugadores.get(turno);
		j.keyReleased(e);
	}
	
	public void keyTyped(KeyEvent arg0) {}

	public SpriteCache getSpriteCache() {
		return spriteCache;
	}

	public SoundCache getSoundCache() {
		return soundCache;
	}	
	
	public void empezarContador(){
		for(segundos = 30; segundos > 0; segundos--){
			System.out.println(segundos);
			delaySegundo();
		}	
		
		changeTurno();	
		
		empezarContador();
		
	}
	
	private static void delaySegundo(){
		try{
			Thread.sleep(1000);
		}catch(InterruptedException e){}
	}
	
	public void terminarTurno(){
		bala.clear();
		changeTurno();
	}
	
	public void changeTurno(){
		if(!jugadores.isEmpty()){
			Jugador j = (Jugador) jugadores.get(turno);
			j.setVx(0);
			
			if(turno < jugadores.size())
				turno++;
			if(turno == jugadores.size())
				turno = 0;
			
			segundos = 30;
		}
	}

	public void gameOver() {
		gameEnded = true;		
	}
}

Actor.java


package juego;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

public class Actor {
	protected int x , y;
	protected int width, height;
	protected String [] spriteNames;
	protected int currentFrame;
	
	protected int frameSpeed;
	protected int t;
	
	protected Stage stage;
	protected SpriteCache spriteCache;
	protected boolean markedForRemoval;
	
	public Actor(Stage stage){
		this.stage 	 = stage;
		spriteCache  = stage.getSpriteCache();
		currentFrame = 0;
		frameSpeed 	 = 1;
		t = 0;		
	}
	
	public void paint(Graphics2D g){
		g.drawImage(spriteCache.getSprite(spriteNames[currentFrame]),x,y,stage);
	}

	public void remove(){
		markedForRemoval = true;
	}
	
	public boolean isMarkedForRemoval(){
		return markedForRemoval;
	}	
	
	public int getX() {	return x; }
	public void setX(int x) { this.x = x;}
	
	public int getY() {	return y; }
	public void setY(int y) { this.y = y; }
	
	public int getWidth() {	return width; }
	public void setWidth(int width) { this.width = width;}
	
	public int getHeight() { return height; }
	public void setHeight(int height) {	this.height = height; }	
	
    public int getFrameSpeed() {return frameSpeed;  }
    public void setFrameSpeed(int i) { frameSpeed = i; }	
    
	public void setSpriteNames(String[] names){
		spriteNames = names;
		height	= 0;
		width	= 0;
		for(int i = 0; i < names.length; i++){
			BufferedImage image = spriteCache.getSprite(spriteNames[i]);
			height	= Math.max(height,image.getHeight());
			width	= Math.max(width,image.getWidth());			
		}
	}   
	
	public Rectangle getBounds(){
		return new Rectangle(x,y,width,height);
	}

	public void collision(Actor a){	
		
		
	}
	
	public void act(){ 
		t++;
		if(t % frameSpeed == 0){
			t = 0;			
			currentFrame = (currentFrame + 1) % spriteNames.length;
		}
	}
}

Jugador.java


package juego;

import java.awt.event.KeyEvent;

public class Jugador extends Actor{
	public static final int MAX_SHIELDS = 200;
	protected int vx;
	private boolean left  = false;
	private boolean right = false;
	private boolean izq = false;
	private boolean der = false;
	private int speed 	  = 3;
	
	private int shields;	
	
	private double angleBala = 5;
	private int speedBala = 10;
	
	public Jugador(Stage stage){
		super(stage);
		setSpriteNames(new String[]{ "tanque.gif" });
		shields = MAX_SHIELDS;
	}
	
	public void act(){
		super.act();
		
		x += vx;
		
		if(x < 0)
			x = 0;
		if(x > Stage.WIDTH - getWidth())
			x = Stage.WIDTH - getWidth();
	}
	
	public void updateSpeed(){
		vx = 0;
		if(left) vx = -speed;
		if(right) vx = speed;
	}
	
	public void keyPressed(KeyEvent e){
		switch(e.getKeyCode()){
			case KeyEvent.VK_LEFT: 
				left = true;
				izq = true;
				der = false;
				break;
			case KeyEvent.VK_RIGHT:
				right = true;
				izq = false;
				der = true;
				break;
			case KeyEvent.VK_SPACE:
				fire();
				break;	
			case KeyEvent.VK_UP: 
				if(angleBala < 90)
					angleBala +=5;
				break;	
			case KeyEvent.VK_DOWN: 
				if(angleBala > 0)
					angleBala-=5;
				break;
			case KeyEvent.VK_X:
				if(speedBala < 20)
					speedBala ++;
				break;
			case KeyEvent.VK_Z: 
				if(speedBala > 6)
					speedBala --;
				break;
	
		}	
		updateSpeed();
	}
	
	public void keyReleased(KeyEvent e){
		switch(e.getKeyCode()){
			case KeyEvent.VK_LEFT: 
				left = false;
				break;
			case KeyEvent.VK_RIGHT:
				right = false;
				break;
					
		}	
		updateSpeed();
	}
	
	public void fire(){
		Bala b = new Bala(stage);
		b.setX(b.getWidth() + x);
		b.setY(y - b.getHeight());
		b.setSpeed(speedBala);
		b.setAngle(angleBala);
		b.applyFriction();
		b.setRight(der);
		b.setLeft(izq);
		stage.addBala(b);
	}
	
	public void collision(Actor a){
		if(a instanceof Bala){
			addShields(-40);
			stage.terminarTurno();
		}
		
		if(getShields() <= 0)
			stage.gameOver();

	}	
	
	public int getVx() {
		return vx;
	}

	public void setVx(int vx) {
		this.vx = vx;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public double getAngleBala() {
		return angleBala;
	}

	public void setAngleBala(float angleBala) {
		this.angleBala = angleBala;
	}

	public int getSpeedBala() {
		return speedBala;
	}

	public void setSpeedBala(int speedBala) {
		this.speedBala = speedBala;
	}

	public int getShields() {
		return shields;
	}

	public void setShields(int shields) {
		this.shields = shields;
	}
	
	public void addShields(int i){
		shields += i;
		if(shields > MAX_SHIELDS) shields = MAX_SHIELDS;
	}	
}

Bala.java


package juego;

public class Bala extends Actor{
	private double angle;
	private int speed;
	
	private float vx;
	private float vy;
	private float gravity = 0.5f;
	private boolean left;
	private boolean right;

	public void applyFriction(){
		float radians = (float)((angle / 180) * Math.PI )*-1;
		vx = (float) (speed * Math.cos(radians));
		vy = (float) (speed * Math.sin(radians));
	}
	
	public Bala(Stage stage) {
		super(stage);
		setSpriteNames(new String[] {"bala.gif"});
	}
	
	public void act(){
		super.act();
		
		if(left)
			x -= vx;
		
		if(right)
			x += vx;
		
		vy += gravity;
		y += vy;
		
		System.out.println("X: " + x + " Y: " + y);
		if(x < 0 || x > Stage.WIDTH || y > Stage.HEIGHT - 100){
			stage.terminarTurno();
		}
	}	


	public double getAngle() {
		return angle;
	}
  
	public void setAngle(double angle) {
		this.angle = angle;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public boolean isLeft() {
		return left;
	}

	public void setLeft(boolean left) {
		this.left = left;
	}

	public boolean isRight() {
		return right;
	}

	public void setRight(boolean right) {
		this.right = right;
	}	
	
}

ResourceCache.java


package juego;

import java.net.URL;
import java.util.HashMap;

public abstract class ResourceCache {
	@SuppressWarnings("rawtypes")
	protected HashMap resources;
	
	@SuppressWarnings("rawtypes")
	public ResourceCache(){
		resources = new HashMap();
	}
	
	protected Object loadResource(String name){
		URL url = null;
		url = getClass().getClassLoader().getResource(name);
		return loadResource(url);
	}
	
	@SuppressWarnings("unchecked")
	protected Object getResource(String name){
		Object res = resources.get(name);
		if(res == null){
			res = loadResource("res/" + name);
			resources.put(name, res);
		}
		return res;
	}
	
	protected abstract Object loadResource(URL url);
}

SoundCache.java


package juego;

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundCache extends ResourceCache{
	
	protected Object loadResource(URL url) {
		return Applet.newAudioClip(url);
	}
	
	public AudioClip getAudioClip(String name){
		return (AudioClip) getResource(name);
	}
	
	public void playSound(final String name){
		new Thread(
			new Runnable() {
				public void run() {
					getAudioClip(name).play();					
				}
			}
		).start();
	}
	
	public void loopSound(final String name){
		new Thread(
			new Runnable() {
				public void run() {
					getAudioClip(name).loop();
				}
			}
		).start();
	}
	
	public void stopSound(final String name){
		getAudioClip(name).stop();
	}

}

SpriteCache.java


package juego;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.net.URL;


import javax.imageio.ImageIO;

public class SpriteCache extends ResourceCache implements ImageObserver{
	
	protected Object loadResource(URL url){
		try{
			return ImageIO.read(url);
		}catch(Exception e){
			System.out.println("No se pudo cargar la imagen de " + url);
			System.out.println("El error fue: " + e.getClass().getName() + " " + e.getMessage());
			System.out.println(0);
			return null;
		}
	}
	
	public BufferedImage getSprite(String name){
		return (BufferedImage) getResource(name);
	}

	public BufferedImage createCompatible(int width, int height, int transparency){
		GraphicsConfiguration gc = 
				GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
		BufferedImage compatible = gc.createCompatibleImage(width, height, transparency);
		return compatible;
	}
	
	public boolean imageUpdate(Image img, int infoflags, int x, int y,int width, int height) {
		return (infoflags & (ALLBITS|ABORT)) == 0;
	}	
}

You should be clearer with the problem you have. What should be happening? What happend instead?

Also, you didn't share the "SpriteCache" code, SoundCache is duplicated. I think no one will be able to help you with sprites without that class.

And an advise... I wouldn't mix spanish and english words in your code, sounds like a bad idea that will confuse you at some point.

Advertisement
I have no problem, just shared the code, the program is running

thanks you also

This topic is closed to new replies.

Advertisement