制作Pacman时遇到了一些问题?

7

编辑:完全忘记提到我正在使用Java编码

我在制作游戏时遇到了一些困难,无法使我的吃豆人精灵/角色在游戏板上平滑移动。游戏板不是我自己创造的,而是一个图片。

我首先尝试了颜色检测,这是最好的方法,但是效果不太流畅,相当卡顿。

然后我试图手动输入不允许进入的位置坐标,但这也没有达到预期的效果。

现在我正在尝试让程序使用颜色检测,并检查一个独立的未见之板以查看是否仍在路径上。这远远失败了。看起来它可能是最聪明的选择,但拐角实在太糟糕了,很难通过调整图像来解决问题。

我想知道你们会为这样的任务建议什么方法。


你的意思是你没有制作这个板吗?最简单的实现方式是使用二维数组。 - Austin Henley
@Fogest,他在谈论一个网格。你可以将你的图像叠加一个网格,这不会出现在最终产品中,但你可以看到每个坐标需要多少像素宽度。你可以使用2D数组来跟踪路径和墙壁。这是一个例子:http://home.comcast.net/~machaira/Pac-Man.png - Matt
1
@Matt 好的,那么使用这个方法,我该如何检查Pacman是否仍在路径上或只允许他在路径上? - ComputerLocus
1
@Fogest是的,我本来要把这个发到聊天室里,但你需要20个声望值。我真的很不喜欢这样做。我希望有一种方法可以在有声望的人创建房间时至少覆盖它。如果您想的话,墙可以是-1。基本上,您将每次检查他移动时都会检查此内容,以确保他可以移动到该位置。如果它是int数组,那么您可以为墙壁设定-1,指定0表示无点,指定1表示一个点。 - Matt
@Fogest 首先创建一个二维数组。只需创建一个网格,暂时不要对其进行任何操作。找出你想要的大小。你想要20x20吗?20x30?等等...然后,你可以填充该数组的数据。所以你需要弄清楚墙壁将会在哪里。让我看看能否快速画一张图片。 - Matt
显示剩余15条评论
1个回答

5
一个存储“老派”游戏板的典型方法是使用一个 char int 多维数组。使用Matt的优秀小图形,您可以看到棋盘上有21x21个方格:
int board[21][21] = {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 
                     {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
                     {1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1},
                     /* ... and so on, for all 21 lines .. */                      }};

无论您为墙和路径选择哪些数字都没有关系。"路径"位置最初包含一个"包含点"的代码。当paccy吃掉点时,在该位置将一个新值存储到板子上,以指示已经消耗了点,但它仍然是一个通道方块。Matt建议用-1表示墙,0表示没有点,1表示有点--这是一个相当好的计划,因为它让您的"墙碰撞"例程只需寻找。

if (board[pac.x][pac.y] > 0) {
    /* still in bounds */
} else {
    /* collided against a wall */
}

缺点是在数组初始化器中使用-1会显得更加笨拙。

如果这是在C中完成的,使用char board[21][21]代替int board[21][21]并将游戏板存储为C字符串将很容易“改进”:

char board[21][21] = " XXXXXXXXXXXXXXXXXXX "
                     " X        X        X "
                     " X XX XXX X XXX XX X "
                     " X                 X "
                     " X XX X XXXXX X XX X "
                     " X    X   X   X    X "
                     " XXXX XXX X XXX XXXX "
                     "    X X       X X    "
                     "XXXXX X XXXXX X XXXXX"
                     "        X   X        "
                     "XXXXX X XXXXX X XXXXX"
                     "    X X       X X    "
                     " XXXX X XXXXX X XXXX "
                     " X        X        X "
                     " X XX XXX X XXX XX X "
                     " X  X           X  X "
                     " XX X X XXXXX X X XX "
                     " X    X   X   X    X "
                     " X XXXXXX X XXXXXX X "
                     " X                 X "
                     " XXXXXXXXXXXXXXXXXXX";

这在源代码中读起来更容易,占用的内存更少,您的墙壁碰撞例程可以如下所示:
if (board[pac.x][pac.y] == 'X') {
    /* collided with a wall */
} else {
    /* still in bounds */
}

尽管编译器会在字符串末尾插入一个NUL,这意味着右下角的正方形永远不能用于路径或墙壁,但稍加努力可以解决这个问题,但并不美观。我记不清足够的Java知识来使其在Java中运行,但如果你觉得这很有吸引力,我相信你可以想出一些办法。

看起来不错。是的,我只是建议使用int,因为我认为在Java中使用int更容易。但显然任何类型都可以。您可以像访问数组一样访问Java中的字符串。 - Matt
我感觉自己像个新手。我真的很困惑。我正在努力理解这个,但我还是卡在这个网格上。 - ComputerLocus
@Fogest 像我说的一样,现在不用担心图形。你只需要让它正常工作,然后再美化它。当你添加图形时,你需要匹配每个坐标有多少像素。现在先让你的网格运行起来,创建一个游戏板。创建你的吃豆人,甚至不用担心鬼怪。让你的吃豆人移动。让他吃东西。你只想让他一次移动一个坐标。 - Matt
1
@Fogest 哦,这很简单。你只需检查坐标是什么。所以,假设吃豆人当前在 (1,5),他想向右移动到 (2,5),也就是 (x,y)。如果你愿意,你可以反转它。无论如何,你需要确保 (2,5) 不是墙壁。所以你要检查数组,比如说如果 (board[1,4] == 0) 那么吃豆人就会移动。吃豆人是一个对象,当你调用 move() 函数时会更新自己。不过这又是另一个话题了。但是,在移动之前,你必须直接调用坐标来确保你能够移动。如果是 -1,那么你就停留在同一坐标。你也可以用字符串做同样的事情。 - Matt
1
@Fogest 你不必把他放在网格上。在你的情况下,因为你不理解对象,我建议只需创建两个变量。PacmanX,PacmanY或其他名称。它们将是整数,对应于他所在的位置。 - Matt
显示剩余30条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接