[A *寻路游戏系统退出问题

问题描述 投票:0回答:1

我正在制作一个游戏,当我使用箭头键移开时,badGuy AI试图追逐我。在我的主界面中,我有一个try catch块,用于播放器是否试图退出屏幕边框。但是由于某种原因,当我单击“开始”时,我得到一个例外,我打印了一个系统,上面写着“游戏结束,您退出了地图”。在badguy类中没有我的reCalcPath方法,这不会发生,因此在此方法中一定是一个问题。

对于这种方法,我有一个地图数组。此数组是一个20x20像素/单元/正方形的40x40布尔数组,如果我以前单击过该单元格位置,则为true,如果为false,则显示为白色,反之亦然。现在我想,请检查badGuy的单元格位置,然后检查其所有相邻单元格,如果该单元格的状态为false,即未绘制任何单元格(这意味着在此意义上没有壁遮挡住他),然后检查他和我的玩家之间的距离。我通过将xPlayer-xbadGuy,yPLayer-xBadGuy视为三角形的相对边和相邻边来使用欧几里得距离方法。使用毕达哥拉斯我得到了斜边。对每个相邻的单元格执行此操作,斜边最小的单元格意味着距离最短。现在,这完全不起作用,因为它的游戏崩溃了。如果recalcpath不起作用,请忽略move方法,因为它无关紧要]

[Main] >>


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.*;

public class AStarMaze extends JFrame implements Runnable, MouseListener, MouseMotionListener, KeyListener {

    // member data
    private boolean isInitialised = false;
    private BufferStrategy strategy;
    private Graphics offscreenBuffer;
    public boolean map[][] = new boolean[40][40];
    private boolean isGameRunning = false;
    private BadGuy badguy;
    private Player player;
    private int startI, startJ;
    private int endI, endJ;

    private String pFilePath, bgFilePath;

    // constructor
    public AStarMaze () {

        //Display the window, centred on the screen
        Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        int x = screensize.width/2 - 400;
        int y = screensize.height/2 - 400;
        setBounds(x, y, 800, 800);
        setVisible(true);
        this.setTitle("A* Pathfinding Demo");

        bgFilePath = "C:\\Users\\brads\\IdeaProjects\\PathfindingAssignment\\src\\badguy.png";
        pFilePath = "C:\\Users\\brads\\IdeaProjects\\PathfindingAssignment\\src\\player.png";
        // load raster graphics and instantiate game objects
        ImageIcon icon = new ImageIcon(bgFilePath);
        Image img = icon.getImage();
        badguy = new BadGuy(img);
        icon = new ImageIcon(pFilePath);
        img = icon.getImage();
        player = new Player(img);

        // create and start our animation thread
        Thread t = new Thread(this);
        t.start();

        // initialise double-buffering
        createBufferStrategy(2);
        strategy = getBufferStrategy();
        offscreenBuffer = strategy.getDrawGraphics();

        // register the Jframe itself to receive mouse and keyboard events
        addMouseListener(this);
        addMouseMotionListener(this);
        addKeyListener(this);

        // initialise the map state
        for (x=0;x<40;x++) {
            for (y=0;y<40;y++) {
                map[x][y]=false;
            }
        }

        isInitialised = true;
    }

    public boolean[][] getMap(){
        return map;
    }

    // thread's entry point
    public void run() {
        long loops=0;
        while ( 1==1 ) {
            // 1: sleep for 1/5 sec
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) { }
        try {
            // 2: animate game objects
            if (isGameRunning) {
                loops++;
                player.move(map); // player moves every frame
                if (loops % 3 == 0) // badguy moves once every 3 frames
                    badguy.reCalcPath(map,player.x,player.y);
                  //  badguy.move(map, player.x, player.y);
            }

            // 3: force an application repaint
            this.repaint();
        }
        catch(IndexOutOfBoundsException e){

            System.out.println("GAME OVER, you exited the map");
            System.exit(-1);
        }

        }
    }

    private void loadMaze() {
        String filename = "C:\\Users\\brads\\IdeaProjects\\PathfindingAssignment\\maze.txt";
        String textinput = null;
        try {
            BufferedReader reader = new BufferedReader(new FileReader(filename));
            textinput = reader.readLine();
            reader.close();
        }
        catch (IOException e) { }

        if (textinput!=null) {
            for (int x=0;x<40;x++) {
                for (int y=0;y<40;y++) {
                    map[x][y] = (textinput.charAt(x*40+y)=='1');
                }
            }
        }
    }

    private void saveMaze() {
        // pack maze into a string
        String outputtext="";
        for (int x=0;x<40;x++) {
            for (int y=0;y<40;y++) {
                if (map[x][y])
                    outputtext+="1";
                else
                    outputtext+="0";
            }
        }

        try {
            String filename = "C:\\Users\\brads\\IdeaProjects\\PathfindingAssignment\\maze.txt";
            BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
            writer.write(outputtext);
            writer.close();
        }
        catch (IOException e) { }
    }

    // mouse events which must be implemented for MouseListener
    public void mousePressed(MouseEvent e) {
        if (!isGameRunning) {
            // was the click on the 'start button'?
            int x = e.getX();
            int y = e.getY();
            if (x>=15 && x<=85 && y>=40 && y<=70) {
                isGameRunning=true;
                return;
            }
            // or the 'load' button?
            if (x>=315 && x<=385 && y>=40 && y<=70) {
                loadMaze();
                return;
            }
            // or the 'save' button?
            if (x>=415 && x<=485 && y>=40 && y<=70) {
                saveMaze();
                return;
            }
        }

        // determine which cell of the gameState array was clicked on
        int x = e.getX()/20;
        int y = e.getY()/20;
        // toggle the state of the cell
        map[x][y] = !map[x][y];
        // throw an extra repaint, to get immediate visual feedback
        this.repaint();
        // store mouse position so that each tiny drag doesn't toggle the cell
        // (see mouseDragged method below)
        prevx=x;
        prevy=y;
    }

    public void mouseReleased(MouseEvent e) {}

    public void mouseEntered(MouseEvent e) {}

    public void mouseExited(MouseEvent e) {}

    public void mouseClicked(MouseEvent e) {}
    //

    // mouse events which must be implemented for MouseMotionListener
    public void mouseMoved(MouseEvent e) {}

    // mouse position on previous mouseDragged event
    // must be member variables for lifetime reasons
    int prevx=-1, prevy=-1;
    public void mouseDragged(MouseEvent e) {
        // determine which cell of the gameState array was clicked on
        // and make sure it has changed since the last mouseDragged event
        int x = e.getX()/20;
        int y = e.getY()/20;
        if (x!=prevx || y!=prevy) {
            // toggle the state of the cell
            map[x][y] = !map[x][y];
            // throw an extra repaint, to get immediate visual feedback
            this.repaint();
            // store mouse position so that each tiny drag doesn't toggle the cell
            prevx=x;
            prevy=y;
        }
    }
    //

    // Keyboard events
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_LEFT)
            player.setXSpeed(-1);
        else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
            player.setXSpeed(1);
        else if (e.getKeyCode()==KeyEvent.VK_UP)
            player.setYSpeed(-1);
        else if (e.getKeyCode()==KeyEvent.VK_DOWN)
            player.setYSpeed(1);
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_LEFT || e.getKeyCode()==KeyEvent.VK_RIGHT)
            player.setXSpeed(0);
        else if (e.getKeyCode()==KeyEvent.VK_UP || e.getKeyCode()==KeyEvent.VK_DOWN)
            player.setYSpeed(0);
    }

    public void keyTyped(KeyEvent e) { }
    //

    // application's paint method
    public void paint(Graphics g) {
        if (!isInitialised)
            return;

        g = offscreenBuffer; // draw to offscreen buffer

        // clear the canvas with a big black rectangle
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 800, 800);

        // redraw the map
        g.setColor(Color.WHITE);
        for (int x=0;x<40;x++) {
            for (int y=0;y<40;y++) {
                if (map[x][y]) {
                    g.fillRect(x*20, y*20, 20, 20);
                }
            }
        }
        // redraw the player and badguy
        // paint the game objects
        player.paint(g);
        badguy.paint(g);

        if (!isGameRunning) {
            // game is not running..
            // draw a 'start button' as a rectangle with text on top
            // also draw 'load' and 'save' buttons
            g.setColor(Color.GREEN);
            g.fillRect(15, 40, 70, 30);
            g.fillRect(315, 40, 70, 30);
            g.fillRect(415, 40, 70, 30);
            g.setFont(new Font("Times", Font.PLAIN, 24));
            g.setColor(Color.BLACK);
            g.drawString("Start", 22, 62);
            g.drawString("Load", 322, 62);
            g.drawString("Save", 422, 62);
        }

        // flip the buffers
        strategy.show();
    }

    // application entry point
    public static void main(String[] args) {
        AStarMaze w = new AStarMaze();
    }

}

播放器类

] >>


import java.awt.Graphics;
import java.awt.Image;


public class Player {

    Image myImage;
    int x=0,y=0;
    int xSpeed=0, ySpeed=0;

    public Player( Image i ) {
        myImage=i;
        x=10;
        y=35;
    }

    public void setXSpeed( int x ) {
        xSpeed=x;
    }

    public void setYSpeed( int y ) {
        ySpeed=y;
    }

    public void move(boolean map[][]) {
        int newx=x+xSpeed;
        int newy=y+ySpeed;
        if (!map[newx][newy]) {
            x=newx;
            y=newy;
        }
    }

    public void paint(Graphics g) {
        g.drawImage(myImage, x*20, y*20, null);
    }

}

[坏家伙

] >>


import java.awt.Graphics;
import java.awt.Image;

public class BadGuy {

    Image myImage;
    int x=0,y=0;
    int distanceX = 0, distanceY = 0;
    boolean hasPath=false;

    public BadGuy( Image i ) {
        myImage=i;
        x = 30;
        y = 10;
    }

    public void reCalcPath(boolean map[][],int targx, int targy) {
//         TO DO: calculate A* path to targx,targy, taking account of walls defined in map[][]
        int totalDistance = 0;
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                if (!map[(x / 20) + i][(y / 20) + j]) {
                    if ((((targx - x) ^ 2) + ((targy - y) ^ 2)) <= totalDistance) {

                        totalDistance = (((targx - x) ^ 2) + ((targy - y) ^ 2));
                        x = ((x / 20) + i);
                        y = ((y / 20) + j);
                        return;

                    }
                }
            }
        }
            System.out.println("Not working");
    }


//    public void move(boolean map[][],int targx, int targy) {
//        if (hasPath) {
//            // TO DO: follow A* path, if we have one defined
//        }
//        else if(map[x / 20][y / 20]) {
//            hasPath = false;
//        }
//    }
    public void paint(Graphics g) {
        g.drawImage(myImage, x*20, y*20, null);
    }

}

我正在制作一个游戏,当我使用箭头键移开时,badGuy AI试图追逐我。在我的主界面中,我有一个try catch块,用于播放器是否试图退出屏幕边框。对于某些...

您的catch块由IndexOutOfBoundsException触发。查找有关错误的更多信息的一种简单方法是记录或输出堆栈跟踪。您可以通过将e.printStackTrace()添加到catch块来完成代码:

        catch(IndexOutOfBoundsException e){
            System.out.println("GAME OVER, you exited the map");
            e.printStackTrace()
            System.exit(-1);
        }

这应该向您显示引起问题的行号。

查看您的reCalcPath方法中的代码,我的有根据的猜测是引起问题的行是:if (!map[(x / 20) + i][(y / 20) + j]) {。如果(x / 20) + i(y / 20) + j小于0或大于地图尺寸,它将抛出您所看到的IndexOutOfBoundsException。在您开始并且x = 30,y = 10,i = -1和j = -1的情况下,其结果为map [0] [-1]。

这就是边界条件。您需要检查x和y在网格边缘的情况。在这种情况下,相邻的网格单元不在地图的外面,将引发异常。

java a-star
1个回答
0
投票

您的catch块由IndexOutOfBoundsException触发。查找有关错误的更多信息的一种简单方法是记录或输出堆栈跟踪。您可以通过将e.printStackTrace()添加到catch块来完成代码:

© www.soinside.com 2019 - 2024. All rights reserved.