Плитка исчезает в предыдущей позиции после "установки" - PullRequest
0 голосов
/ 28 июня 2011

Я создаю редактор карт для небольшого игрового проекта, который я делаю. Учитывая, что редактор карт не будет интенсивным, я просто использовал Java 2D, который я ненавижу. В любом случае, вот мой map.java, tile.java и мой код TileList.java.

ИСПРАВЛЕНО, я изменил свой код TileList.java (функция set) следующим образом: Хорошо, я исправил это: я просто изменил функцию set (плитка Tile)!

public void set(Tile tile) {
    for(int i = 0; i < this.tileList.length; i++) {
        int x = this.tileList[i].getX();
        int y = this.tileList[i].getY();
        if((x == tile.getX()) && (y == tile.getY())) {
            System.out.println("Changing tile: (" + x + "," + y + ")" + " with (" + tile.getX() + "," + tile.getY() + ")");
            this.tileList[i].setImage(tile.getImage());
        }
    }
}

Ошибка отображения изображения: http://i.imgur.com/eosPt.png

map.java:

package org.naive.gui.impl;

import org.naive.util.TileList;

import javax.swing.JPanel;
import java.util.HashMap;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.Rectangle;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * Copyright 2011 Fellixombc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class Map extends JPanel implements MouseListener {

    private final int tileSize;
    private final int mapSize;
    private final int size;
    private TileList tileSet;
    private Tile currentTile = null;

    /* Creates the Map, e.g, Panel
     * @param int Desired size (in tiles) of the map
     */
    public Map(int size, int tileSize) {
        this.tileSize = tileSize / 2;
        this.size = size;
        this.mapSize = (this.tileSize)*(size/2);
        this.tileSet = new TileList(size/2 * size/2);
        properties();
    }

    /* Initlize the properties for the JPanel
     */
    public void properties() {
        this.setPreferredSize(new Dimension(mapSize, mapSize));
        this.addMouseListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D gfx = (Graphics2D) g;
        for(int i = 0; i < this.tileSet.size; i++) {
            Tile tile = this.tileSet.get(i);
            gfx.drawImage(tile.getImage(), tile.getX(), tile.getY(), null);
        }
        for(int i = 0; i <= size/2; i++) {
            gfx.setColor(Color.BLACK);
            gfx.drawLine(i * this.tileSize, 0, i * this.tileSize, this.tileSize * this.size/2);
            gfx.drawLine(0, i * this.tileSize, this.tileSize * this.size/2, i * this.tileSize);
        }
    }

    public void populate() {
        int i = 0;
        for(int x = 0; x < size/2; x++) {
            for(int y = 0; y < size/2; y++) {
                Tile tile = new Tile("grass.png");
                tile.setPos(x * this.tileSize, y * this.tileSize);
                this.tileSet.setAtIndex(i, tile);
                i++;
            }
        }
    }

    /* Sets a new tile
     * @param tile The *new* tile to be set
     */
    public void setTile(Tile tile) {
        if(this.currentTile != null) {
            tile.setPos(this.currentTile.getX(), this.currentTile.getY());
            this.tileSet.set(tile);
            this.currentTile = tile;
        }
        this.repaint();
    }

    /* Gets the tile closest* to the mouse click
     * @param int The x-axis location of the mouse click
     * @param2 int The y-axis location of the mouse click
     */
    public void getTile(int x, int y) {
        for(int i = 0; i < this.tileSet.size; i++) {
            Tile tile = this.tileSet.get(i);
            int minX = tile.getX();
            int minY = tile.getY();
            int maxX = minX + this.tileSize;
            int maxY = minY + this.tileSize;

            if((x >= minX) && (x < maxX) && (y >= minY) && (y < maxY)) {
                this.currentTile = tile;
                System.out.println("Tile at: " + "(" + this.currentTile.getX() + "," + this.currentTile.getY() + ")");
            }
        }
    }


    public void setTileSet(TileList tileSet) {
        this.tileSet = tileSet;
    }

    /* Gets the TileList, e.g, the tiles of the 'map'
     * @return hashmap Returns the list of tiles
     */
    public TileList getTileSet() {
        return this.tileSet;
    }

    public int getMapSize() {
        return this.size;
    }

    public int getTileSize() {
        return this.tileSize * 2;
    }


    /* Gets where the mouse clicked on the canvas
     * @param mouseevent Where the mouse event occurred
     */
    public void mouseClicked(MouseEvent e) {
        this.getTile(e.getX(), e.getY());
    }

    /* Useless..
     */
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
}

Tile.java

package org.naive.gui.impl;

import javax.swing.ImageIcon;

/**
 * Copyright 2011 Fellixombc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class Tile extends ImageIcon {

    private int x = 0;
    private int y = 0;
    private final String sprite;

    public Tile(String sprite) {
        super("data/sprite/" + sprite);
        this.sprite = sprite;
    }

    public String getSprite() {
        return this.sprite;
    }

    public void setPos(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

}

TileList.java пакет org.naive.util;

import org.naive.gui.impl.Tile;

import java.util.Iterator;

/**
 * Copyright 2011 Fellixombc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class TileList {

    public int size;
    private Tile[] tileList;

    public TileList(int size) {
        this.size = size;
        this.tileList = new Tile[size];
    }

    public void setAtIndex(int index, Tile tile) {
        this.tileList[index] = tile;
    }

    public void set(Tile tile) {
        for(int i = 0; i < this.tileList.length; i++) {
            int x = this.tileList[i].getX();
            int y = this.tileList[i].getY();
            if((x == tile.getX()) && (y == tile.getY())) {
                System.out.println("Changing tile: (" + x + "," + y + ")" + " with (" + tile.getX() + "," + tile.getY() + ")");
                this.tileList[i] = tile;
            }
        }
    }

    public Tile get(int index) {
        return this.tileList[index];
    }
}

Ответы [ 2 ]

0 голосов
/ 28 июня 2011

Я думаю, что проблема в том, что вы передаете новый (и, вероятно, временный) объект Tile при вызове setTile. Таким образом, когда вы редактируете / изменяете другую плитку, этот временный объект перезаписывается новым объектом плитки, а старый удаляется. Один из способов убедиться в этом - отредактировать третью плитку, а первые две, которые вы изменили, исчезнут.

Как правило, редакторы плиток (и на самом деле игры на основе плиток) не изменяют объект плиток, они просто меняют свойства этого объекта на новые значения при изменении ситуации. Это имеет много преимуществ, в основном связанных с затратами на создание нового объекта. Итак, в этом редакторе карт вы должны передать новое значение спрайта (вместе с любыми другими вещами, которые могут измениться) вместо создания нового объекта плитки для каждого редактирования.

Вы также можете создать массив (или карту, или список, или что-то), который содержит свойства каждого типа плитки, и просто передать значение, указывающее на индекс этого массива. Я мог бы написать какой-нибудь псевдокод для любого из этих решений, если вам нужно.

0 голосов
/ 28 июня 2011

Одна вещь, которая может помочь сделать немного более понятным, что именно происходит и также более эффективно в вашем коде, - это устранить цикл внутри этой функции:

public void set(Tile tile) {
    for(int i = 0; i < this.tileList.length; i++) {
        int x = this.tileList[i].getX();
        int y = this.tileList[i].getY();
        if((x == tile.getX()) && (y == tile.getY())) {
            System.out.println("Changing tile: (" + x + "," + y + ")" + " with (" + tile.getX() + "," + tile.getY() + ")");
            this.tileList[i] = tile;
        }
    }
}

Теперь я бы порекомендовал сделать что-тов соответствии с этим:

public void set(Tile tile)
{
     int tileIndex = tile.getX() + (tile.getY() * 16); // 16 is the grid Y segments, this assumes your grid is square
     if(tileIndex >= 0 && tileIndex < (16*16)) // some validation 0 to max size
     {
         System.out.println("Changing tile: (" + tile.getX() + "," + tile.getY() + ")");
         this.tileList[i] = tile;
     }
}

Теперь это должно быть более эффективным, и, возможно, вы можете обнаружить ошибку :) Я также, вероятно, заменил бы функцию getTile, чтобы сделать то же самое, когда вы знаете x, yположение, которое вам не нужно, чтобы найти его.

...