移动在网格上创建复制到左边随机



我是java新手,一直在做一个小型生态系统项目。整个游戏的主网格由一个名为grid[][]的二维数组表示。生物的列表是种群[][]。为了简单起见,我只使用一种生物进行测试。

我正在做一个运动,它的工作原理如下:

  1. 将生物体所在位置的网格上的贴图更改为生物体下方的贴图
  2. 改变生物体的位置
  3. 记录生物体下的瓷砖
  4. 将tile替换为生物体的id

当移动时,有时生物体会复制自己,只在这一秒出现,下一秒就消失了。我已经努力找了2天了,还是找不到他们为什么这样做。

下面是重要的代码:

package ecosystem.Window;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;
public class Game extends Canvas implements Runnable{
    public boolean running=false;
    public int fps;
    public Thread thread;
    public Random rand=new Random();
    public int tile=33;
    public final int WATER=-2;
    public final int TREES=-1;
    public final int GROUND=0;
    public final int PREY=1;
    public final int PREDATOR=2;
    public final int X=0;
    public final int Y=1;
    public final int UNDERSQUARE=2;
    public int[][]grid=new int[16][16];
    public int[][]population=new int[10][3];
    public synchronized void start(){
        if(running)
        return;
        running=true;
        thread=new Thread(this);
        thread.start();
    }
    public static void main(String[] args){
        new Window(640,480,"Ecosystem",new Game());
    }
    public void init(){
        int row=0;
        int column=0;
        int r;
        while(row<15){
            if(column>=15){
                row+=1;
                column=0;
            }else{
                column+=1;
            }
            r=rand.nextInt(4);
            grid[column][row]=(r-3);
        }
        for(int i=0;i<2;i++){
            population[i][X]=rand.nextInt(16);
            population[i][Y]=rand.nextInt(16);
            population[i][UNDERSQUARE]=GROUND;
            grid[population[i][X]][population[i][Y]]=PREY;
        }
    }
    public void run(){
        init();
        this.requestFocus();
        System.out.println(" ");
        long lastTime = System.nanoTime();
        double amountOfTicks = 10000000000.0;
        int frames=0;
        double ns = 8000000000000000000.0 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int updates = 0;
        while(running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while(delta >= 1){
                tick();
                updates++;
                delta--;
                render();
            }
            frames++;
            if(System.currentTimeMillis() - timer > 1000){
                timer += 1000;
                fps=frames;
                frames = 0;
                updates = 0;
            }
        }
    }
    private void tick() {
        System.out.println("Tick");
        grid[population[1][X]][population[1][Y]]=population[1][UNDERSQUARE];
        population[1][X]--;
        population[1][UNDERSQUARE]=grid[population[1][X]][population[1][Y]];
        grid[population[1][X]][population[1][Y]]=PREY;
    }
    private void render() {
        int column=0;
        int row=0;
        BufferStrategy bs = this.getBufferStrategy();
        if(bs==null){
            this.createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.darkGray);
        g.fillRect(0, 0, 700, 900);
        g.setColor(Color.black);
        g.fillRect(0, 0, 494, 496);
        //GRID//
        while(row<15){
            if(column>=15){
                row+=1;
                column=0;
            }else{
                column+=1;
            }
            if(grid[column][row]==WATER){
                g.setColor(Color.blue);
            }
            if(grid[column][row]==TREES){
                g.setColor(Color.green);
            }
            if(grid[column][row]==GROUND){
                g.setColor(Color.orange);
            }
            if(grid[column][row]==PREY){
                g.setColor(Color.red);
            }
            if(grid[column][row]==PREDATOR){
                g.setColor(Color.YELLOW);
            }
            g.fillRect(column*tile-(tile+1), row*tile, (tile-1), (tile-1));
        }
        //CONTROL PANEL//

        /////////////////
        /////////////////
        g.dispose();
        bs.show();
        //System.out.println("");
    }
}

你直接从另一个线程访问AWT对象(例如,通过从你的线程调用render(),或this的任何其他Canvas方法)。您只能从事件分派线程访问这些对象。如果你不这样做,所有的赌注都结束了;这很容易破坏你的渲染输出。EDT的链接描述是这样说的:

忽略此规则的程序可能在大多数情况下正常运行,但会发生不可预测的错误,难以重现。

你需要做一些改变。你有几个选择。

最简单的选择可能是在线程中使用SwingUtilities.invokeAndWait(),使用调用render()Runnable。您可以使用invokeLater(),但是您必须特别注意确保您正在同步访问数据。尽管如此,你还必须检查你的代码,并确保你没有从其他线程调用任何Canvas方法(例如this.requestFocus()是一个no-go)。

其他选项包括重新设计你的代码,使GUI自己渲染,例如通过计时器,并主动查询当前状态从你的线程;而不是让线程控制呈现,让GUI从线程中提取状态。这有时会变得很复杂,特别是当你想要模拟帧和GUI更新之间的1:1对应时。

一般来说,让你的类扩展Canvas,但也有你的线程实现有一个坏的组合;因为一般来说,Canvas方法都不能安全地从另一个线程调用。你应该考虑将模拟逻辑与GUI分离(即不要将游戏逻辑放在Canvas中);这样做还有很多潜在的好处。

最新更新