كيفية إنشاء خريطة متجانبة في Java للعبة ثنائية الأبعاد؟

StackOverflow https://stackoverflow.com/questions/622832

  •  05-07-2019
  •  | 
  •  

سؤال

لست متأكدا من كيفية التعامل مع هذه المشكلة.

في الأساس، أريد تمثيل Pixel -> Tile لنافذة بحجم 400 × 400.كل إحداثيات على الشاشة، على سبيل المثال 120x300 يجب أن يكون جزءًا من البلاط.أصغر كائن لدي هو 4 بكسل، لذلك يمكننا القول أن 1 بلاطة = 4 بكسل.يبلغ حجم كل من اللاعب والعدو 20 × 20، لذا سيشغل كل لاعب/رجل سيء 5 قطع.

ثم أريد استخدام فئة الخريطة هذه من أجل:

  • قم باسترداد إحداثيات x/y لكائن اللاعب/الوحش عن طريق إضافة فهرس/معرف المربع.

  • معرفة مكان الحدود، بحيث لا يتحرك الكائن إلى ما هو أبعد من ذلك 400x400, ، وبالتالي إخفائها.

  • كشف التصادم ومعرفة إذا كانت البلاطة فارغة أم لا.

كيف يمكن القيام بذلك؟نتحدث على وجه التحديد عن تحويل x,y->tile أو Tile Index->x,y (لرسم النقوش المتحركة بشكل مناسب) هنا.

هل كانت مفيدة؟

المحلول

أولاً، قم بتقسيم مفهوم البكسل، الذي يهتم فقط بالتمثيل، مع البلاط، وهو كائن لعبة حقيقي مع قيود يضعها على اللعبة.

أجد طريقة جيدة لفك تشابك أشياء مثل هذه وهي البدء في رسم واجهة برمجة التطبيقات التقريبية لما تريد.شيء مثل:

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 )

حيث تكون جميع الوحدات الداخلية للوحة عبارة عن بلاطات وليس بكسلات.ومن ثم يمكن استخلاص معلومات البكسل من اللوحة بشكل مستقل عن تمثيل البلاط مع قليل من الضرب الداخلي-

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

يمكن تمثيل المربعات داخليًا كمصفوفة ثنائية الأبعاد أو مصفوفة واحدة، وفي هذه الحالة يمكنك استخدام نوع من نظام التمثيل الداخلي لتعيين المصفوفة الخاصة بك إلى مربعات اللوحة، وبالتالي حساب التعديل.

نصائح أخرى

اجابة قصيرة:عمليات الضرب وModulo.

ولكن إذا كان هذا الأمر يحيرك، فأنا أقترح عليك القيام بتجديد رياضي جدي قبل محاولة كتابة لعبة.

وكذلك بيانك

My smallest sprite is 4 pixels, so we can say that 1 tile = 4 pixels. The player and enemy sprites are all 20 x 20, so each player/bad guy will occupy 5 tiles.

لا يعمل مع أي هندسة معقولة.إذا كنت تقصد بـ "1 بلاطة = 4 بكسل" أن البلاطات هي 2×2، فإن اللاعب يأخذ 100، وليس خمسة.إذا كنت تقصد أنهم 4 × 4، فإن اللاعبين يأخذون 25، وهو ليس 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;
}

ربما ستحتاج إلى طرق تعمل على وسيطتين (x وy at) أيضًا.

بالنسبة لتحويل ID->قطعة والعكس، لديك طرق مختلفة متاحة.أي واحد للاختيار يعتمد على المتطلبات الدقيقة (السرعة، حجم اللعبة ...).لذا تأكد من إخفاء تفاصيل التنفيذ، حتى تتمكن من تغييرها لاحقًا.

سأبدأ بحل سهل حقيقي:

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

نأمل أن يحصل على انك بدأته.تتم كتابة كافة التعليمات البرمجية دون وجود مترجم قريب، لذلك ستتضمن الأخطاء المطبعية والأخطاء بالطبع، والتي قد يتم توزيعها بموجب ترخيص المشاع الإبداعي.

يجب أن يعمل أسلوب الاحتفاظ بالقطع في مجموعة بشكل جيد إذا لم يكن هناك العديد من القطع.يجب أن تعمل بشكل أفضل من المصفوفة ثنائية الأبعاد طالما أن معظم مساحة اللوحة لا تحتوي على قطعة.يفترض الأمر برمته حاليًا عدم وجود قطع متداخلة.إذا كنت بحاجة إلى تلك العناصر، فيجب على getPieceOnTile إرجاع مجموعة من القطع.مجموعة إذا كان الترتيب غير مهم، وقائمة إذا كان الأمر كذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top