我正在开发类似于高峰时间/交通阻塞/阻塞益智游戏的Android游戏。董事会是一个包含长方形件的广场。长件只能水平移动,而高块件只能垂直移动。目标是释放红色的棋子并将其移出棋盘。这个游戏只是我的第二个任何语言的编程项目,所以任何提示或最佳做法将与您的答案一起赞赏。drag-n-drop益智游戏的碰撞问题
我有一个名为Pieces的游戏作品,它描述了它们的大小和绘制方式,给它们拖放功能以及检测和处理碰撞。
然后我有一个名为GameView的活动类,它创建我的布局并创建Pieces对象以添加到名为Board的RelativeLayout。我曾考虑让董事会成为自己的班级,但还没有需要。
这里就是我的工作进展的样子:
我的问题:
这其中大部分的作品,除了我的冲突处理完全正常。它似乎是在很好地检测到碰撞,而不是在发生碰撞时将它们推到彼此的外面,而是在它被拖拽到的位置和应该在的位置之间(似乎是)之间来回跳动。它看起来像这样:
另一个奇怪的是:当拖动的块与其左边的一块相撞时,碰撞处理似乎完美地工作。只有在上面,下面和右侧出现问题。
这里的碰撞代码:
@Override
public boolean onTouchEvent(MotionEvent event){
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//check if touch is on piece
if (eventX > x && eventX < (x+width) && eventY > y && eventY < (y+height)){
initialX=x;
initialY=y;
break;
}else{
return false;
}
case MotionEvent.ACTION_MOVE:
//determine if piece should move horizontally or vertically
if(width>height){
for (Pieces piece : aPieces) {
//if object equals itself in array, skip to next object
if(piece==this){
continue;
}
//if next to another piece,
//do not allow to move any further towards said piece
if(eventX<x&&(x==piece.right+1)){
return false;
}else if(eventX>x&&(x==piece.x-width-1)){
return false;
}
//move normally if no collision
//if collision, do not allow to move through other piece
if(collides(this,piece)==false){
x = (eventX-(width/2));
}else if(collidesLeft(this,piece)){
x = piece.right+1;
break;
}else if(collidesRight(this,piece)){
x = piece.x-width-1;
break;
}
}
break;
}else if(height>width){
for (Pieces piece : aPieces) {
if(piece==this){
continue;
}else if(collides(this,piece)==false){
y = (eventY-(height/2));
}else if(collidesUp(this,piece)){
y = piece.bottom+1;
break;
}else if(collidesDown(this,piece)){
y = piece.y-height-1;
break;
}
}
}
invalidate();
break;
case MotionEvent.ACTION_UP:
// end move
if(this.moves()){
GameView.counter++;
}
initialX=x;
initialY=y;
break;
}
// parse puzzle
invalidate();
return true;
}
这需要的onDraw过程中发生:
width = sizedBitmap.getWidth();
height = sizedBitmap.getHeight();
right = x+width;
bottom = y+height;
我的碰撞试验方法看起来像这样用不同的数学每个:
private boolean collidesDown(Pieces piece1, Pieces piece2){
float x1 = piece1.x;
float y1 = piece1.y;
float r1 = piece1.right;
float b1 = piece1.bottom;
float x2 = piece2.x;
float y2 = piece2.y;
float r2 = piece2.right;
float b2 = piece2.bottom;
if((y1<y2)&&(y1<b2)&&(b1>=y2)&&(b1<b2)&&((x1>=x2&&x1<=r2)||(r1>=x2&&x1<=r2))){
return true;
}else{
return false;
}
}
private boolean collides(Pieces piece1, Pieces piece2){
if(collidesLeft(piece1,piece2)){
return true;
}else if(collidesRight(piece1,piece2)){
return true;
}else if(collidesUp(piece1,piece2)){
return true;
}else if(collidesDown(piece1,piece2)){
return true;
}else{
return false;
}
}
作为第二个问题,应该我的x,y,右,底部,宽度,高度变量是整数,而不是浮动像他们 现在? 此外,如何更好地实施的任何建议将不胜感激,即使与问题无关!预先感谢您的帮助,并通过这么长的问题坐下来!
更新:
我得到它与下面的代码的工作几乎是完美的(这不包括垂直部分的代码):
@Override
public boolean onTouchEvent(MotionEvent event){
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//check if touch is on piece
if (eventX > x && eventX < (x+width) && eventY > y && eventY < (y+height)){
initialX=x;
initialY=y;
break;
}else{
return false;
}
case MotionEvent.ACTION_MOVE:
//determine if piece should move horizontally or vertically
if(width>height){
for (Pieces piece : aPieces) {
//if object equals itself in array, skip to next object
if(piece==this){
continue;
}
//check if there the possibility for a horizontal collision
if(this.isAllignedHorizontallyWith(piece)){
//check for and handle collisions while moving left
if(this.isRightOf(piece)){
if(eventX>piece.right+(width/2)){
x = (int)(eventX-(width/2)); //move normally
}else{
x = piece.right+1;
}
}
//check for and handle collisions while moving right
if(this.isLeftOf(piece)){
if(eventX<piece.x-(width/2)){
x = (int)(eventX-(width/2));
}else{
x = piece.x-width-1;
}
}
break;
}else{
x = (int)(eventX-(width/2));
}
这段代码的唯一问题是,它仅检测移动件和另一个之间的碰撞(优先选择左侧的碰撞)。如果有一块在左侧碰撞而另一块在右侧碰撞,则它只会检测到与左侧碰撞的碰撞。我认为这是因为一旦发现可能发生的碰撞,它会处理它,而不会完成循环遍历所有片断的数组。我如何得到它在同一时间检查多个可能的碰撞?
我已经回答了您的更新以下的问题 – Timo 2011-03-16 11:52:01