Java - 二维阵列图中的运动和墙碰撞

时间:2014-10-23 21:56:21

标签: java multidimensional-array collision pacman

我正在为一个项目创造一个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}
    };
}

1 个答案:

答案 0 :(得分:2)

除了||而不是&&之外还有一些愚蠢的错误。如果没有看到更多的应用程序,很难确定这样的问题在哪里。不过我会给出一些提示:

  1. 在添加碰撞检测之前,请确保您的移动完美运行。
  2. 添加碰撞检测时,将测试简化为最低限度,例如仅添加1个墙。然后尽量让你最难突破那堵墙,就像在每个角度都进入它一样,并注意一旦你碰撞或穿过墙壁就无法移动的奇怪行为。
  3. 如果你让角色移动然后寻找碰撞,你会在实施碰撞检测时发现问题。您应该检查下一步“步骤”的坐标。会是,如果你撞墙,那就不要动了。考虑一下,如果你移动你的角色然后在程序进行碰撞检测后发现你已经撞墙,那么技术上就是你的墙内!您应该计算角色的下一个坐标,如果没有碰撞,则将这些坐标提交给角色。
  4. 确保您完全调试程序,添加println语句:System.out.println("collision!")或调试程序,无论您最喜欢哪种方式。

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


    修改 我看到你关于CodeReview的问题已经关闭,这可能是因为你说&#34;我的代码没有工作&#34;。我告诉你在那里问它,目的是让他们基本上做我在这里做的事情。改进和重新组织代码,而不是修复碰撞检测。我确实碰巧为你解决了这个问题,但我对此进行了评论,以便在代码中查看我的评论! :)

    以下是我发现的一些问题

    1. 你的类应遵循Java命名约定,这意味着CamelCase用Captial字母开始,所以游戏应该是Game,输入将是输入ect ...静态变量应该始终是UPPER_SNAKE_CASE,静态变量总是在顶部声明这个班。
    2. 变量的范围遍布整个地方,例如Input类检测输入但更改Game类中的变量。 OOP的一个好处是,您可以将应用程序的特定区域拆分为特定的类,您不希望拥有的是god object,这就是您现在使用Game类的内容。它变得势不可挡,难以管理。继续这样做,很快就会有一个无法管理的程序。
    3. 你有一些奇怪的变量命名或奇怪的用法。我正在查看pTileXpTileYplayerPosXplayerPosYtileXtileY。为什么6变量?你应该只需要2,玩家的x和y位置。可以使用这些坐标随时找到切片位置。
    4. 目前你的地图类几乎没用。你有一些静态变量,但你不使用任何OOP结构!你有正确的想法,但让我们使用类结构。
    5. 除非需要,否则永远不要将某些内容声明为全局变量,始终减少变量的范围并根据需要增加。当你成为一名经验丰富的程序员时,你会对它的范围有更多的了解。
    6. 我将为您提供一个固定版本的代码,进一步移动方法和周围的东西将是未来添加的必要条件。我删除了很多全局变量,这些变量只是愚蠢到达那里。

      <强> Game.class

      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}
          };
      }
      

      <强> Input.class

      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;
              }
          }
      }
      

      <强> Resource.class

      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);
      
              }
          }
      }