我正在尝试重新突破,但是在角落和球之间的互动让我头疼不已。从窗户的边缘反弹,块体工作得很好,从窗户的角落反弹也很完美。为简单起见,所有块都是轴对齐的。交换x和y移动仅适用于8个案例中的2个。对于其他6个,必须反转一个或两个向量才能使碰撞正确,但我无法想出一种方法以简单的方式做到这一点。编写8个if语句不正确,容易引起错误。
Ball类是Ellipse2D.Double类的扩展。
Block类是Rectangle类的扩展。
我看过的每个问题/答案/教程要么过于复杂(不是AA rects,矩形不在固定位置),简化(处理好像两个碰撞碰撞)或完全脱离主题(检测碰撞/重叠) ,球对球处理)。
这是我得到的:
public void move(Paddle p, List<Block> b) {
//called every frame
this.x += dx;
this.y += dy;
checkCollisionsWalls();
// checkCollisionPaddle(p);
checkCollisionBlocks(b);
if (this.dir == 90 || this.dir == 270)
this.dir++;
// make sure ball wont get stuck between two walls of window
}
private void checkCollisionBlocks(List<Block> b) {
for (Block block : b) {
if (this.intersects(block)) {
if (this.x + this.width / 2 >= block.x && this.x + this.width / 2 <= block.x + block.width) {
System.out.println("Top / Bot reflect");
this.dy *= -1;
break;
}
if (this.y + this.height / 2 >= block.y && this.y + this.height / 2 <= block.y + block.height) {
System.out.println("Left / Right reflect");
this.dx *= -1;
break;
}
// if execution got here we must have hit a corner
reflectCorner();
}
}
}
private void reflectCorner() {
if (dx > dy) {
this.dy *= -1;
} else {
this.dx *= -1;
}
if (Math.abs(dx) == Math.abs(dy)) {
this.dy *= -1;
this.dx *= -1;
}
double temp = this.dx;
this.dx = this.dy;
this.dy = temp;
temp = 0;
}
dx和dy是Ball类中的全局变量,实际上所有代码都是(仍然)在Ball类中。
编辑:
很抱歉看到问一个明确问题的部分,我对它有点了解......
这个当前代码发生了什么:
从任何方向击中右下角时,反射效果很好
击中左上角会导致球卡在直肠内。然后它沿边缘漂移到右下角
在平行于x轴移动的同时触摸右上角和在平行于y轴移动时触摸左下角时,球反射两次,在正y或正x方向上每次反弹一个像素(正交的轴正在移动)
所有其他反射都很好。
应该怎么做:
reflectCorner()
方法适用于所有角落,就像右下角一样,不会产生如上所述的结果。
问题: 如果没有过于复杂的if-structures,我该怎么做呢?
如有必要,我可以提供我使用的测试设置。
答案 0 :(得分:0)
我终于设法让它在各方面都有效。首先,我通过检查球的中心和任何角落之间的距离是否小于/等于球的半径来计算击中了哪个角。然后我交换x和y运动。对于所有需要的两个角落,对于后两个角落,我必须根据球的角落和方向反转其中一个角落。
最后:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<android.support.constraint.ConstraintLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
tools:context="appname.coname.com.appname" >
<android.support.v7.widget.Toolbar
android:id="@+id/global_header"
android:minHeight="?attr/actionBarSize"
android:background="@android:color/white"
android:layout_width="match_parent"
android:layout_height="64dp"
android:elevation="4dp">
<TextView
android:id="@+id/global_header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="22sp"
android:textColor="@color/colorPrimaryDark"
android:layout_gravity="left"
android:paddingLeft="10dp" />
<ImageView
android:id="@+id/header_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:layout_gravity="end"
android:src="@drawable/menu_icon" />
</android.support.v7.widget.Toolbar>
<TextView
android:id="@+id/sample_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"
android:textColor="#000000"
android:text="Hello, World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_marginTop="64dp"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="@android:color/white" />
</android.support.v4.widget.DrawerLayout>
更多我不是自己的,而且相对紧凑。不过,如果有人有更简单的想法,你仍然可以回答,我会测试它。