人物跳跃与障碍物碰撞

JJzxz 2012-05-20 07:33:46
本人初学,正在编个小游戏,在碰撞检测遇到点问题,人物跳跃后不能落到障碍物上,或者是落到了不能自己下来,求懂的人帮忙解决下,不胜感激
...全文
384 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-05-24
  • 打赏
  • 举报
回复
现在这个改好了吧
批评不敢当,大家互相学习吧
我觉得代码第一要务是增加可读性以便今后维护(包括自己和他人)
检测的一个方法就是别人可以很轻松地看明白,包括其中的业务逻辑
基本上一个方法名可以概括的一组逻辑代码就可以封装在一个方法中
各种数据硬编码最好以描述性变量名替代等等
使各层逻辑都条理清晰
因为你这里可能牵涉到一些具体业务,比如背景也可能会移动等等,具体也说不上什么。
JJzxz 2012-05-23
  • 打赏
  • 举报
回复
嗯嗯,调用move就动,如果碰撞了人物就不再动,所以我的人物会悬在半空,不知道怎么让他在自由落体到地上,或是在物体上行走,下面我碰撞检测和run方法的代码由于太多,画背景和人物以及MIDlet那部分没加,请多批评

//碰撞检测
public void isCrash(){
if(MaLi.collidesWith(layer1, false)){

flag=false;
}
else if(MaLi.collidesWith(layer4, false)){
score=score+10;
flag=false;
}
else if(MaLi.collidesWith(emy1,false)){
score=score+10;
manager.remove(emy1);
eat=true;
}
else
flag=true;
}


//run方法
public void run() {
while(RUN){
gra.setColor(230, 230,255);
gra.fillRect(0, 0, this.getWidth(), this.getHeight());
if(eat){
manager.append(emy1);
emy1.setPosition(new Random().nextInt(this.getWidth()), 180);
eat=false;
}
if(MaLi.getY()>this.getHeight()-MaLi.getHeight())
MaLi.setPosition(MaLi.getX(),this.getHeight()-MaLi.getHeight() );
int state=this.getKeyStates();
switch(state){
case GameCanvas.LEFT_PRESSED:
if(MaLi.getX()>0){
MaLi.move(-10, 0);
}
else{
MaLi.move(40, 0);
emy1.move(50, 30);
layer1.move(50, 0);
layer2.move(50, 0);
layer3.move(50, 0);
layer4.move(50, 0);
}
isCrash();
if(!flag)
MaLi.move(10, 0);

break;
case GameCanvas.RIGHT_PRESSED:
MaLi.nextFrame();
if(MaLi.getX()<this.getWidth()-MaLi.getWidth()){
MaLi.move(10, 0);
}
else{
MaLi.move(-40, 0);
emy1.move(-50, 0);
layer1.move(-50, 0);
layer2.move(-50, 0);
layer3.move(-50, 0);
layer4.move(-50, 0);
}
isCrash();
if(!flag)
MaLi.move(-10, 0);
break;
case GameCanvas.UP_PRESSED:
if(MaLi.getY()>0){

//MaLi.move(0, -15);
new GameUP(this,MaLi);

}
isCrash();
if(!flag){
MaLi.move(0, 15);
}
break;
case GameCanvas.DOWN_PRESSED:
if(MaLi.getY()<this.getHeight()-MaLi.getHeight()){
MaLi.move(0, 15);
}
isCrash();
if(!flag){
MaLi.move(0,-15);
}
break;
default:
break;
}
gra.setColor(0, 0, 0);
gra.setFont(Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_ITALIC,Font.SIZE_MEDIUM));
gra.drawString("Score:"+String.valueOf(score), 0, 0, Graphics.LEFT|Graphics.TOP);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
manager.paint(gra,0,0);
if(MaLi.getX()>layer1.getWidth()-50){
gra.setColor(255, 0, 0);
gra.setFont(Font.getFont(Font.FONT_STATIC_TEXT,Font.STYLE_BOLD,Font.SIZE_LARGE));
gra.drawString("闯关成功!", this.getWidth()/2, this.getHeight()/2, Graphics.HCENTER|Graphics.VCENTER);
RUN=false;
}
this.flushGraphics();

}
}
dracularking 2012-05-23
  • 打赏
  • 举报
回复
感觉问题不少,我说一下我的观点:
首先是可读性差,不按面向对象封装,比如跳跃,就应该是属于人物对象的一个方法
物体的移动不要割裂出许多单独的方面,越统一的规则越好
再看逻辑,我看到的是:
if (flag) {
if (sprite.collidesWith(gb.layer1, false)) {
flag = false;
}
sprite.move(0, move_Y[i]);
}
是先检测了是否碰撞,如果碰撞了,但还是能移动,这里是不是有问题。

再说障碍物很多,是不是都要判断的问题,如果不判断怎么知道是否碰撞呢?你可能可以通过预先得知的障碍物位置而预制行动路线,首先这有点违背统一行动规则(有的是通过判断,有的是通过预制),其次要是存在事先无法知道位置的物体(比如移动物体),这种就失效,所以我认为还是通过判断的方式更简洁统一。
dracularking 2012-05-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

我编的代码不是很多,可能实现方式不太正规,理解了你的意思容我再想想,非常感谢你的回答
[/Quote]
我觉得你这个调试一下看原因会很清楚
我这里看的话,因为你代码中move方法就一处,是不是本意是不调用move人物就不动?
而一旦检测到碰撞,flag置为false后,就不会再调用move,但是却会不断削减y值。
JJzxz 2012-05-23
  • 打赏
  • 举报
回复
我编的代码不是很多,可能实现方式不太正规,理解了你的意思容我再想想,非常感谢你的回答
JJzxz 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
最普遍的就是矩形碰撞检测吧,不管是人物还是障碍物都是矩形,就是检测所控人物的矩形是否会与它移动路径上的障碍物矩形之间碰撞(矩形相交)
move() {
if(!wouldCollide()) {
moveOneStep();
}
}

关键是wouldCollide方法实现是 当前位置+欲移动单位距离 是否与障碍物碰撞
[/Quote]
public class GameUP extends GameCanvas implements Runnable {
private Sprite sprite;
GameBack gb = new GameBack();
boolean flag = gb.flag;

public GameUP(GameBack gb, Sprite s) {
super(true);
this.sprite = s;
this.gb = gb;
new Thread(this).start();
}

public void run() {
int move_Y[] = { -20, -18, -13, -9, -3, -1, 1, 3, 9, 13, 18, 20 };
int y = move_Y.length;
while (y > 0) {
for (int i = 0; i < move_Y.length; i++) {
if (flag) {
if (sprite.collidesWith(gb.layer1, false)) {
flag = false;
}
sprite.move(0, move_Y[i]);


} else
y = -1;
y--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

}

这是我实现跳跃的类,当按向上键跳跃的时候实例化这个类的对象,实现向上跳后落回地下的过程,但现在碰撞到背景障碍物后怎么才能让它落到上面,并在离开的时候自己下落到地上,背景的障碍物很多,总不能一个一个判断当前位置吧,那样不会很麻烦吗?
dracularking 2012-05-22
  • 打赏
  • 举报
回复
最普遍的就是矩形碰撞检测吧,不管是人物还是障碍物都是矩形,就是检测所控人物的矩形是否会与它移动路径上的障碍物矩形之间碰撞(矩形相交)
move() {
if(!wouldCollide()) {
moveOneStep();
}
}

关键是wouldCollide方法实现是 当前位置+欲移动单位距离 是否与障碍物碰撞
JJzxz 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
这个说滴比较空洞。。
[/Quote]
我不太会提问题可能我的表达大家不能白,我就是想要一个方法,如何实现就好,我用了碰撞检测,发生碰撞后退回,但是碰撞后它不能保持它呆在障碍物上,或是退回去后就悬在半空过了障碍物后也不会自由落体到地面
ruancaipu 2012-05-21
  • 打赏
  • 举报
回复
这个说滴比较空洞。。
JJzxz 2012-05-20
  • 打赏
  • 举报
回复
拜托各位,知道的帮忙解答下,真的是想了很久都没想出来

13,097

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧