Domanda

Non sono sicuro di come affrontare questo problema.

Fondamentalmente, voglio un Pixel - > Rappresentazione di piastrelle di una finestra 400x400. Ogni coordinata sullo schermo, ad esempio 120x300 dovrebbe far parte di una tessera. Il mio sprite più piccolo è di 4 pixel, quindi possiamo dire che 1 riquadro = 4 pixel. Il giocatore e gli sprite nemici sono tutti 20 x 20, quindi ogni giocatore / cattivo occuperà 5 tessere.

Quindi voglio usare questa classe Map per:

  • Recupera le coordinate x / y di uno sprite di un giocatore / mostro supplicando l'indice / ID della tessera.

  • Sapere dove sono i confini, quindi non sposta lo sprite oltre 400x400 , nascondendolo così.

  • Rilevamento delle collisioni, sapendo se una tessera è libera o meno.

Come si può fare? Parlando specificamente della conversione x, y- > tile o tile index- > x, y (per disegnare gli sprite in modo appropriato) qui.

È stato utile?

Soluzione

In primo luogo, dividi il concetto di pixel, che riguarda solo la rappresentazione, con una tessera, che è un vero oggetto di gioco con vincoli che pone sul gioco.

Trovo che un buon modo per districare cose come questa sia iniziare a delineare l'API approssimativa di ciò che vuoi. Qualcosa del tipo:

public class Board {
  public Board (int width, int height){.. }
  public boolean isOccupied(int x, int y){.. }
  public void moveTo(Point from, Point to) { .. 
    (maybe throws an exception for outofbounds )

dove tutte le unità interne della scheda sono in riquadri, non in pixel. Quindi le informazioni sui pixel possono essere derivate dalla scheda indipendentemente dalla rappresentazione della piastrella con un po 'di moltiplicazione interna-

  public Point getPixelPosition(int xTilePos, int yTilePos, int pixelsPerTile)..

I riquadri possono essere rappresentati internamente come un array 2d o un singolo array, nel qual caso useresti un qualche tipo di schema di rappresentazione interna per mappare il tuo array ai quadrati della scheda, quindi l'aritmetica mod.

Altri suggerimenti

Risposta breve: operazioni di moltiplicazione e modulo.

Ma se questo ti stordisce, ti suggerirei di fare un serio aggiornamento di matematica prima di provare a scrivere un gioco.

Anche la tua dichiarazione

  

Il mio sprite più piccolo è di 4 pixel, quindi noi   posso dire che 1 riquadro = 4 pixel. Il   gli sprite del giocatore e del nemico sono tutti 20 x   20, quindi ogni giocatore / cattivo occuperà   5 tessere.

non funziona per nessuna geometria ragionevole. Se entro " 1 riquadro = 4 pixel " intendi che le tessere sono 2x2, quindi un giocatore ne prende 100, non cinque. Se vuoi dire che sono 4x4, i giocatori ne prendono 25, che comunque non è 5.

/** size of a tile in pixel (for one dimension)*/
int TILE_SIZE_IN_PIXEL = 4;
/** size of a piece in tiles (for one dimension)*/
int PIECE_SIZE_IN_TILE = 5;


public int tileToPixel(int positionInTiles){
    return TILE_SIZE_IN_PIXEL * positionInTiles;
}

/** returns the tile coordinate to which the given tile coordinate belongs 

Note: tileToPixel(pixelToTile(x)) only returns x if x is the upper or left edge of a tile
*/
public int pixelToTile(int positionInPixel){
    return positionInPixel / TILE_SIZE_IN_PIXEL;
}

Probabilmente vorrai che i metodi operino anche su due argomenti (xey su).

Per la conversione ID- > pezzo e viceversa hai vari approcci disponibili. Quale scegliere dipende dai requisiti esatti (velocità, dimensioni del gioco ...). Quindi assicurati di nascondere i dettagli di implementazione, in modo da poterli modificare in seguito.

Comincerei con una soluzione davvero semplice:

public class Piece{
    /** x position measured in tiles */
    private int x;
    /** y position measured in tiles */
    private int y;

    /** I don't think you need this, but you asked for it. I'd pass around Piece instances instead */
    private final  Long id;

    public void getX(){
        return x;
    }
    public void getY(){
        return y;
    }

    public void getID(){
        return id;
    }

}

public class Board(){
    private Set<Long,Piece> pieces = new HashMap<Piece>(pieces);

    public Piece getPieceOnTile(int tileX, int tileY){ 
        for(Piece piece:pieces){
             if (isPieceOnTile(piece, tileX, tileY)) return piece;
        }
    }

    private boolean isPieceOnTile(piece, tileX, tileY){
        if (piece.getX() < tileX) return false;
        if (piece.getX() > tileX + PIECE_SIZE_IN_TILE) return false;

        if (piece.getY() < tileY) return false;
        if (piece.getY() > tileY + PIECE_SIZE_IN_TILE) return false;

        return true;
    }
}

Spero che ti inizi. Tutto il codice è scritto senza un compilatore nelle vicinanze, quindi includerà errori di battitura e, naturalmente, bug, che possono essere distribuiti con la licenza creative commons.

L'approccio di mantenere i pezzi in un set dovrebbe funzionare bene se non ci sono molti pezzi. Dovrebbe funzionare meglio di un array 2D purché la maggior parte dell'area della scheda non contenga un pezzo. Il tutto attualmente presuppone che non ci siano pezzi sovrapposti. Se hai bisogno di questi getPieceOnTile devi restituire una raccolta di pezzi. Un set se l'ordine non ha importanza, un elenco se lo fa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top