gpt4 book ai didi

Java - 二维数组 map 中的移动和墙壁碰撞

转载 作者:行者123 更新时间:2023-12-02 05:20:44 25 4
gpt4 key购买 nike

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

最佳答案

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

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

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

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

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

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

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

    游戏类
    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;
    }
    }
    }

    资源.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);

    }
    }
    }

    关于Java - 二维数组 map 中的移动和墙壁碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26538154/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com