0

我正在为一个项目创建 pac man,但在我的角色移动时遇到了麻烦。特别是实现墙壁碰撞,我可以很好地移动角色,只是当我尝试进行墙壁碰撞时......显然我做错了什么

当我试图四处移动时,它会检测到箭头键输入但不会移动角色,因此我认为我的 if 语句不正确,所以我尝试将其设置为在上升时处理墙壁碰撞。这导致了看似看不见的墙壁或地方,我只是无法移动我已经看了一段时间,但还没有找到解决方案。

当前代码

    package main;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class game extends Canvas implements Runnable {
    final static String NL = System.getProperty("line.separator");
    public static int tile;
    public boolean running = false;
    public String name = "PacMan";
    public static final int WIDTH = 23;//578;
    public static final int HEIGHT = 29;//720;
    public static final int SCALE = 25;
    private JFrame frame;
    private Image bImage;
    private Graphics db;
    private input input;
    public static int playerPosX = 0;
    public static int playerPosY = 0;
    public static int playerHeight = 16;
    public static int playerWidth = 16;
    public static int speed = 3;

    static BufferedImage background = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage pacman = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage settingsBackground = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage level1 = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage level2 = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage points = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage point = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage wall = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage blackBack = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;
    static BufferedImage pointBack = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);;


    public static boolean key_down = false;
    public static boolean key_up = false;
    public static boolean key_right = false;
    public static boolean key_left = false;
    public boolean wallDrawn = false;
    public boolean loaded = false;

    public static int tc = 0;
    public int tileX, tileY, pTileX, pTileY;

    public game() {


        setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); // keeps
                                                                        // the
                                                                        // canvas
                                                                        // same
                                                                        // size
        setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

        frame = new JFrame(name); // creates the frame for our game
        input = new input();

        //if(MAIN_MENU == true && GAME == false){
        //  buttons = new buttons(frame.getContentPane()); //draws the buttons based on the code in our graphics/buttons.java
        //}

        frame.setLayout(new BorderLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // ends program on click of the Exit button in the top right corner
        frame.setLocationByPlatform(true);
        frame.addKeyListener(new input() );
        frame.add(this, BorderLayout.CENTER);
        frame.pack(); // keeps size correct
        frame.setResizable(false); //keep this false, if set to true whenever someone resizes it our code will not function correctly
        frame.setVisible(true);

        this.addKeyListener(input);
        this.createBufferStrategy(2); //I think this is double buffering, honestly not too sure
    }


    public static void main(String[] args) {
        new game().start();
    }

    public void resLoader() {
        try {
            background = ImageIO.read(new File("res\\Background.png"));
            wall = ImageIO.read(new File("res\\maptile.png"));
            pacman = ImageIO.read(new File("res\\pacman.png"));
            settingsBackground = ImageIO.read(new File("res\\Background.png"));
            level1 = ImageIO.read(new File("res\\level1.png"));
            point = ImageIO.read(new File("res\\Points for pacman.png"));
            blackBack = ImageIO.read(new File("res\\blackBack.png"));
            pointBack = ImageIO.read(new File("res\\points.png"));

        } catch (IOException e) {
            System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ WARNING! ~~~~~~~~~~~~~~~~~~~~~~~~~~");
            System.out.println("There was am Image unsuccessfully loaded!" + NL + "The game may not work properly, check the load images method for spelling errors!");
            System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ WARNING! ~~~~~~~~~~~~~~~~~~~~~~~~~~" + NL + NL);
        }
    }

    public void run() 
    {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000 / 60D;
        long lastTimer = System.currentTimeMillis();
        double delta = 0;

        int frames = 0;
        int ticks = 0;

        while (running == true) {
            long now = System.nanoTime();
            delta += (now - lastTime) / nsPerTick;
            lastTime = now;
            boolean render = false;

            while (delta >= 1) {
                ticks++;
                tick();
                delta -= 1;
                render = true;

            }

                try {
                    Thread.sleep(3);        //keep the Frames from going to high
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            if(render == true){
            frames++;
            render();
            }

            if (System.currentTimeMillis() - lastTimer >= 1000) {
                lastTimer +=1000;
                //System.out.println("Frames: " + frames + "   Ticks: " + ticks); 

                frames = 0;
                ticks = 0;
            }
        }

        try {
            Thread.sleep(3);        //keep the Frames from going to high
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void start() {
        resLoader();
        new Thread(this).start();
        running = true;

    }

    public synchronized void stop() {
        running = false;
    }

    public void render () {
        Graphics g = getGraphics();
        if (bImage == null) {

          bImage = createImage (this.getSize().width, this.getSize().height);
          db = bImage.getGraphics ();

        }

        db.setColor (getBackground ());
        db.fillRect (0, 0, this.getSize().width, this.getSize().height);

        paint (db);

        g.drawImage (bImage, 0, 0, this);
      }



            public void paint (Graphics g) {

            for (int x = 0; x < main.map.width; x++)
              { 
                 for (int y = 0; y < main.map.height; y++)
                 {
                     tile = main.map.level1[y][x];
                     tileX = x * 21;
                     tileY = y * 26;


                 if(tile == 0){
                     g.drawImage(wall,tileX,tileY, 21, 26,null);
                 }

                 if(tile == 1){
                     g.drawImage(pointBack,tileX, tileY, (int)21.42857142857143, 26,null);
                    }

                 if(tile == 2){
                     g.drawImage(blackBack,tileX, tileY, (int)21.42857142857143, 26,null);
                 }

                 if(tile == 5) {
                     if(!loaded) {
                         pTileX = tileX;
                         pTileY = tileY;
                         loaded = true;
                     }
                     g.drawImage(blackBack,tileX, tileY, (int)21.42857142857143, 26,null);
                 }
                 }
              }
            g.drawImage(pacman, pTileX, pTileY, playerWidth, playerHeight, null);
        }





    public void tick() {
        playerPosX = pTileX / 21;
        playerPosY = pTileY / 26;

        int wallPosX, wallPosY;

        if(key_up && map.level1[playerPosX][playerPosY] == 1){
            pTileY = pTileY - speed;
        }

        if(key_down && map.level1[playerPosX][playerPosY] == 1){
            pTileY += speed;
        }

        if(key_left && map.level1[playerPosX][playerPosY] == 1){
            pTileX -= speed;
        }

        if(key_right && map.level1[playerPosX][playerPosY] == 1){
            pTileX += speed;
        }
    }
}

package main;

import java.awt.event.*;

public class input implements KeyListener
{




    public void keyTyped(KeyEvent e) {
    }



    /** Here we have a rather basic key listener
     *  It is set that you can only go left right up or down right now
     *  If more directions are needed delete the "other key = false"
     */

    public void keyPressed(KeyEvent e) {
        System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            game.key_right = true;
            game.key_left = false;
            game.key_up = false;
            game.key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            game.key_right = false;
            game.key_left = true;
            game.key_up = false;
            game.key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            game.key_right = false;
            game.key_left = false;
            game.key_up = true;
            game.key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            game.key_right = false;
            game.key_left = false;
            game.key_up = false;
            game.key_down = true;
        }
    }





    public void keyReleased(KeyEvent e) {
        System.out.println(e.getKeyCode());
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            game.key_right = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            game.key_left = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            game.key_up = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
           game.key_down = false;
        }
    }
}

public class map {
    public static int width = 28;
    public static int height = 28;
    public static int[][] level1 = {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,2,2,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,2,2,2,2,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,0,0,1,1,1,1,1,1,1,5,1,1,1,1,1,1,1,1,0,0,1,1,1,0},
        {0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0},
        {0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0},
        {0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0},
        {0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };
}
4

1 回答 1

2

除了有一些愚蠢的错误,比如 a||而不是 a &&。如果不查看更多应用程序,就很难确定此类问题的问题所在。不过我会给出一些提示:

  1. 在添加碰撞检测之前,请确保您的动作运行良好。
  2. 添加碰撞检测时,将测试简化到最低限度,例如仅添加 1 面墙。然后尽你最大的努力突破那堵墙,就像从各个角度进入它并注意奇怪的行为,例如一旦你碰撞或穿过墙壁就无法移动。
  3. 如果你让你的角色移动然后寻找碰撞,你会在实施碰撞检测时发现问题。您应该检查下一个“步骤”所在的坐标,如果您撞到了墙,请不要移动。想想看,如果你移动你的角色,那么在程序进行碰撞检测并看到你撞到墙之后,从技术上讲,你在墙内!您应该计算角色的下一个坐标,如果没有碰撞,则将这些坐标提交给角色。

确保彻底调试程序,添加 println 语句:System.out.println("collision!")或调试器,无论您最喜欢哪种方式。

这真的应该是一个评论,但它太长了......


编辑: 我看到您关于 CodeReview 的问题已关闭,这可能是因为您说“我的代码不起作用”。我告诉你在那里问它,目的是让他们基本上做我在这里做的事情。改进和重组你的代码,而不是修复碰撞检测。我确实碰巧为你解决了这个问题,但我评论了它,所以看看我在代码中的评论!:)

以下是我发现的一些问题

  1. 您的类应遵循 Java 命名约定,这意味着以大写字母开头的 CamelCase,因此游戏应为 Game,输入应为 Input 等...静态变量应始终为 UPPER_SNAKE_CASE,静态变量始终声明在类的顶部.
  2. 变量的范围无处不在,例如,Input类检测输入但更改Game类中的变量。OOP 的一个好处是您可以将应用程序的特定区域分解为特定的类,您不想要的是一个上帝对象,这就是您现在的Game类所拥有的。它变得势不可挡且难以管理。继续这样做,很快你就会有一个无法管理的程序。
  3. 你有一些奇怪的变量命名或它们的奇怪用法。我在看pTileX, pTileY, playerPosX, playerPosY, tileX, tileY. 为什么是 6 个变量?您应该只需要 2,即播放器的 x 和 y 位置。可以使用这些坐标随时找到图块位置。
  4. 您的地图类目前几乎没用。你有一些静态变量,但你没有使用任何 OOP 结构!你有正确的想法,但让我们使用类结构。
  5. 除非需要,否则永远不要将某些东西声明为全局变量,始终缩小变量的范围并根据需要增加。当您成为一名经验更丰富的程序员时,您将对它应该是什么范围有更多的了解。

我将给你一个固定版本的代码,进一步移动方法和东西将是未来添加所必需的。我删除了很多全局变量,这些变量放在那里很傻。

游戏类

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;

import javax.swing.JFrame;

public class Game extends Canvas implements Runnable {
    public static int playerHeight = 16;
    public static int playerWidth = 16;
    public static int movementSpeed = 3;

    public boolean running = false;

    private JFrame frame;
    private Image bufferImage;
    private Graphics bufferGraphics;
    private Input input;

    private Point playerLocation = null;

    private GameMap currentLevel;


    public Game() {
        Resources.loadResources();
        loadLevel(new GameMap.Level1());

        frame = new JFrame("PacMan"); // creates the frame for our game
        input = new Input();

        // if(MAIN_MENU == true && GAME == false){
        // buttons = new buttons(frame.getContentPane()); //draws the buttons
        // based on the code in our graphics/buttons.java
        // }

        frame.setLayout(new BorderLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // ends program on
                                                                // click of the
                                                                // Exit button
                                                                // in the top
                                                                // right corner
        frame.setLocationByPlatform(true);
        frame.addKeyListener(new Input());
        frame.add(this, BorderLayout.CENTER);
        frame.pack(); // keeps size correct
        frame.setResizable(false); // keep this false, if set to true whenever
                                    // someone resizes it our code will not
                                    // function correctly
        frame.setVisible(true);

        this.addKeyListener(input);
        this.createBufferStrategy(2); // I think this is double buffering,
                                        // honestly not too sure
    }

    /**
     * Loads the level into the game, also changes the dimensions of the window to fit the game
     * @param gameMap
     */
    private void loadLevel(GameMap gameMap) {
        currentLevel = gameMap;

        playerLocation = convertMapLocationToScreenLocation(currentLevel.getPlayerStartLocation());

        Dimension canvasSize = new Dimension(currentLevel.getWidth()*Resources.TILE_WIDTH, currentLevel.getHeight()*Resources.TILE_HEIGHT);

        setMinimumSize(canvasSize);
        setMaximumSize(canvasSize);
        setPreferredSize(canvasSize);

    }

    public void run() {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000 / 60D;
        long lastTimer = System.currentTimeMillis();
        double delta = 0;

        int frames = 0;
        int ticks = 0;

        while (running == true) {
            long now = System.nanoTime();
            delta += (now - lastTime) / nsPerTick;
            lastTime = now;
            boolean render = false;

            while (delta >= 1) {
                ticks++;
                tick();
                delta -= 1;
                render = true;

            }

            try {
                Thread.sleep(20); // keep the Frames from going to high
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (render == true) {
                frames++;
                render();
            }

            if (System.currentTimeMillis() - lastTimer >= 1000) {
                lastTimer += 1000;

                frames = 0;
                ticks = 0;
            }
        }

        try {
            Thread.sleep(20); // keep the Frames from going to high
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void start() {
        new Thread(this).start();
        running = true;

    }

    public synchronized void stop() {
        running = false;
    }

    public void render() {
        Graphics g = getGraphics();
        if (bufferImage == null) {

            bufferImage = createImage(this.getSize().width, this.getSize().height);
            bufferGraphics = bufferImage.getGraphics();

        }

        bufferGraphics.setColor(Color.orange);
        bufferGraphics.fillRect(0, 0, this.getSize().width, this.getSize().height);

        drawGame(bufferGraphics);

        g.drawImage(bufferImage, 0, 0, this);
    }

    // this had to be renamed to drawGame, the paint method is used by AWT objects. This caused a serious bug where you would be constantly repainting.
    public void drawGame(Graphics g) {

        for (int x = 0; x < currentLevel.getWidth(); x++) {
            for (int y = 0; y < currentLevel.getHeight(); y++) {
                int tile = currentLevel.getTileAt(x, y);
                int tileX = x * Resources.TILE_WIDTH;
                int tileY = y * Resources.TILE_HEIGHT;

                if (tile == GameMap.TILE_WALL) {
                    g.drawImage(Resources.WALL, tileX, tileY, Resources.TILE_WIDTH, Resources.TILE_HEIGHT, null);
                }

                if (tile == GameMap.TILE_NOTHING) {
                    g.drawImage(Resources.BLACK_BACK, tileX, tileY,
                            Resources.TILE_WIDTH, Resources.TILE_HEIGHT, null);
                }

                if (tile == GameMap.TILE_POINT) {
                    g.drawImage(Resources.POINT, tileX, tileY,
                            Resources.TILE_WIDTH, Resources.TILE_HEIGHT, null);
                }
                /* This is not a good way to find the first location for the player, knowing that location belongs to the Map class
                if (tile == 5) {
                    if (!loaded) {
                        playerPosX = tileX;
                        playerPosY = tileY;
                        loaded = true;
                    }
                    g.drawImage(blackBack, tileX, tileY,
                            (int) 21.42857142857143, 26, null);
                }*/
            }
        }
        g.drawImage(Resources.PACMAN, playerLocation.x, playerLocation.y, playerWidth, playerHeight, null);
    }

    public void tick() {

        int nextPlayerPosX = playerLocation.x;
        int nextPlayerPosY = playerLocation.y;

        if (input.key_up) {
            nextPlayerPosY -= movementSpeed;
        }

        if (input.key_down) {
            nextPlayerPosY += movementSpeed;
        }

        if (input.key_left) {
            nextPlayerPosX -= movementSpeed;
        }

        if (input.key_right) {
            nextPlayerPosX += movementSpeed;
        }

        // lets make sure the next location doesnt collide with a wall, if so then dont move the pacman!
        if(!doesPlayerCollideWith(nextPlayerPosX, nextPlayerPosY, GameMap.TILE_WALL)) {
            playerLocation.setLocation(nextPlayerPosX, nextPlayerPosY);
        }
    }

    /**
     * Looks at the players screen location and gets the map tiles for each corner.
     * @param screenX
     * @param screenY
     * @return the 4 map tiles for each corner of the pac man given the screenX and screenY
     */
    private int[] getPlayerCornerCollisions(int screenX, int screenY) {
        int[] corners = new int[4];
        Point tileLocation = convertScreenLocationToMapLocation(screenX, screenY);
        corners[0] = currentLevel.getTileAt(tileLocation.x, tileLocation.y);

        tileLocation = convertScreenLocationToMapLocation(screenX + playerWidth, screenY);
        corners[1] = currentLevel.getTileAt(tileLocation.x, tileLocation.y);

        tileLocation = convertScreenLocationToMapLocation(screenX, screenY + playerHeight);
        corners[2] = currentLevel.getTileAt(tileLocation.x, tileLocation.y);

        tileLocation = convertScreenLocationToMapLocation(screenX + playerWidth, screenY + playerHeight);
        corners[3] = currentLevel.getTileAt(tileLocation.x, tileLocation.y);
        return corners;
    }

    /**
     * Checks if any corners of the player intersects with the given mapTileType
     * @param screenX
     * @param screenY
     * @param mapTileType
     * @return true if the player intersects with the given map tile type
     */
    public boolean doesPlayerCollideWith(int screenX, int screenY, int mapTileType) {
        for(int tileType : getPlayerCornerCollisions(screenX, screenY)) {
            if(tileType == mapTileType) {
                return true;
            }
        }
        return false;
    }

    /**
     * Takes the screen location and converts it to a coordinate in the map
     * @param location
     * @return
     */
    public Point convertScreenLocationToMapLocation(Point location) {
        return convertScreenLocationToMapLocation(location.x, location.y);
    }
    public Point convertScreenLocationToMapLocation(int x, int y) {
        return new Point(x/Resources.TILE_WIDTH, y/Resources.TILE_HEIGHT);
    }

    public Point convertMapLocationToScreenLocation(Point location) {
        return convertMapLocationToScreenLocation(location.x, location.y);
    }
    public Point convertMapLocationToScreenLocation(int x, int y) {
        return new Point(x*Resources.TILE_WIDTH, y*Resources.TILE_HEIGHT);
    }

    public static void main(String[] args) {
        new Game().start();
    }
}

GameMap.class - 以前是 Map.class

import java.awt.Point;

public abstract class GameMap {
    public static final int TILE_WALL = 0;
    public static final int TILE_NOTHING = 1;
    public static final int TILE_POINT = 2;
    public static final int TILE_START_LOCATION = 5;



    public abstract int getWidth();
    public abstract int getHeight();
    public abstract int[][] getLevelData();
    public abstract java.awt.Point getPlayerStartLocation();

    public int getTileAt(int x, int y) {
        return getLevelData()[y][x];
    }

    public static class Level1 extends GameMap {

        @Override
        public int getWidth() {
            return LEVEL_1_DATA[0].length;
        }

        @Override
        public int getHeight() {
            return LEVEL_1_DATA.length;
        }

        @Override
        public int[][] getLevelData() {
            return LEVEL_1_DATA;
        }

        @Override
        public Point getPlayerStartLocation() {
            for(int y=0;y<LEVEL_1_DATA.length;y++) {
                for(int x=0;x<LEVEL_1_DATA[y].length;x++) {
                    if(LEVEL_1_DATA[y][x] == GameMap.TILE_START_LOCATION) {
                        return new Point(x, y);
                    }
                }
            }
            // should never reach this unless we forgot to put a start location.
            throw new RuntimeException("No player start location could be found!");
        }
    }

    private static int[][] LEVEL_1_DATA = {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,2,2,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,2,2,2,2,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0},
        {0,1,1,1,0,0,1,1,1,1,1,1,1,5,1,1,1,1,1,1,1,1,0,0,1,1,1,0},
        {0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0},
        {0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0},
        {0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0},
        {0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0},
        {0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0},
        {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };
}

输入类

import java.awt.event.*;

public class Input implements KeyListener
{
    public boolean key_down = false;
    public boolean key_up = false;
    public boolean key_right = false;
    public boolean key_left = false;

    public void keyTyped(KeyEvent e) {
    }

    /** Here we have a rather basic key listener
     *  It is set that you can only go left right up or down right now
     *  If more directions are needed delete the "other key = false"
     */

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            key_right = true;
            key_left = false;
            key_up = false;
            key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            key_right = false;
            key_left = true;
            key_up = false;
            key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            key_right = false;
            key_left = false;
            key_up = true;
            key_down = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            key_right = false;
            key_left = false;
            key_up = false;
            key_down = true;
        }
    }





    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            key_right = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            key_left = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            key_up = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
           key_down = false;
        }
    }
}

资源类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public final class Resources {
    private final static String NL = System.getProperty("line.separator");

    public static final int TILE_WIDTH = 23;// 578;
    public static final int TILE_HEIGHT = 29;// 720;

    public static BufferedImage BACKGROUND = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage PACMAN = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage SETTINGS_BACKGROUND = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage LEVEL1 = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    /*public static BufferedImage LEVEL2 = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);*/
    public static BufferedImage POINTS = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage POINT = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage WALL = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage BLACK_BACK = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
    public static BufferedImage POINT_BACK = new BufferedImage(TILE_WIDTH, TILE_HEIGHT,
            BufferedImage.TYPE_INT_RGB);

    public static void loadResources() {
        try {
            BACKGROUND = ImageIO.read(new File("res\\Background.png"));
            WALL = ImageIO.read(new File("res\\maptile.png"));
            PACMAN = ImageIO.read(new File("res\\pacman.png"));
            SETTINGS_BACKGROUND = ImageIO.read(new File("res\\Background.png"));
            LEVEL1 = ImageIO.read(new File("res\\level1.png"));
            POINT = ImageIO.read(new File("res\\Points for pacman.png"));
            BLACK_BACK = ImageIO.read(new File("res\\blackBack.png"));
            POINT_BACK = ImageIO.read(new File("res\\points.png"));

        } catch (IOException e) {
            System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ WARNING! ~~~~~~~~~~~~~~~~~~~~~~~~~~");
            System.out.println("There was am Image unsuccessfully loaded!"
                            + NL
                            + "The game may not work properly, check the load images method for spelling errors!");
            System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ WARNING! ~~~~~~~~~~~~~~~~~~~~~~~~~~"
                            + NL + NL);

        }
    }
}
于 2014-10-23T22:23:04.587 回答