我的代码在碰到蓝色方块时会停止红色方块,但是我不希望红色方块无限期地停止。我该如何解决?
我创建了碰撞检测,如果红色方块碰到蓝色方块,它会使速度= 0。
//r=red
float rx = 200;
float ry = 375;
float rw = 50;
float rh = 50;
//b=blue
float bx = 550;
float by = 375;
float bw = 50;
float bh = 50;
float speed = 2;
//float cspeed = 2;
void setup() {
size(800, 800);
noStroke();
noSmooth();
noCursor();
}
void draw() {
surface.setTitle(mouseX + ", " + mouseY);
background(50);
collision();
move();
display();
}
void collision() {
//Check if blue and red are touching
boolean hit = rectRect(rx, ry, rw, rh, bx, by, bw, bh);
if (hit) {
speed = 0;
} else {
speed = 2;
}
}
void display() {
fill(0, 0, 255); //Blue square
rect(bx, by, bw, bh);
fill(255, 0, 0); //Red square
rect(rx, ry, rw, rh);
}
void move() {
//Red square movement
if (keyPressed) {
if (key == 'd' || key == 'D') {
rx = rx + speed;
if (rx > width) {
}
}
}
if (keyPressed) {
if (key == 'a' || key == 'A') {
rx = rx - speed;
if (rx > width) {
}
}
}
if (keyPressed) {
if (key == 'w' || key == 'W') {
ry = ry - speed;
if (ry > width) {
}
}
}
if (keyPressed) {
if (key == 's' || key == 'S') {
ry = ry + speed;
if (ry > width) {
}
}
}
}
boolean rectRect(float rx, float ry, float rw, float rh, float bx, float by, float bw, float bh) {
//is red touching blue?
if (rx + rw >= bx &&
rx <= bx + bw &&
ry + rh >= by &&
ry <= by + bh) {
return true;
}
return false;
}
我不希望红色方块和蓝色方块重叠,但是如果它们确实接触,我想继续玩。现在,红场无限期地停止。
答案 0 :(得分:2)
在void collision()
中,您设置了发生碰撞时正方形的速度将降低到0.01。
在正方形移动后检查碰撞 。
一旦正方形发生碰撞,它们将无法再移动,因此速度保持在0.01。永远。
有很多方法可以解决此问题。由于蓝色方块永远不会移动,因此您可以在碰撞重叠之前先检查一次碰撞,也可以在发生碰撞时“反弹”红色方块。
快速/简便的解决方法是修改此功能:
void move() {
//Red square movement
// You only need to check for input once, then for which input interests you
if (keyPressed) {
// I think this would look better in a switch statement, but we'll keep it an If for simplicity
if (key == 'd' || key == 'D') {
// checking if the square will collide BEFORE it does
// notice that the square won't move if it detects that this move will be a collision
if (!rectRect(rx + speed, ry, rw, rh, bx, by, bw, bh)) {
rx = rx + speed;
}
}
else if (key == 'a' || key == 'A') {
if (!rectRect(rx - speed, ry, rw, rh, bx, by, bw, bh)) {
rx = rx - speed;
}
}
else if (key == 'w' || key == 'W') {
if (!rectRect(rx, ry - speed, rw, rh, bx, by, bw, bh)) {
ry = ry - speed;
}
}
else if (key == 's' || key == 'S') {
if (!rectRect(rx, ry + speed, rw, rh, bx, by, bw, bh)) {
ry = ry + speed;
}
}
if (ry > width) {
// insert whatever you were planning with this condition
}
}
}
现在,void collision()
已被void move()
接管,因此您可以擦除void collision
。从字面上讲,它永远不会发生,因为我们会在发生任何碰撞之前在 之前停止正方形。
现在...您想添加更多正方形。容易。
当然,您可以为每个正方形编写一个move
函数。但这很累,而且肯定有更好的方法。
有,但这将测试您的技能。我们将使事情变得简单,以免您一不振,但是我们知道我们将进入OOP(面向对象编程)领域。如果您在学校里,那么从了解课堂上会受益匪浅(嗯,即使您不在学校里,这仍然很棒)。
首先,我们将编写一个简单的类,用于创建和管理您在此程序中使用的矩形形状。如果您使用的是Processing IDE,建议您创建一个“新建选项卡”,以使代码保持整洁。您不必非要这样做,因为编译器看不到区别,但是随着项目变得越来越复杂,制表符是组织代码的理想工具。
在新标签页中,输入以下代码:
class Rectangle {
// This should be 'private', but I'm using 'protected' in case I wan to inherit those later, and 'public' to keep things simple
public float x = 0;
public float y = 0;
public float w = 50;
public float h = 50;
protected boolean isVisible = true;
protected color fillColor;
// This is the constructor. It serves to initialize the class.
public Rectangle(float xx, float yy, float ww, float hh, color cc) {
x = xx;
y = yy;
w = ww;
h = hh;
fillColor = cc;
}
public void Render() {
// I like to let my class draw themselves!
if (isVisible) {
fill(fillColor);
rect(x, y, w, h);
}
}
public void Move(float moveX, float moveY) {
// This will be used to move. Since the variables are 'protected', they cannot be accessed from outside this class, so I have to create a tool to use them.
// It is good practice to set 'public' only what's needed, and to manage class variables inside the class.
// This is for many good reasons. Among those, remember that it's harder to debug 'why is my x position weird' when it can be accessed from anywhere.
x += moveX;
y += moveY;
}
public boolean Collision(float xx, float yy, float ww, float hh, float moveX, float moveY) {
// Give coordinates to this function and it will tell you if there's a collision with this rectangle
return Intersect(x + moveX, y + moveY, w, h, xx, yy, ww, hh);
}
}
完成了吗?大!现在,您有了一个Rectangle类,它将包含矩形的坐标,颜色等内容。
现在,我们将不得不对您的代码进行一些更改。
首先,您不需要全局变量来跟踪红色和蓝色正方形的位置,因为这将由您刚创建的类处理。您可以删除它们。全局变量很有用,但通常来说,使用的越少越好,因为全局变量可能成为跟踪并导致无法预料的错误的噩梦。
然后,您需要将新类初始化为几个漂亮的矩形。为了使事情整洁,我们将有一个名为“ red”的矩形,以及一个将成为障碍的无名矩形的ArrayList。 ArrayList是一个很棒的工具,您以后可以学习使用。现在,我们只说它将在一个整洁的列表中包含所有这些障碍,我们将在需要时调用它。
move
函数必须处理所有新的障碍,并且必须处理一个对象而不是一堆全局变量。
最后,必须更新rectRect函数。现在,它曾经检查红色和蓝色是否相交,但是从现在开始,它需要能够检查所有矩形。我们将使其更加中立,并以不同的方式使用它。
这些更改之后的代码是:
//red
Rectangle red;
//all other rectangles
ArrayList <Rectangle> rectList;
float speed = 2;
//float cspeed = 2;
void setup() {
size(800, 800);
noStroke();
noSmooth();
noCursor();
// Initializing Red square
red = new Rectangle(200, 375, 50, 50, color(255, 0, 0));
// Initializing a bunch of rectangles
rectList = new ArrayList <Rectangle>();
rectList.add(new Rectangle(550, 375, 50, 50, color(0, 0, 255))); // Red
rectList.add(new Rectangle(300, 500, 50, 50, color(0, 255, 0))); // Green
// you can add as many as you want
}
void draw() {
surface.setTitle(mouseX + ", " + mouseY);
background(50);
move();
display();
}
void display() {
red.Render();
// this is a java 'For Each' loop. Research it, it's very useful.
for ( Rectangle r : rectList) {
r.Render();
}
}
void move() {
//Red square movement
float moveX = 0;
float moveY = 0;
if (keyPressed) {
// We're going calculate up how much we want to move the red square first
// Then we'll check for collisions
// Then we'll move the square (it there are no collisions)
if (key == 'd' || key == 'D') {moveX += speed;}
else if (key == 'a' || key == 'A') {moveX -= speed;}
else if (key == 'w' || key == 'W') {moveY -= speed;}
else if (key == 's' || key == 'S') {moveY += speed;}
for (Rectangle r : rectList) {
if (red.Collision(r.x, r.y, r.w, r.h, moveX, moveY)) {
// If a collision is detected, we exit this function so there will be no move
return;
}
}
red.Move(moveX, moveY);
}
}
// INTERSECT RECTs
// The old function was nice, but it was really useful only with your specific example. You can re-use this one with any set of rectangles.
// There are many ways to write this function. I wrote this instance back when I was a student, and I still use it to this day.
boolean Intersect(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2)
{
boolean checkX = false;
boolean checkY = false;
if ( (x1<=x2 && (x1+w1)>=x2) || (x1<=(x2+w2) && (x1+w1)>=x2+w2) || (x1>=x2 && (x1+w1)<=(x2+w2)) ) {checkX = true;}
if ( (y1<=y2 && (y1+h1)>=y2) || (y1<=(y2+h2) && (y1+h1)>=y2+h2) || (y1>=y2 && (y1+h1)<=(y2+h2)) ) {checkY = true;}
if (checkX && checkY) {return true;}
return false;
}
现在,您可以添加其他任何大小和颜色的正方形和矩形了!尝试一下!但是,更重要的是,尝试理解它。如果您有任何疑问,请记住我在这里为您提供帮助。
玩得开心!