简体   繁体   English

Java 2d 游戏中的路径查找?

[英]Path finding in a Java 2d Game?

Essentially its a pacman clone game I'm working on.本质上,它是我正在开发的一款 pacman 克隆游戏。 I have an Enemy class, and 4 instances of this class created which all represent 4 ghosts of the game.我有一个 Enemy class,以及这个 class 的 4 个实例,它们都代表游戏的 4 个幽灵。

All ghosts start up in random areas of the screen and then they have to work their way towards the pacman character.所有的幽灵都在屏幕的随机区域开始,然后他们必须朝着吃豆人角色前进。 As the player controls the pacman, moving it around, they should follow it and take the nearest possible way towards him.当玩家控制 pacman 并移动它时,他们应该跟随它并尽可能靠近他。

There is no maze/obstacles (yet) so the entire map (400x400 pixels) is open ground to them.没有迷宫/障碍物(还没有),因此整个 map(400x400 像素)对它们都是开放的。

For the player and each Ghost, i can retrieve the X, Y, image width and height attributes.对于玩家和每个 Ghost,我可以检索 X、Y、图像宽度和高度属性。 Also, i already have a collision detection algorithm, so not worried about that, just about the ghosts finding their way to pacman.另外,我已经有一个碰撞检测算法,所以不用担心,只是鬼魂找到了吃豆人的路。

For a good pathfinding algorithm, using A* would probably be a good idea, however, for a simple game that doesn't require sophisticated, efficient, nor effective path searching, simply having the characters move toward a target by finding out the direction of the target should be sufficient.对于一个好的寻路算法,使用A*可能是一个好主意,然而,对于一个不需要复杂、高效或有效路径搜索的简单游戏,只需通过找出方向来让角色朝着目标移动目标应该足够了。

For example, the decision to make the character move, in pseudocode:例如,让角色移动的决定,在伪代码中:

if (target is to the left of me):
    move(left);
else
    move(right);

if (target is above me):
    move(up);
else
    move(down);

Yes, the character is not going to make the most efficient movement, but it will get closer and closer to the target on each iteration of the game loop.是的,角色不会做出最有效的移动,但它会在游戏循环的每次迭代中越来越接近目标。

It's also my guess that an arcade game from the early 80's probably wouldn't be using sophisticated pathfinding algorithms.我也猜测 80 年代初期的街机游戏可能不会使用复杂的寻路算法。

If you just have a grid of pixels - an "big field" on which pacman and ghost can move about freely - then the shortest path is easy - a straight line between the ghost and the pacman.如果你只有一个像素网格——一个 pacman 和 ghost 可以在上面自由移动的“大场”——那么最短路径很简单——ghost 和 pacman 之间的直线。

But "shortest path" invariably means we're trying to solve a graph-theory problem.但是“最短路径”总是意味着我们正在尝试解决图论问题。 (I'm assuming knowledge of graphs, some graph theory, adj. matrices, etc!) (我假设了解图、一些图论、adj. 矩阵等!)

In the case above, consider each pixel to be a node on a graph.在上述情况下,将每个像素视为图上的一个节点。 Each node is connected to its neighbors by an edge, and each edge has equal "weight" (moving to the node on "above" is no slower than moving to the node "below").每个节点通过一条边连接到它的邻居,并且每条边都具有相等的“权重”(移动到“上方”的节点并不比移动到“下方”的节点慢)。

So you have this: ("*" = node, "-, /, \, |" = edge)所以你有这个:(“*”=节点,“-,/,\,|”=边缘)

*-*-*
|\|/|
*-*-*  ... (etc)
|/|\|
*-*-* 

If Pacman is in the center, it can move to any other node very easily.如果 Pacman 在中心,它可以很容易地移动到任何其他节点。

Something more closer to reality might be this:更接近现实的可能是这样的:

*-*-*
| | |
*-*-*  ... (etc)
| | |
*-*-* 

Now, pacman cannot move diagonally.现在,吃豆人不能对角移动。 To go from the center to the bottom-right requires 2 "hops" rather than one.从中心到右下角到 go 需要 2 个“跃点”而不是 1 个。

To continue the progression:继续前进:

*-*-*-*
| | | |
| | | |
| | | |
*-*-*-*
| | | |
*-*-*-*

Now, to go from a node in the middle to a node at the top, you need 3 hops.现在,从中间节点到顶部节点到 go,需要 3 跳。 However, to move toward the bottom only takes 1 hop.然而,向底部移动只需要 1 跳。

It would be easy to translate any game-board setup into a graph.将任何游戏板设置转换为图形很容易。 Each "intersection" is a node.每个“交叉点”都是一个节点。 The path between two intersections is an edge, and the length of that path is the weight of that edge.两个交点之间的路径是一条边,该路径的长度是该边的权重。

Enter A*.进入一个*。 By constructing a graph (use an adjency matrix or a list of nodes), you can use the A* algorithm to find the shortest path.通过构建图(使用邻接矩阵或节点列表),您可以使用 A* 算法找到最短路径。 Other algorithms include Dijkstra's.其他算法包括 Dijkstra 算法。 And many others, But first you need to frame your problem in terms of a graph.还有很多其他的,但首先你需要用图表来描述你的问题。 and then toy with how you'd go from node A (pacman) to node B (ghost).然后玩弄如何将 go 从节点 A (pacman) 到节点 B (ghost)。

Hope that helps!希望有帮助!

It's been a very long time, but from memory the ghosts in Pac-Man didn't do much in the way of pathfinding.已经很久了,但是从 memory 开始,Pac-Man 中的幽灵在寻路方面并没有做太多事情。 They would do a fairly standard randomized maze traversal until they "spotted" you, which involved finding an unobstructed path along the axis of a corridor towards you, and then they would move directly towards you until you disappeared from their line of sight, whereupon they would resume a random pattern.他们会做一个相当标准的随机迷宫遍历,直到他们“发现”你,这包括沿着走廊的轴线找到一条通向你的通畅路径,然后他们会直接向你移动,直到你从他们的视线中消失,然后他们将恢复随机模式。 On higher levels Pac-Man would leave invisible trails behind him for a while that the ghosts would "smell" and sometimes follow.在更高的级别上,吃豆人会在他身后留下一段时间的隐形痕迹,鬼会“闻到”并有时会跟随。

When Pac-Man got a power up, the only difference in the algorithm is that, when they spotted you, the ghosts would flee you instead of moving towards you.当吃豆人启动时,算法的唯一区别是,当他们发现你时,鬼魂会逃离你而不是向你移动。

So, for an authentic experience, you probably don't need a very sophisticated pathfinding algorithm at all.因此,为了获得真实的体验,您可能根本不需要非常复杂的寻路算法。 If you want to be fancy, of course, you can implement A*.如果你想花哨,当然可以实现A*。

Walking directly towards your enemies is a start but when you add a maze you'll want to add a bit smarter pathfinding so your ghosts don't get stuck in bends or dead ends.直接走向你的敌人是一个开始,但是当你添加一个迷宫时,你会想要添加一些更智能的寻路功能,这样你的幽灵就不会陷入弯道或死胡同。

The following tutorial is a great lightweight guide to get started with A*, with downloadable examples.以下教程是一个很棒的轻量级 A* 入门指南,带有可下载的示例。

Path Finding on Tile based Maps基于瓦片的地图上的路径查找

in Pacman all of the ghost had a different chasing algorithm在吃豆人中,所有的幽灵都有不同的追逐算法

  • Blinky -> Chases.眨眼->追逐。 Will usually take the shortest route to you, and tends to follow.通常会采取最短的路线到达您,并倾向于遵循。
  • Pinky -> Ambushes.小指 -> 伏击。 Tends to take a more roundabout way to pac-man.吃豆人倾向于采取更迂回的方式。 Deadly.致命。 (pinky and blinky tend to make different choice when choosing a direction, often caging the player in a corner) (pinky和blinky在选择方向时往往会做出不同的选择,经常把玩家困在角落里)
  • Inky -> Freak.漆黑->怪胎。 This dude acts strangely.这家伙的行为很奇怪。 He moves about the board fairly randomly, but sometimes chases when he gets in close.他在棋盘上相当随意地移动,但有时在他靠近时会追逐。
  • Clyde -> Idiot.克莱德->白痴。 Moves randomly.随机移动。 Not much of a threat.威胁不大。

The ghosts have an interesting pattern programmed into their movements: occasionally, they will simultaneously cease and desist their pursuit of Pac-Man and return to their respective corners of the maze, entering "scatter mode".鬼魂的动作有一个有趣的模式:偶尔,它们会同时停止和停止对吃豆人的追求,并返回各自的迷宫角落,进入“分散模式”。

there is a full description of the algo at the pacman dossierpacman dossier中有关于算法的完整描述

regards问候

Guillaume纪尧姆

You could start looking at A* (A star)你可以开始看 A*(A 星)

And here is a page that has links to other path finding algorithms.这是一个链接到其他寻路算法的页面

[edit] gah... brain is too slow... forgot about this book, it is C or C++ (I forget which), but you can still get the concepts for Java. [edit] gah...大脑太慢了...忘记了这本书,它是 C 或 C++(我忘记了),但是您仍然可以获得 ZD52387880E1EA22817A72D3759213 的概念。 It may not be the easiest for you to read, but isn't bad overall.它可能不是你最容易阅读的,但总体来说还不错。 AI for Game Developers by David M. Bourg, Glenn Seemann . 面向游戏开发人员的 AI,作者:David M. Bourg、Glenn Seemann

I think go for the shortest path algorithm at every move made by pacman.我认为 go 是 pacman 每一步的最短路径算法。 A very good implementation is Dijkstra's algorithm .一个很好的实现是Dijkstra 的算法

Just to summarize: Visualize the maze as a graph with vertices and edges.总结一下:将迷宫可视化为具有顶点和边的图形。 Each edge has a wait (in your case all the edges have same weight).每条边都有一个等待(在你的情况下,所有边都具有相同的权重)。 The algorithm finds the shortest path from source vertice to target vertice by moving one step down each immediate reachable edge.该算法通过将每个直接可达的边向下移动一步来找到从源顶点到目标顶点的最短路径。 Then on the next vertice you do the same and keep on doing until to you get to the target.然后在下一个顶点上你做同样的事情并继续做直到你到达目标。 The first path reached is the shortest path.到达的第一条路径是最短路径。 There can be many optimizations done to this algorithm to speed up the things like taking into account where the pacman was in its previous position and in which direction it moved so that you can get some heiristics in the algorithm.可以对该算法进行许多优化以加快速度,例如考虑 pacman 在其先前的 position 中的位置以及它移动的方向,以便您可以在算法中获得一些启发式。 I would suggest finding the shortest path from each ghost to pacman on every movement and move the ghost in that direction.我建议在每个动作中找到从每个幽灵到吃豆人的最短路径,然后将幽灵朝那个方向移动。 Eventually the distance will reduce and you will be able to catch pacman.最终距离会减少,你将能够赶上吃豆人。

Another heuristic that can be used it to find all the immediate edges reachable from pacman and try to cover as many of these vertices as possible by ghosts.另一种启发式方法,可用于查找 pacman 可到达的所有直接边缘,并尝试通过重影覆盖尽可能多的这些顶点。 So instead of setting pacman as the target vertice we set the vertices immediatetly reachable by pacman as target, the result will be that the available ghosts will try to cover up themajor escape routes of pacman and catch him.因此,我们没有将 pacman 设置为目标顶点,而是将 pacman 立即可到达的顶点设置为目标,结果将是可用的幽灵将试图掩盖 pacman 的主要逃生路线并抓住他。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM