我正在构建一个迷宫游戏,在这里我有一个简单的地图...
直到没有问题,但我的问题是碰撞
这是我的地图:
在这里,我用以下代码自己构建了地图:
package maze;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
public class Maze1 extends GameObject{
public Maze1(int x, int y, ID id) {
super(x, y, id);
}
public void tick() {
}
public void render(Graphics g){
Font fnt = new Font("arial", 1, 25);
g.setFont(fnt);
g.drawString("Level : 1",165 , 433);
//x, y, WIDTH, HEIGHT
g.setColor(Color.darkGray);
g.fillRect(65, 65, 130 ,15);
g.fillRect(0, 130, 145 ,15);
g.fillRect(195, 195, 400 ,15);
g.fillRect(65, 195, 80 ,15);
g.fillRect(130, 260, 80 ,15);
g.fillRect(65, 325, 195 ,15);
g.fillRect(325, 325, 80 ,15);
// x, y, WIDTH, HEIGHT
g.fillRect(195, 130, 80 ,80);
g.fillRect(260, 0, 145 ,80);
//x, y, HEIGHT, WIDTH
g.fillRect(65, 145, 15 ,130);
g.fillRect(195, 65, 15 ,195);
g.fillRect(260, 260, 15 ,130);
g.fillRect(325, 130, 15 ,80);
g.fillRect(325, 260, 15 ,65);
g.setColor(Color.black);
g.fillRect(0, -20, 500 ,32); //x, y, WIDTH, HEIGHT
g.fillRect(0, 390, 500 ,15);
g.fillRect(0, Game.HEIGHT - 41, 500 ,30);
g.fillRect(-20, 0, 32 ,500);
g.fillRect(Game.WIDTH -18, 0, 32 ,340);
g.fillRect(Game.WIDTH -18, 400, 32 ,100);
}
}
此碰撞代码用于右上角矩形
我已经尝试了两种不同类型的碰撞代码,但都不起作用
碰撞码:
public void collision() {
if(this.getX() >=229 && this.getY() <= 79) {
if(this.getX() >=229) {
this.setVelX(0);
this.setVelY(0);
this.setX(this.getX() -1);
}
if(this.getY() <= 79){
this.setVelX(0);
this.setVelY(0);
this.setY(this.getY() +1);
}
}
在这里,当玩家从左侧击中矩形时,玩家向下移动,当玩家从底部击中矩形时,玩家向左移动。
我用if, else if语句尝试过相同的代码,但仍然不起作用。当玩家点击左侧时,它可以完美地工作,但当玩家从底部点击矩形时,它会传送到矩形的边缘。
我希望我的描述足够清楚,能让你描绘出我的处境。
提前感谢!
对于碰撞检测,我建议将地图数据保留在矩形列表中。类似于:
public class Rect {
public int topLeftX;
public int topLeftY;
public int width;
public int height;
public Rect(int x, int y, int w, int h){
topLeftX = x;
topLeftY = y;
width = w;
height = h;
}
//Ignore the code below here for now
public boolean collidingWith(int x, int y, int width, int height){
Rect r = new Rect(x, y, width, height);
boolean rLeftInWidth = r.topLeftX > topLeftX && r.topLeftX < topLeftX + width;
boolean rRightInWidth = r.topLeftX + r.width > topLeftX && r.topLeftX + width < topLeftX + width;
boolean rTopInHeight = r.topLeftY > topLeftY && r.topLeftY < topLeftY + width;
boolean rBottomInHeight = r.topLeftY + r.width > topLeftY && r.topLeftY + width < topLeftY + width;
if(rLeftInWidth || rRightInWidth){
//If there is horizantal overlap between the other rectangle and this one
if(rTopInHeight || rBottomInHeight){
//If there is also vertical overlap then we must be colliding
return true;
}
}
return false;
}
}
然后,您将矩形保存在数组或某种集合中,ArrayList可能是最简单的。
ArrayList<Rect> wallData = new ArrayList<Rect>();
然后,您可以添加地图数据。这是从您的矩形绘画中获取的:
g.fillRect(65, 65, 130 ,15);
它变成了一个矩形,具有相同的参数。您甚至可以在填充矩形并重用它之前这样做。
wallData.add(new Rect(65, 65, 130, 15));
Rect r = wallData.get(0);
g.fillRect(r.topLeftX, r.topLeftY, r.width, r.height);
那么,现在你有了这些数据,你如何使用它呢?当您想要检查碰撞时,只需循环浏览矩形列表并检查您的播放器是否发生冲突即可。
for(Rect rectangle: wallData){
if(rectangle.collidingWith(<playerX>, <playerY>, <playerWidth>, <playerHeight>)){
//Your player is colliding with a rectangle!
}
}
还记得我之前告诉你不要理会的那一节吗?现在让我们来复习一下。我发誓,这比看起来简单多了!
public boolean collidingWith(int x, int y, int width, int height){
Rect r = new Rect(x, y, width, height);
boolean rLeftInWidth = r.topLeftX > topLeftX && r.topLeftX < topLeftX + width;
boolean rRightInWidth = r.topLeftX + r.width > topLeftX && r.topLeftX + width < topLeftX + width;
boolean rTopInHeight = r.topLeftY > topLeftY && r.topLeftY < topLeftY + width;
boolean rBottomInHeight = r.topLeftY + r.width > topLeftY && r.topLeftY + width < topLeftY + width;
if(rLeftInWidth || rRightInWidth){
//If there is horizantal overlap between the other rectangle and this one
if(rTopInHeight || rBottomInHeight){
//If there is also vertical overlap then we must be colliding
return true;
}
}
return false;
}
}
我们从找出是否水平重叠开始。例如,以下内容水平重叠,但不是垂直重叠。
=-----=
- -
- -
-------
+------
- -
- -
-------
你可以分辨出来,因为带加号的角在相等的角之间。四个布尔值只是判断我们的角是否在另一个物体的角之间。
boolean rLeftInWidth = r.topLeftX > topLeftX && r.topLeftX < topLeftX + width;
如果我们的左上角位于其他矩形的左上角和右上角之间,这将成为现实。然后我们也对右上角这样做。如果其中任何一个是真的,那么我们在水平方向重叠!
从那里,我们只是检查它是否水平和垂直重叠。如果是,它就会碰撞,就像这样!
-------
- -
- ------
----- -
- -
------
现在,当你意识到你的玩家正在碰撞时,你会怎么做?这需要一些工作,但没什么特别的。在通过将玩家的速度添加到其位置来移动玩家之前,只需保存其位置即可。
private int playerX;
private int playerY;
<method where you change it>{
playerX = <playerX>;
playerY = <playerY>;
<change their location according to velocity>
}
现在,如果玩家与墙碰撞,只需将其位置设置回刚才保存的值,并将其速度设置为0!
设置起来有点复杂,但一旦开始,这是一个不错的解决方案。
在这个答案中,我把一大堆东西放在中间
我希望这对你有帮助!如果您有任何疑问,请随时询问,我很乐意提供更多帮助。碰撞检测是一个复杂的主题,有很多方法。这通常是我发现最简单的应用程序。
此方法与您的原始方法相比的优点:
如果您已经创建了矩形列表,您可以使用循环来绘制它们:
for(Rect r: wallData){
g.fillRect(r.topLeftX, r.topLeftY, r.width, r.height);
}
>
易于编辑:如果你决定改变你的地图,你只需要改变一些矩形的宽度、高度和位置,而不是通过一堆if语句来判断这是否是正确的改变。(我以前经历过)
不易出错:为每面墙设置一些矩形比设置大量的if语句要容易得多。
这种方法与原始方法的缺点
>
这一个效率较低——有更多的操作用于检查播放器是否与矩形碰撞,而不是2个ifs。此外,可能还有玩家无法碰撞的矩形。然而,效率上的损失很小,尤其是在地图中矩形数量较少的情况下。
这个更复杂。最好了解您使用的代码,而不是盲目地复制粘贴。如果你需要做出改变,如果你不理解,就会更难。(并不是说你没有,只是可能会更难一些。)
我知道关于这个话题已经有了一些答案,但我不太清楚如何测量相机和物体之间的距离。 我的目标是: 我用OpenCV通过颜色检测成功地追踪了一个红色的球。现在我试着在红球的中间点一个激光。当红球移动时,激光器应始终跟随红球。我用一个小伺服电机来转动激光。 我在想,如果我能测量物体和相机之间的距离,我就能计算出伺服需要转动的角度。。。 我试图跟踪卡梅伦·洛厄尔·帕尔默的帖子。 我所做的: 我校准了我的Pi
问题内容: 我主要专注于图形方面,以创建一些2DGame。我看过/看过几本教程,但是没有一部教程那么令人满意。我已经有一个玩家(一个正方形)在屏幕上移动并与其他正方形碰撞。重力等。 如果在屏幕上看到的对象太多(30 * 20),则一切正常。但是,如果我将其增加到300 * 300,则该程序开始运行非常慢,因为它必须检查许多对象。 我真的不知道Minecraft之类的游戏如何与ALL THOSE块一
当我在中创建一个场景时,我经常需要两个节点在完全相同的或位置来创建一面墙。我添加了矩形物理体。它们都没有任何摩擦。 当我使一个spritendode在这些碰撞体上移动时(我对物理体使用冲量),它的行为就像在两个矩形之间有一个屏障,我需要“推”节点或使其跳过边界。正如我所说的,这些节点彼此完全一致,因此节点应该能够平滑地通过它们。 有什么建议吗? 如果你需要我正在使用的任何代码/图片,请询问。 编辑
有人对如何处理Unity中缺少碰撞的快速移动物体有任何建议吗?我正在为移动设备创建一个突破游戏,发现当桨移动得非常快时,它会错过与球的碰撞。我将碰撞更改为连续检测,但这会引发奇怪的行为,例如碰撞时桨被推倒。 我还尝试使用dontgothrough脚本使其适用于2D碰撞器,但没有成功。有人有什么建议吗?
本文向大家介绍Javascript 多物体运动的实现,包括了Javascript 多物体运动的实现的使用技巧和注意事项,需要的朋友参考一下 我们先来看下之前的运动的代码,是否支持多物体运动,会出现怎么样的问题。 以下是Javascript 代码: 此时当鼠标移入到第一个div 时,他是正常运行的。但是如果现在又移动到第二个或者第三个div时候就会出现bug。 image 这个是什么原因呢? 看图可
我有两个身体,都是动态的,其中一个我已经关闭了重力,只有当它被我的另一个身体击中时才想打开它。我知道我可以设置自己的联系人侦听器,但我想指定一个动作,只有当两个特定的身体接触时。 有人有指导吗?