Space Invaders kolizje

0

W celu poduczenia się java próbuje zrobić sobie grę z kursu space invaders. Nie trzymam się tego kursu w 100%, staram się na jego podstawie zrobić grę Tank. Mój problem polega na tym że "sciana" w którą zostanie wystrzelony pocisk nie reaguje, lub reaguje dopiero po pewnym czasie. Poniżej kod programu:
KlasaGłowna"

public class Wojna extends Canvas implements Stage, KeyListener {
	private static final long serialVersionUID = 7037479338593065179L;
	public long usedTime;
	public BufferStrategy strategia;
	private SpriteCache spriteCache;
	private ArrayList<Actor> actors;
	private ArrayList<Blok> blok;

	private Player player;
	private Map map = new Map(this);

	public Wojna() {
		spriteCache = new SpriteCache();
		JFrame okno = new JFrame(".: Gra:.");
		JPanel panel = (JPanel) okno.getContentPane();
		setBounds(0, 0, Stage.W, Stage.H);
		panel.setPreferredSize(new Dimension(Stage.W, Stage.H));
		panel.setLayout(null);
		panel.add(this);

		okno.setBounds(0, 0, Stage.W, Stage.H);
		okno.setVisible(true);
		okno.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		okno.setResizable(false);
		createBufferStrategy(2);
		strategia = getBufferStrategy();
		requestFocus();
		addKeyListener(this);
	}

	public void keyPressed(KeyEvent e) {
		player.keyPressed(e);
	}

	public void keyReleased(KeyEvent e) {
		player.keyReleased(e);
	}

	public void keyTyped(KeyEvent e) {
	}

	public void initWorld() {
		actors = new ArrayList<Actor>();
		blok = new ArrayList<Blok>();
		map.rysuj();

		for (int i = 0; i < 6; i++) {
			Monster m = new Monster(this);
			m.setX((int) (Math.random() * Stage.W - 60));
			m.setY(i * 20);
			m.setVx((int) (Math.random() * 3) + 1);
			actors.add(m);
		}
		player = new Player(this);
		player.setX(Stage.W / 2);
		player.setY(Stage.H - 2 * player.getHeight());

	}

	public void paintWorld() {
		Graphics2D g = (Graphics2D) strategia.getDrawGraphics();
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, getWidth(), getHeight());
		for (int i = 0; i < blok.size(); i++) {
			Blok b = (Blok) blok.get(i);
			b.paint(g);
		}
		for (int i = 0; i < actors.size(); i++) {
			Actor m = (Actor) actors.get(i);
			m.paint(g);
		}
		player.paint(g);
		g.setColor(Color.RED);
		if (usedTime > 0)
			g.drawString(String.valueOf(1000 / usedTime) + "fps", 0,
					Stage.H - 50);
		else
			g.drawString("--- fps", 5, Stage.H - 50);
		;

		strategia.show();

	}

	public void addActor(Actor a) {
		actors.add(a);

	}

	public void updateWorld() {
		int i = 0;
		while (i < actors.size()) {
			Actor m = (Actor) actors.get(i);
			if (m.isMarkedForRemoval()) {
				actors.remove(i);
			} else {
				m.act();

				i++;
			}
		}
		while (i < blok.size()) {
			Blok b = (Blok) blok.get(i);
			if (b.isMarkedForRemoval()) {
				blok.remove(i);
			} else {
				i++;
			}
		}
		player.act();
	}

	public SpriteCache getSpriteCache() {
		return spriteCache;

	}

	public void checkCollisions() {
		Rectangle playerBounds = player.getBounds();
		for (int i = 0; i < actors.size(); i++) {
			Actor a1 = (Actor) actors.get(i);
			Rectangle r1 = a1.getBounds();
			if (r1.intersects(playerBounds)) {
				player.collision(a1);
				a1.collision(player);
			}
			for (int j = i + 1; j < actors.size(); j++) {
				Actor a2 = (Actor) actors.get(j);
				Rectangle r2 = a2.getBounds();
				if (r1.intersects(r2)) {
					a1.collision(a2);
					a2.collision(a1);
				}
				for (int k = 0; k < blok.size(); k++) {
					Blok b1 = (Blok) blok.get(k);
					Rectangle r3 = b1.getBounds();
					if (r1.intersects(r3)) {
						a1.collision(b1);
						b1.collision(a1);
					}

				}

			}
		}
	}

	public void game() {
		usedTime = 1000;
		initWorld();
		while (isVisible()) {
			long startTime = System.currentTimeMillis();
			updateWorld();
			checkCollisions();
			paintWorld();
			usedTime = System.currentTimeMillis() - startTime;
			do {
				Thread.yield();
			} while (System.currentTimeMillis() - startTime < 15);
		}
	}

	public static void main(String[] args) {
		Wojna inv = new Wojna();
		inv.game();

	}

	public void addBlok(Blok b) {
		blok.add(b);

	}

}

KlasaBlok
<code= java>package Stage;

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

import Actor.Actor;
import Core.SpriteCache;
import Core.Stage;

public class Blok {
protected int x, y;
protected int w, h;
protected String spriteName;
protected Stage stage;
protected SpriteCache spriteCache;

public Blok(Stage stage) {
	this.stage = stage;
	spriteCache = stage.getSpriteCache();

}

public Rectangle getBounds() {
	return new Rectangle(x, y, w, h);
}

public void collision(Blok a) {
}

protected boolean markedForRemoval;

public void remove() {
	markedForRemoval = true;
}

public boolean isMarkedForRemoval() {
	return markedForRemoval;
}


public void paint(Graphics2D g) {
	g.drawImage(spriteCache.getSprite(spriteName, 0), x, y,
			stage);
}

public int getX() {
	return x;
}

public void setX(int i) {
	x = i;
}

public int getY() {
	return y;
}

public void setY(int i) {
	y = i;
}

public void setSpriteName(String name, int sP) {

	spriteName = name;
	h = 0;
	w = 0;
	for (int i = 0; i < sP; i++) {
		BufferedImage image = spriteCache.getSprite(spriteName, i);
		h = Math.max(h, image.getHeight());
		w = Math.max(w, image.getWidth());
	}
}

public int getHeight() {
	return h;
}

public int getWidth() {
	return w;
}

public void setHeight(int i) {
	h = i;
}

public void setWidth(int i) {
	w = i;
}

public void act() {

}

public void collision(Actor a) {

	
}

}

KlasaActor:
```java
public class Actor {
	protected int x, y;
	protected int w, h;
	protected String spriteName;
	protected Stage stage;
	protected SpriteCache spriteCache;
	protected int currentFrame;
	protected String[] spriteNames;
	protected int frameSpeed;
	protected int t;
	int sP;

	public Actor(Stage stage) {
		this.stage = stage;
		spriteCache = stage.getSpriteCache();
		frameSpeed = 1;
		t = 0;

	}

	public Rectangle getBounds() {
		return new Rectangle(x, y, w, h);
	}

	public void collision(Actor a) {
	}

	protected boolean markedForRemoval;

	public void remove() {
		markedForRemoval = true;
	}

	public boolean isMarkedForRemoval() {
		return markedForRemoval;
	}

	public int getFrameSpeed() {
		return frameSpeed;
	}

	public void setFrameSpeed(int i) {
		frameSpeed = i;
	}

	public void paint(Graphics2D g) {
		g.drawImage(spriteCache.getSprite(spriteName, currentFrame, w,h), x, y,
				stage);
	}

	public int getX() {
		return x;
	}

	public void setX(int i) {
		x = i;
	}

	public int getY() {
		return y;
	}

	public void setY(int i) {
		y = i;
	}

	public void setSpriteName(String name, int sP, int w,int h) {
		this.sP = sP;
		spriteName = name;
		this.h = h;
		this.w = w;
		for (int i = 0; i < sP; i++) {
			BufferedImage image = spriteCache.getSprite(spriteName, i,w,h);
			h = Math.max(h, image.getHeight());
			w = Math.max(w, image.getWidth());
		}
	}

	public int getHeight() {
		return h;
	}

	public int getWidth() {
		return w;
	}

	public void setHeight(int i) {
		h = i;
	}

	public void setWidth(int i) {
		w = i;
	}

	public void act() {
		t++;
		if (t % frameSpeed == 0) {
			t = 0;
			currentFrame = (currentFrame + 1) % sP;
		}
	}

	public void collision(Blok b) {
		// TODO Auto-generated method stub
		
	}
}

KlasaPocisk

 
public class Bullet extends Actor {
	protected static final int BULLET_SPEED = 10;

	public Bullet(Stage stage) {
		super(stage);
		setSpriteName("r.jpg",1,10,30);
	}

	public void act() {
		super.act();
		y -= BULLET_SPEED;
		if (y < 0)
			remove();
	}
	public void collision(Actor a) {
		if (a instanceof Monster)
			remove();

	}
	public void collision(Blok b) {
		if (b instanceof Beton)
			remove();

	}
}
0

Spowolniłem trochę grę, teraz usuwa bloki po prawej stronie ekranu bez problemu. Zauważyłem również że jeśli wybije wszystkie latające stworki ściany usuwają się bez problemu.
Jeszcze raz wstawiam klase blok

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

import Actor.Actor;
import Core.SpriteCache;
import Core.Stage;

public class Blok {
	protected int x, y;
	protected int w, h;
	protected String spriteName;
	protected Stage stage;
	protected SpriteCache spriteCache;
	protected int HP, frameHP;

	public Blok(Stage stage) {
		this.stage = stage;
		spriteCache = stage.getSpriteCache();

	}

	public Rectangle getBounds() {
		return new Rectangle(x, y, w, h);
	}

	public void collision(Blok a) {
	}

	protected boolean markedForRemoval;

	public void remove() {
		markedForRemoval = true;
	}

	public boolean isMarkedForRemoval() {
		return markedForRemoval;
	}
	private int frameHP(){
		if(HP > 0){
			frameHP = HP - 1;
		}
		else{frameHP = 0;}
		return frameHP;
	}
	
	

	public void paint(Graphics2D g) {
		
		g.drawImage(spriteCache.getSprite(spriteName, frameHP()), x, y,
				stage);
	}

	public int getHP() {
		return HP;
	}

	public void setHP(int hP) {
		HP = hP;
	}

	public int getX() {
		return x;
	}

	public void setX(int i) {
		x = i;
	}

	public int getY() {
		return y;
	}

	public void setY(int i) {
		y = i;
	}

	public void setSpriteName(String name, int sP) {

		spriteName = name;
		h = 0;
		w = 0;
		for (int i = 0; i < sP; i++) {
			BufferedImage image = spriteCache.getSprite(spriteName, i);
			h = Math.max(h, image.getHeight());
			w = Math.max(w, image.getWidth());
		}
	}

	public int getHeight() {
		return h;
	}

	public int getWidth() {
		return w;
	}

	public void setHeight(int i) {
		h = i;
	}

	public void setWidth(int i) {
		w = i;
	}



	public void collision(Actor a) {

		
	}
}

KlasaMapa:
package Stage;

import Actor.Monster;
import Core.SpriteCache;
import Core.Stage;

public class Map {
	protected Stage stage;

	public int mapa[][] = new int[12][16];
	protected String spriteName;
	protected SpriteCache spriteCache;
	protected int x, y;

	public Map(Stage stage) {
		this.stage = stage;
		spriteCache = stage.getSpriteCache();

	}

	public void plansza() {
		int mapa1[][] = { 
				{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
				{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
		for (int i = 0; i < mapa.length; i++) {
			for (int j = 0; j < mapa[0].length; j++) {
				mapa[i][j] = mapa1[i][j];

			}
		}
	}

	public void rysuj() {
		plansza();
		for (int i = 0; i < mapa.length; i++) {
			for (int j = 0; j < mapa[0].length; j++) {
				y = i * 50;
				x = j * 50;
				switch (mapa[i][j]) {
				case 0:
					break;
				case 1:
					Beton b = new Beton(stage);
					b.setX(x);
					b.setY(y);
					b.setHP(3);
					stage.addBlok(b);

					break;
				case 2:
					Monster m = new Monster(stage);
					m.setX(x);
					m.setY(y);
					m.setVx(5);
					stage.addActor(m);
					break;
				}

			}
		}

	}

}
0

Kolejne spostrzeżenie, nie usuwa się tyle bloków ile jest aktualnie stworków na ekranie. Przykład: lata sobie 6 "potworków" 6 bloków nie mogę usunąć.
Ale jeśli te bloki uszkodzę, a następnie zabije stworki bloki będą się razem z nimi usuwały.
Zmieniłem trochę pętle w checkCollisions

	public void checkCollisions() {
		Rectangle playerBounds = player.getBounds();
		for (int i = 0; i < actors.size(); i++) {
			Actor a1 = (Actor) actors.get(i);
			Rectangle r1 = a1.getBounds();
			if (r1.intersects(playerBounds)) {
				player.collision(a1);
				a1.collision(player);
			}
			for (int j = i + 1; j < actors.size(); j++) {
				Actor a2 = (Actor) actors.get(j);
				Rectangle r2 = a2.getBounds();
				if (r1.intersects(r2)) {
					a1.collision(a2);
					a2.collision(a1);
				}

			}
		}
		for (int i = 0; i < actors.size(); i++) {
			for (int k = 0; k < blok.size(); k++) {
				Actor a1 = (Actor) actors.get(i);
				Rectangle r1 = a1.getBounds();
				Blok b1 = (Blok) blok.get(k);
				Rectangle r3 = b1.getBounds();
				if (r1.intersects(r3)) {
					a1.collision(b1);
					b1.collision(a1);
				}

			}
		}
	}
0

Nie trudź się. Wstawiłeś 500 linijek kodu, nie podając konkretnego pytania i fragmentu z którym masz problem. Nikt nie tknie tego nawet kijem przez szmatę.

0

Problem jest w tym że nie wiem w czym jest problem. Część bloków daje się zniszczyć dopiero po zabiciu stworków. Nie wiem która część kodu powoduje ten problem.

Edit:
Naprawione, problem siedział w metodzie updateWorld w pętli użyłem jednej zmiennej 'i" dla potworków i bloków.

1 użytkowników online, w tym zalogowanych: 0, gości: 1