Salve. Sto provando a programmare un giochino in java (per ora un applet) senza utilizzare particolari librerie, java puro. Ho difficoltà nell'implementare una semplice collision detection per la quale sto utilizzando l'oggetto Rectangle2D.
In generale la situazione è questa: c'è un'arena divisa in celle, dove ogni cella (grande 32x32) può essere vuota, contenere un nemico oppure il personaggio principale. Se si fa click con il mouse su
di un nemico allora si spara un proiettile verso di esso. Il proiettile deve svanire se si scontra con un
ostacolo interposto tra il nemico ed il pg principale oppure ovviamente se va a segno al nemico.
Il problema è che appena sparo un proiettile viene rilevata immediatamente una collisione e di fatto non parte alcun proiettile, perché una volta rilevata la collisione vado a rimuovere il proiettile dalla lista dei proiettili presenti in scena (possono essere sparati a raffica e devo controllarli tutti).
Ogni oggetto del modello dati implementa il metodo:
codice:
public Rectangle2D getBounds() {
return new Rectangle2D.Double(x, y, DIAMETER, DIAMETER);
}
per ottenere il rettangolo che lo contiene.
Esempio, ostacolo:
codice:
package model;
import java.awt.geom.Rectangle2D;
public class Obstacle {
private float x;
private float y;
private static final int DIAMETER = 32;
public Obstacle(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public Rectangle2D getBounds() {
return new Rectangle2D.Double(x, y, DIAMETER, DIAMETER);
}
}
Questa è la logica di sparo e movimento:
codice:
public class ArenaController {
private Arena arena;
/** selected cell for movement */
private float targetX, targetY;
/** true if droid is moving */
private boolean moving = false;
/** true if droid is shooting to enemy */
private boolean shooting = false;
private DroidController droidController;
public ArenaController(Arena arena) {
this.arena = arena;
this.droidController = new DroidController(arena);
}
public void update(float delta) {
Droid droid = arena.getDroid();
//droid movements
if (moving) {
droidController.moveDroid(delta, targetX, targetY);
//check if arrived
if (droid.getX() == targetX && droid.getY() == targetY)
moving = false;
}
//meccanismo di sparo
if(shooting) {
//se non ci sono proiettili non si sta sparando
if(arena.getBullets().isEmpty()) {
shooting = false;
}
//scorro tutti i proiettili sparati ancora presenti
for(int i = 0; i < arena.getBullets().size(); i++) {
//proiettile corrente
Bullet bullet = arena.getBullets().get(i);
//calcolo angolo
double angle = Math.atan2(bullet.getEnemyY() - bullet.getY(), bullet.getEnemyX() - bullet.getX());
//aggiornamento delle coordinate per spostare il proiettile
bullet.setX((float) (bullet.getX() + (Math.cos(angle) * bullet.getSpeed() * delta)));
bullet.setY((float) (bullet.getY() + (Math.sin(angle) * bullet.getSpeed() * delta)));
//per ogni proiettile controllo se si è scontrato
//con uno degli ostacoli presenti nell'arena
for(int j = 0; j < arena.getObstacles().size(); j++) {
Obstacle obs = arena.getObstacles().get(j);
if(obs.getBounds().contains(bullet.getBounds())) {
arena.removeBullet(bullet);
}
}
//per ogni proiettile controllo se si è scontrato
//con uno dei nemici della scena
for(int j = 0; j < arena.getEnemies().size(); j++) {
Enemy ene = arena.getEnemies().get(j);
if(ene.getBounds().contains(bullet.getBounds())) {
arena.removeBullet(bullet);
}
}
}
}
}
public boolean onClick(int x, int y) {
//click on empty cell
if(arena.getGrid()[(int)(y / Arena.TILE)][(int)(x / Arena.TILE)] == null) {
//coordinates
targetX = x / Arena.TILE;
targetY = y / Arena.TILE;
//enables movement
moving = true;
return true;
}
//click on enemy: fire
if(arena.getGrid()[(int)(y / Arena.TILE)][(int)(x / Arena.TILE)] instanceof Enemy) {
//coordinates
float enemyX = x / Arena.TILE;
float enemyY = y / Arena.TILE;
//new bullet
Bullet bullet = new Bullet();
//start coordinates
bullet.setX(arena.getDroid().getX());
bullet.setY(arena.getDroid().getY());
//end coordinates (enemie)
bullet.setEnemyX(enemyX);
bullet.setEnemyY(enemyY);
//adds bullet to arena
arena.addBullet(bullet);
//enables shooting
shooting = true;
return true;
}
return false;
}
}
Insomma come mai mi rileva subito una collisione ed il proiettile non fa a tempo a partire che è già stato eliminato? Spero di ricevere un piccolo aiuto.