Java 如何确保玩家不会穿过墙
我正在编写我的第一个2D游戏(吃豆人)。我认为比赛看起来不错,但我有一个大问题——碰撞。对象仍然在穿墙。我被它困住了,所以我决定向有丰富经验的真正程序员寻求帮助。(当然我做了一些研究,但我不想做复制和粘贴之类的事情,因为我不明白)。正如我所说的,游戏就要结束了,我所需要做的就是阻止吃豆人通过。例如,我画了一个大的白色矩形作为平台。我希望有人能帮助我。在整个项目中,我学到了很多,我理解碰撞,但不知道如何正确编程。我想我很快就能找到答案了,但有些东西不见了 注:我在WindowBuilder中创建了window,因此编译可能会有问题:(Java 如何确保玩家不会穿过墙,java,swing,collision-detection,collision,windowbuilder,Java,Swing,Collision Detection,Collision,Windowbuilder,我正在编写我的第一个2D游戏(吃豆人)。我认为比赛看起来不错,但我有一个大问题——碰撞。对象仍然在穿墙。我被它困住了,所以我决定向有丰富经验的真正程序员寻求帮助。(当然我做了一些研究,但我不想做复制和粘贴之类的事情,因为我不明白)。正如我所说的,游戏就要结束了,我所需要做的就是阻止吃豆人通过。例如,我画了一个大的白色矩形作为平台。我希望有人能帮助我。在整个项目中,我学到了很多,我理解碰撞,但不知道如何正确编程。我想我很快就能找到答案了,但有些东西不见了 注:我在WindowBuilder中创建了
在代码中更新x和y,但在始终位于其初始位置的“packman”对象中没有这样做;因此,当您检查与墙的交点时,packman始终位于(170,50);我更改了动画方法以反映packman和paint方法中的更改,以便使用更新的packman坐标 动画:
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (count == 1) {
packman.x = packman.x - xVel;
repaint();
zkontrolujKolizi();
}
if (count ==2) {
packman.y = packman.y - yVel;
repaint();
zkontrolujKolizi();
}
if (count ==3) {
packman.x = packman.x + xVel;
repaint();
zkontrolujKolizi();
}
if (count ==4) {
packman.y = packman.y+yVel;
repaint();
zkontrolujKolizi();
}
}
油漆:
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.drawRect(packman.x,packman.y,packman.width,packman.height);
g.setColor(Color.blue);
g.fillRect(packman.x,packman.y,packman.width,packman.height);
g.drawRect(platform.x,platform.y,platform.width,platform.height);
g.setColor(Color.blue);
g.drawRect(secondPlat.x,secondPlat.y,secondPlat.width,secondPlat.height);
g.setColor(Color.blue);
}
当然,代码中还有很多东西需要重构,但这就是为什么没有检测到冲突的原因
要避免穿过墙移动,请计算新位置,检查碰撞,如果为真,请回滚位置更改:
@Override
public void actionPerformed(ActionEvent arg0) {
int rollbackX=packman.x;
int rollbackY=packman.y;
switch (count) {
case 1:
packman.x = packman.x - xVel;
break;
case 2:
packman.y = packman.y - yVel;
break;
case 3:
packman.x = packman.x + xVel;
break;
case 4:
packman.y = packman.y+yVel;
break;
}
//Collision found, rollback
if (zkontrolujKolizi()) {
packman.x=rollbackX;
packman.y=rollbackY;
} else {
repaint();
}
}
public boolean zkontrolujKolizi() {
return packman.intersects(platform) || packman.intersects(secondPlat);
}
我使用了完全相同的方法,但仅限于移动对象
@Override
public void actionPerformed(ActionEvent e) {
//This is my actually code I've implemented from your answer
int rollbackX = packRect.x;
int rollbackY = packRect.y;
switch (count) {
case 1:
packman.setCoordinatesX(packman.getCoordinatesX() - xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x - xVel;
collectPoint();
// repaint();
break;
case 2:
packman.setCoordinatesY(packman.getCoordinatesY() - yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y - yVel;
sbirejBody();
// repaint();
break;
case 3:
packman.setCoordinatesX(packman.getCoordinatesX() + xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x + xVel;
collectPoint();
// repaint();
break;
case 4:
packman.setCoordinatesY(packman.getCoordinatesY() + yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y+yVel;
collectPoint();
// repaint();
break;
}
int originX = packRect.x;
int originY = packRect.y;
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
if (checkCollision) {
rollbackX= originX;
rollbackY = originY;
}else {
repaint();
}
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
}
public boolean checkCollision() {
return packman.intersects(platform) || packman.intersects(secondPlat);
}
代码没有编译,因为缺少一些类,但我很奇怪,在实际移动对象之前检查碰撞。通常应该在“动画”代码中进行检查(缺少这些类,因此我无法检查)@Rocco我得到建议,我应该发布理解我的问题的最低代码,所以我没有添加像ghost或packman这样的简单类。我添加了moving animation,我理解,但请更好地检查MRE是什么:,它必须是最小的,但是完整的;这意味着你必须从头开始,创建一个复制问题的新项目。如果你只需删除部分以减小大小,它就不会编译,而且仅通过目视检查很难发现问题(更不用说许多人甚至不会在这种情况下尝试)。@Rocco好的,我用更少的代码创建了新项目。我的问题是,矩形,,,Pacman“即使我使用了intersect方法,我也能通过吗?我希望我能通过。好吧,但我不是在画组件,或者是吗?我有点困惑?我从来没有用过PAINTCOMPONENT来画画。看起来很好,碰撞被检测到了,但如何不让对象通过呢?我应该使用getHeight()和Width()吗?”方法,比如当我不想离开屏幕时。如果你知道我的意思:D@PeteJerk为了避免穿墙移动,计算新位置,检查碰撞,如果为真,回滚位置更改,最后查看新代码。好的,它可以工作,谢谢。我为pacman在我的项目中实现了它,有碰撞的一切都可以工作,但是在碰撞后我还有一个问题吗?我不知道你是否读过我的answer@PeteJerk如果是关于绘画,最好打开一个新的问题,而不是修改这个问题等等,现在你的打包工不再是rect,所以你必须恢复在列之前更改的所有对象上以前的坐标lision check.@Rocco类似的东西?我编辑了我的问题
@Override
public void actionPerformed(ActionEvent e) {
//This is my actually code I've implemented from your answer
int rollbackX = packRect.x;
int rollbackY = packRect.y;
switch (count) {
case 1:
packman.setCoordinatesX(packman.getCoordinatesX() - xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x - xVel;
collectPoint();
// repaint();
break;
case 2:
packman.setCoordinatesY(packman.getCoordinatesY() - yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y - yVel;
sbirejBody();
// repaint();
break;
case 3:
packman.setCoordinatesX(packman.getCoordinatesX() + xVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.x = packRect.x + xVel;
collectPoint();
// repaint();
break;
case 4:
packman.setCoordinatesY(packman.getCoordinatesY() + yVel);
gifLabel.setLocation(packman.getCoordinatesX(), packman.getCoordinatesY()-38);
packRect.y = packRect.y+yVel;
collectPoint();
// repaint();
break;
}
int originX = packRect.x;
int originY = packRect.y;
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
if (checkCollision) {
rollbackX= originX;
rollbackY = originY;
}else {
repaint();
}
packRect.setLocation(originX, originY);
packman.setCoordinatesX(originX);
packman.setCoordinatesY(originY);
gifLabel.setLocation(originX, originY);
}
public boolean checkCollision() {
return packman.intersects(platform) || packman.intersects(secondPlat);
}