代码之家  ›  专栏  ›  技术社区  ›  Kokufuu

AWT-EventQueue-1 NullExceptionPointer

  •  1
  • Kokufuu  · 技术社区  · 12 年前

    我在用瓷砖做迷宫游戏。迷宫每隔一段时间就会改变形状。 此时,在迷宫重现之前,波浪线变空。 我在不同的时间间隔和游戏停止后都会出现NPE错误。 可能是因为某些方法试图在实际重新创建之前进行访问。 我尝试在某些地方放置if(…!=null),甚至尝试同步某些部分(我不太熟悉)。

    编辑:感谢Arvind指出了问题。我设法修复了它,但我仍然会通知一些更多的帮助,因为这不是我认为最好和最整洁的修复。 在某些情况下,平铺t等于空。我只是检查了一下,然后继续; 以避免错误。

    非常感谢您提前提供的任何帮助和建议!

    出现此错误后,游戏仍然运行:

    Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
    at shiftingmaze.Game.paintTiles(Game.java:161)
    at shiftingmaze.Game.paint(Game.java:115)
    at shiftingmaze.Game.update(Game.java:107)
    at sun.awt.RepaintArea.updateComponent(Unknown Source)
    at sun.awt.RepaintArea.paint(Unknown Source)
    at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$400(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
    

    过了一段时间,它就会冻结并出现以下错误:

    Exception in thread "Thread-4" java.lang.NullPointerException
    at shiftingmaze.Game.updateTiles(Game.java:153)
    at shiftingmaze.Game.run(Game.java:86)
    at java.lang.Thread.run(Unknown Source)
    

    以下是代码的一些部分:

    @Override
    public void start() {
    
        hero = new Hero();
    
        Timer t = new Timer();
    
        t.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                tilearray.clear();
                shiftMaze();
            }
        }, 0, 1000);
    
        Thread thread = new Thread(this);
        thread.start();
    }
    
    @Override
    public void stop() {
    
    }
    
    @Override
    public void destroy() {
    
    }
    
    @Override
    public void run() {
    
        while (true) {
            hero.update();
            updateTiles();
            repaint();
            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    @Override
    public void update(Graphics g) {
    
        if (image == null) {
            image = createImage(this.getWidth(), this.getHeight());
            second = image.getGraphics();
        }
    
        second.setColor(getBackground());
        second.fillRect(0, 0, getWidth(), getHeight());
        second.setColor(getForeground());
        paint(second);
        g.drawImage(image, 0, 0, this);
    }
    
    @Override
    public void paint(Graphics g) {
    
        g.drawImage(background, 0, 0, this);
        paintTiles(g);
        // g.drawRect((int)Hero.rect.getX(), (int)Hero.rect.getY(),
        // (int)Hero.rect.getWidth(), (int)Hero.rect.getHeight());
        // g.drawRect((int)Hero.bigRect.getX(), (int)Hero.bigRect.getY(),
        // (int)Hero.bigRect.getWidth(), (int)Hero.bigRect.getHeight());
        g.drawImage(character, hero.getHeroX(), hero.getHeroY(), this);
    }
    
    public void shiftMaze() {
    
        final int MAZEROW = 24;
        final int MAZECOL = 40;
    
        for (int i = 0; i < MAZEROW * MAZECOL / 2; i++) {
            int n = rand.nextInt(MAZECOL - 2) + 1;
            int m = rand.nextInt(MAZEROW - 2) + 1;
            if (!(n == 1 && m == 1) && !(n == MAZECOL - 2 && m == MAZEROW - 2)) {
                Tile t = new Tile(n, m);
                tilearray.add(t);
            }
        }
    
        for (int i = 0; i < MAZECOL; i++) {
            for (int j = 0; j < MAZEROW; j++) {
                if (i == 0 || i == MAZECOL - 1 || j == 0 || j == MAZEROW - 1)
                    if (!(i == 1 && j == 0)
                            && !(i == MAZECOL - 2 && j == MAZEROW - 1)) {
                        Tile t = new Tile(i, j);
                        tilearray.add(t);
                    }
            }
        }
    }
    
    public void updateTiles() {
    
        for (int i = 0; i < tilearray.size(); i++) {
            Tile t = (Tile) tilearray.get(i);
            t.update();
        }
    }
    
    public void paintTiles(Graphics g) {
    
        for (int i = 0; i < tilearray.size(); i++) {
            Tile t = (Tile) tilearray.get(i);
            g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY(), this);
        }
    }
    

    这来自Tile类:

    public Tile(int x, int y) {
    
        tileX = x * 20;
        tileY = y * 20;
        tileImage = Game.getWall();
    
        r = new Rectangle();
    }
    
    public void update() {
    
        r.setBounds(tileX, tileY, 20, 20);
        if (r.intersects(Hero.bigRect))
            checkCollision(Hero.rect);
    }
    
    2 回复  |  直到 12 年前
        1
  •  0
  •   user2575725 user2575725    12 年前

    问题就在这里:

    public void updateTiles() {
        for (int i = 0; i < tilearray.size(); i++) {
            Tile t = (Tile) tilearray.get(i);//<-- tile is null in some cases
            t.update();
        }
    }
    

    有很多方法可以避免这种情况:

    选项1 :子类ArrayList,并用null检查重写方法add()和addAll()。

    选项2 :填充波浪线后,使用此行删除空值

        tilearray.removeAll(Collections.singleton(null));
    

    编辑

    如果您正在寻找第二个选项,那么您应该尝试以下操作:

    public void shiftMaze() {
        //<-- to do here
        tilearray.removeAll(Collections.singleton(null));//<-- at the end
    }
    
        2
  •  0
  •   Kokufuu    12 年前

    谢谢你的帮助,我试过了,但还是有空。 与此同时,我做了以下操作以消除错误。它几乎一直在工作,但很少我仍然得到NPE或索引超出范围的错误。。。 我将游戏加速到100毫秒的娱乐时间,以便长期进行错误检查。

    for (int i = 0; i < tilearray.size(); i++) {
        Tile t = (Tile) tilearray.get(i);
        if (t == null && i < tilearray.size() - 1) {
            System.out.println("t = null @ updateTiles(), moving to next element");
            continue;
        }
        if (t == null && i >= tilearray.size()) {
            System.out.println("t = null @ updateTiles(), no elements left");
            break;
        }
        t.update();
    
    推荐文章