处理过程中的碰撞检测
Collision detection on Processing
我正在制作 Space Invaders 游戏。非常基本和简单。到目前为止,我有一个可以移动(左右)和射击的射手。我也有一个以某种方式移动的入侵者。我要子弹让入侵者消失
所以我的问题是如何让碰撞检测工作(不是颜色碰撞)?如果有人能告诉我它是如何完成的,那么我将不胜感激。
注意:我过去曾因为输入太多代码而被指责,所以我希望只有 Bullet 和 Invader class 是正确的方法。
ArrayList <Bullet> bullets;
class Bullet
{
float x;
float y;
float speed;
Bullet(float tx, float ty)
{
x = tx;
y = ty;
}
void display()
{
stroke(255, 0, 0);
fill(255);
ellipse(x,y, 10, 10);
}
void move()
{
y -= 5;
}
}
void moveAll()
{
for(Bullet temp : bullets)
{
temp.move();
}
}
void displayAll()
{
for(Bullet temp : bullets)
{
temp.display();
}
}
Cell[][] grid;
float i, j;
boolean b3=false;
boolean b4=true;
boolean b5=false;
int cols = 5;
int rows = 2;
color pixel;
class Cell {
float cX,cY;
Cell(float tempX, float tempY, float tempW, float tempH) {
cX = tempX;
cY = tempY;
}
void display2() {
stroke(255, 0, 0);
fill(255, 0, 0);
rect(cX+30,cY+100,5,5);
rect(cX+35,cY+95,5,5);
rect(cX+35,cY+90,5,5);
rect(cX+40,cY+85,5,5);
rect(cX+45,cY+80,5,5);
rect(cX+50,cY+80,5,5);
rect(cX+55,cY+75,5,5);
rect(cX+60,cY+75,5,5);
rect(cX+65,cY+75,5,5);
rect(cX+70,cY+75,5,5);
rect(cX+75,cY+80,5,5);
rect(cX+80,cY+80,5,5);
rect(cX+85,cY+85,5,5);
rect(cX+90,cY+90,5,5);
rect(cX+90,cY+95,5,5);
rect(cX+95,cY+100,5,5);
rect(cX+95,cY+105,5,5);
rect(cX+95,cY+110,5,5);
rect(cX+95,cY+115,5,5);
rect(cX+90,cY+120,5,5);
rect(cX+85,cY+120,5,5);
rect(cX+80,cY+120,5,5);
rect(cX+75,cY+115,5,5);
rect(cX+70,cY+115,5,5);
rect(cX+70,cY+120,5,5);
rect(cX+70,cY+125,5,5);
rect(cX+65,cY+115,5,5);
rect(cX+60,cY+115,5,5);
rect(cX+55,cY+115,5,5);
rect(cX+55,cY+120,5,5);
rect(cX+55,cY+125,5,5);
rect(cX+50,cY+115,5,5);
rect(cX+45,cY+115,5,5);
rect(cX+45,cY+120,5,5);
rect(cX+40,cY+120,5,5);
rect(cX+35,cY+120,5,5);
rect(cX+30,cY+115,5,5);
rect(cX+30,cY+110,5,5);
rect(cX+30,cY+105,5,5);
rect(cX+40,cY+125,5,5);
rect(cX+40,cY+130,5,5);
rect(cX+45,cY+135,5,5);
rect(cX+50,cY+140,5,5);
rect(cX+55,cY+140,5,5);
rect(cX+60,cY+140,5,5);
rect(cX+65,cY+140,5,5);
rect(cX+70,cY+140,5,5);
rect(cX+75,cY+140,5,5);
rect(cX+80,cY+135,5,5);
rect(cX+85,cY+130,5,5);
rect(cX+85,cY+125,5,5);
if(b4==true) { //moving right
b3 = false;
b5 = false;
cX += 2;
}
else if(b5==true) { //moving left
b3 = false;
b4 = false;
cX -= 2;
}
if( (b4 == true && cX >= 780) || (b5 == true && cX <= -1))
{
b3 = true; //moving down
b4 = false;
b5 = false;
}
if( b3 == true) //moving down
{
cY += 3;
if (cY % 10 == 0) //moving down 10 pixels
{
b3=false;
if ( cX >= 780) //if it is on the right edge
{
b4 = false;
b5 = true;
}
else if ( cX <= -1 ) //if it is on the left edge
{
b4 = true;
b5 = false;
cY += 3;
}
}
}
}
void monster()
{
display2();
}
}
有很多方法可以处理碰撞检测,这使得这个问题非常宽泛。但我将重点介绍两种可能有用的方法:
方法一:圆形碰撞
如果您知道两个物体的中心和大小,您可以简单地使用 dist()
函数计算出两个物体相距多远。如果该距离小于它们的大小,则对象正在碰撞。
这是一个小例子:
void setup() {
size(500, 500);
ellipseMode(RADIUS);
}
void draw() {
background(0);
float circleOneX = width/2;
float circleOneY = height/2;
float circleOneRadius = 50;
float circleTwoX = mouseX;
float circleTwoY = mouseY;
float circleTwoRadius = 100;
if (dist(circleOneX, circleOneY, circleTwoX, circleTwoY) < circleOneRadius + circleTwoRadius) {
//colliding!
fill(255, 0, 0);
} else {
//not colliding!
fill(0, 255, 0);
}
ellipse(circleOneX, circleOneY, circleOneRadius, circleOneRadius);
ellipse(circleTwoX, circleTwoY, circleTwoRadius, circleTwoRadius);
}
方法二:矩形碰撞
或者,您可以在对象周围定义一个边界框。然后您只需要一系列 if 语句来检查这些框是否完全重叠。如果是这样,那么对象正在碰撞。
这是一个小例子:
void setup() {
size(500, 500);
}
void draw() {
background(0);
float rectOneX = width/2;
float rectOneY = height/2;
float rectOneWidth = 50;
float rectOneHeight = 50;
float rectTwoX = mouseX;
float rectTwoY = mouseY;
float rectTwoWidth = 100;
float rectTwoHeight = 100;
if (rectOneX < rectTwoX + rectTwoWidth &&
rectOneX + rectOneWidth > rectTwoX &&
rectOneY < rectTwoY + rectTwoHeight &&
rectOneHeight + rectOneY > rectTwoY) {
//colliding!
fill(255, 0, 0);
} else {
//not colliding!
fill(0, 255, 0);
}
rect(rectOneX, rectOneY, rectOneWidth, rectOneHeight);
rect(rectTwoX, rectTwoY, rectTwoWidth, rectTwoHeight);
}
Processing 附带的 the button example 中介绍了这两种方法。
我正在制作 Space Invaders 游戏。非常基本和简单。到目前为止,我有一个可以移动(左右)和射击的射手。我也有一个以某种方式移动的入侵者。我要子弹让入侵者消失
所以我的问题是如何让碰撞检测工作(不是颜色碰撞)?如果有人能告诉我它是如何完成的,那么我将不胜感激。
注意:我过去曾因为输入太多代码而被指责,所以我希望只有 Bullet 和 Invader class 是正确的方法。
ArrayList <Bullet> bullets;
class Bullet
{
float x;
float y;
float speed;
Bullet(float tx, float ty)
{
x = tx;
y = ty;
}
void display()
{
stroke(255, 0, 0);
fill(255);
ellipse(x,y, 10, 10);
}
void move()
{
y -= 5;
}
}
void moveAll()
{
for(Bullet temp : bullets)
{
temp.move();
}
}
void displayAll()
{
for(Bullet temp : bullets)
{
temp.display();
}
}
Cell[][] grid;
float i, j;
boolean b3=false;
boolean b4=true;
boolean b5=false;
int cols = 5;
int rows = 2;
color pixel;
class Cell {
float cX,cY;
Cell(float tempX, float tempY, float tempW, float tempH) {
cX = tempX;
cY = tempY;
}
void display2() {
stroke(255, 0, 0);
fill(255, 0, 0);
rect(cX+30,cY+100,5,5);
rect(cX+35,cY+95,5,5);
rect(cX+35,cY+90,5,5);
rect(cX+40,cY+85,5,5);
rect(cX+45,cY+80,5,5);
rect(cX+50,cY+80,5,5);
rect(cX+55,cY+75,5,5);
rect(cX+60,cY+75,5,5);
rect(cX+65,cY+75,5,5);
rect(cX+70,cY+75,5,5);
rect(cX+75,cY+80,5,5);
rect(cX+80,cY+80,5,5);
rect(cX+85,cY+85,5,5);
rect(cX+90,cY+90,5,5);
rect(cX+90,cY+95,5,5);
rect(cX+95,cY+100,5,5);
rect(cX+95,cY+105,5,5);
rect(cX+95,cY+110,5,5);
rect(cX+95,cY+115,5,5);
rect(cX+90,cY+120,5,5);
rect(cX+85,cY+120,5,5);
rect(cX+80,cY+120,5,5);
rect(cX+75,cY+115,5,5);
rect(cX+70,cY+115,5,5);
rect(cX+70,cY+120,5,5);
rect(cX+70,cY+125,5,5);
rect(cX+65,cY+115,5,5);
rect(cX+60,cY+115,5,5);
rect(cX+55,cY+115,5,5);
rect(cX+55,cY+120,5,5);
rect(cX+55,cY+125,5,5);
rect(cX+50,cY+115,5,5);
rect(cX+45,cY+115,5,5);
rect(cX+45,cY+120,5,5);
rect(cX+40,cY+120,5,5);
rect(cX+35,cY+120,5,5);
rect(cX+30,cY+115,5,5);
rect(cX+30,cY+110,5,5);
rect(cX+30,cY+105,5,5);
rect(cX+40,cY+125,5,5);
rect(cX+40,cY+130,5,5);
rect(cX+45,cY+135,5,5);
rect(cX+50,cY+140,5,5);
rect(cX+55,cY+140,5,5);
rect(cX+60,cY+140,5,5);
rect(cX+65,cY+140,5,5);
rect(cX+70,cY+140,5,5);
rect(cX+75,cY+140,5,5);
rect(cX+80,cY+135,5,5);
rect(cX+85,cY+130,5,5);
rect(cX+85,cY+125,5,5);
if(b4==true) { //moving right
b3 = false;
b5 = false;
cX += 2;
}
else if(b5==true) { //moving left
b3 = false;
b4 = false;
cX -= 2;
}
if( (b4 == true && cX >= 780) || (b5 == true && cX <= -1))
{
b3 = true; //moving down
b4 = false;
b5 = false;
}
if( b3 == true) //moving down
{
cY += 3;
if (cY % 10 == 0) //moving down 10 pixels
{
b3=false;
if ( cX >= 780) //if it is on the right edge
{
b4 = false;
b5 = true;
}
else if ( cX <= -1 ) //if it is on the left edge
{
b4 = true;
b5 = false;
cY += 3;
}
}
}
}
void monster()
{
display2();
}
}
有很多方法可以处理碰撞检测,这使得这个问题非常宽泛。但我将重点介绍两种可能有用的方法:
方法一:圆形碰撞
如果您知道两个物体的中心和大小,您可以简单地使用 dist()
函数计算出两个物体相距多远。如果该距离小于它们的大小,则对象正在碰撞。
这是一个小例子:
void setup() {
size(500, 500);
ellipseMode(RADIUS);
}
void draw() {
background(0);
float circleOneX = width/2;
float circleOneY = height/2;
float circleOneRadius = 50;
float circleTwoX = mouseX;
float circleTwoY = mouseY;
float circleTwoRadius = 100;
if (dist(circleOneX, circleOneY, circleTwoX, circleTwoY) < circleOneRadius + circleTwoRadius) {
//colliding!
fill(255, 0, 0);
} else {
//not colliding!
fill(0, 255, 0);
}
ellipse(circleOneX, circleOneY, circleOneRadius, circleOneRadius);
ellipse(circleTwoX, circleTwoY, circleTwoRadius, circleTwoRadius);
}
方法二:矩形碰撞
或者,您可以在对象周围定义一个边界框。然后您只需要一系列 if 语句来检查这些框是否完全重叠。如果是这样,那么对象正在碰撞。
这是一个小例子:
void setup() {
size(500, 500);
}
void draw() {
background(0);
float rectOneX = width/2;
float rectOneY = height/2;
float rectOneWidth = 50;
float rectOneHeight = 50;
float rectTwoX = mouseX;
float rectTwoY = mouseY;
float rectTwoWidth = 100;
float rectTwoHeight = 100;
if (rectOneX < rectTwoX + rectTwoWidth &&
rectOneX + rectOneWidth > rectTwoX &&
rectOneY < rectTwoY + rectTwoHeight &&
rectOneHeight + rectOneY > rectTwoY) {
//colliding!
fill(255, 0, 0);
} else {
//not colliding!
fill(0, 255, 0);
}
rect(rectOneX, rectOneY, rectOneWidth, rectOneHeight);
rect(rectTwoX, rectTwoY, rectTwoWidth, rectTwoHeight);
}
Processing 附带的 the button example 中介绍了这两种方法。