无法找到任何可能的错误,但Java说不同

时间:2014-02-21 04:42:20

标签: java

我遇到了一个问题,我正在用Java编程,当我去运行它时,它提出了一个大约6个错误的列表。这些

Exception in thread "Display" java.lang.ArrayIndexOutOfBoundsException: 64
    at com.cmnatic.mld.graphics.Screen.clear(Screen.java:27)
    at com.cmnatic.mld.Game.render(Game.java:107)
    at com.cmnatic.mld.Game.run(Game.java:77)
    at java.lang.Thread.run(Unknown Source)

如果有帮助,这是我的代码(ofc确实如此)

Game.java:

package com.cmnatic.mld;

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JFrame;

import com.cmnatic.mld.graphics.Screen;

public class Game extends Canvas implements Runnable {
    private static final long serialVersionUID = 1L;

    public static int width = 300; // 300 * 3 = 900
    public static int height = width / 16 * 9; //168.75 * 3 = 506.25
    public static int scale = 3;
    public static String title = "CMNatic's MLD Entry #49";


    private Thread thread;
    private JFrame frame;
    private boolean running = false;

    private Screen screen;

    private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    private int[] pixels =((DataBufferInt)image.getRaster().getDataBuffer()).getData();

    public Game() {
        Dimension size = new Dimension(width * scale, height * scale);
        setPrefferedSize(size);

        screen = new Screen(width, height);

        frame = new JFrame();
        this.setSize(900,506); 
    }

    private void setPrefferedSize(Dimension size) {

    }

    public synchronized void start() {
        running = true;
        thread = new Thread(this , "Display");
        thread.start();
    }

    public synchronized void stop() {
        running = false;
        try {
        thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        long lastTime = System.nanoTime();
        long timer = System.currentTimeMillis();
        final double ns = 100000000.0 / 60.0; // nano-seconds = 1000000000 (9 0'S) / 60.0
        double delta = 0;
        int frames = 0;
        int updates = 0;
        while (running) {
            long now = System.nanoTime();
            delta += (now-lastTime) / ns;  //nano-seconds (ns)  
            lastTime = now;
            while (delta >= 1) {
                update();
                updates++;
                delta--;
            }
            render();
            frames++;

            if (System.currentTimeMillis() - timer > 1000) {
                timer += 1000;
                System.out.println(updates + " ups, " + frames + " fps");
                frame.setTitle(title + "    |    " + updates + "ups, " + frames);
                updates = 0;
                frames = 0;
            }
        }
        stop();
    }

    int x = 0, y = 0;

    public void update() {
        y++;
        if (y % 10 == 0) x++;
        x++;
        //y++;
    }

    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {   
            createBufferStrategy(3);
            return;
        }

Screen.Java

package com.cmnatic.mld.graphics;

import java.util.Random;

public class Screen {

    private int width, height;
    public int[] pixels;
    public final int MAP_SIZE = 8;
    public final int MAP_SIZE_MASK = MAP_SIZE - 1;
    public int[] tiles = new int[MAP_SIZE * MAP_SIZE];

    private Random random = new Random();

    public Screen(int width, int height) {
        this.width = width;
        this.height = height;
        pixels = new int[width * height]; // 50,400

        for (int i = 0; i < MAP_SIZE * MAP_SIZE; i++) {
            tiles[i] = random.nextInt(0xffffff);
        }
    }

    public void clear() {
        for (int i = 0; i < pixels.length; i++) {
            tiles[i] = random.nextInt(0xffffff);
            tiles[0] = 0;   
        }
    }

    public void render(int xOffset, int yOffset) {
        for (int y = 0; y < height; y++) {
            int yy = y + yOffset;
            //if (yy < 0 || y >= height) break;
            for (int x = 0; x < width; x++) {
                int xx = x + xOffset;
                //if (xx < 0 || x >= width) break;
                int tileIndex = ((xx >> 4) + xOffset& MAP_SIZE_MASK) + ((yy >> 4)& MAP_SIZE_MASK) * MAP_SIZE;   
                pixels[x + y * width] = tiles[tileIndex];   


            }
        }
    }

}

如果有人能提供帮助,我将永远感激不尽!

2 个答案:

答案 0 :(得分:2)

您的问题是您在pixels方法中可以互换使用tilesclear。逻辑“board”大小为8x8,但您的pixels数组的大小基于传入的参数。然后,您尝试迭代8x8板中的50k左右像素并立即运行结束。

此外,这两个数组都非常明显地代表了二维概念(板和屏幕),它使您的代码更清晰地使用二维数组:

int pixels[][] = new int[width][height];

答案 1 :(得分:2)

Screen.clear()中你有:

    for (int i = 0; i < pixels.length; i++) {
        tiles[i] = random.nextInt(0xffffff);
        tiles[0] = 0;   
    }

但根据您的评论,pixels明显大于tiles。你可能在for循环中意味着tiles.length(我假设clear应该在Screen构造函数的末尾执行与你在循环中所做的相同的事情。 / p>

通常,当您看到ArrayIndexOutOfBoundsException时,它恰恰意味着数组索引超出范围。遇到这种情况时,请仔细查看您的代码,并尝试找到发生这种情况的任何机会。在这种情况下,在索引循环中使用不同数组的length是一个很大的红旗。

此外,顺便说一句,该循环中的tiles[0] = 0看起来不应该在那里。