为什么游戏在实际撞到砖头之前就检测到碰撞?
我试图为个人项目创建一个砖砌游戏。我正在为不同的砖块使用阵列,并用砖的图像叠加砖块。我能够检测到碰撞,但是由于某种原因,球在撞到实际砖之前略微检测到碰撞。当球撞到砖块时,我也有一个疑问。感谢任何帮助。
代码:
color black = color(0,0,0);
color red = color(255,0,0);
color white = color(255,255,255);
float ballx = 412.5, bally = 500, balld = 20, ballr = balld/2, paddleX = 362.5, paddleY = 650;
float paddleW = 100, paddleH = 15;
float ballspdX, ballspdY;
boolean ball_drop = true;
float direction_choice;
float [] brickX = new float [50];
float [] brickY = new float [50];
int brickW = 50, brickH = 25;
int ball_lives = 5;
PFont font1;
PFont font2;
PImage brickimg;
boolean gameover_sign = false;
boolean Game_Over_mode = false;
boolean right = false;
boolean left = false;
void brickformation(){
brickX[0] = 50;
brickX[1] = 125;
brickX[2] = 200;
brickX[3] = 275;
brickX[4] = 350;
brickX[5] = 425;
brickX[6] = 500;
brickX[7] = 575;
brickX[8] = 650;
brickX[9] = 725;
brickX[10] = 50;
brickX[11] = 125;
brickX[12] = 200;
brickX[13] = 275;
brickX[14] = 350;
brickX[15] = 425;
brickX[16] = 500;
brickX[17] = 575;
brickX[18] = 650;
brickX[19] = 725;
brickX[20] = 50;
brickX[21] = 125;
brickX[22] = 200;
brickX[23] = 275;
brickX[24] = 350;
brickX[25] = 425;
brickX[26] = 500;
brickX[27] = 575;
brickX[28] = 650;
brickX[29] = 725;
brickX[30] = 50;
brickX[31] = 125;
brickX[32] = 200;
brickX[33] = 275;
brickX[34] = 350;
brickX[35] = 425;
brickX[36] = 500;
brickX[37] = 575;
brickX[38] = 650;
brickX[39] = 725;
brickX[40] = 50;
brickX[41] = 125;
brickX[42] = 200;
brickX[43] = 275;
brickX[44] = 350;
brickX[45] = 425;
brickX[46] = 500;
brickX[47] = 575;
brickX[48] = 650;
brickX[49] = 725;
brickY[0] = 50;
brickY[1] = 50;
brickY[2] = 50;
brickY[3] = 50;
brickY[4] = 50;
brickY[5] = 50;
brickY[6] = 50;
brickY[7] = 50;
brickY[8] = 50;
brickY[9] = 50;
brickY[10] = 125;
brickY[11] = 125;
brickY[12] = 125;
brickY[13] = 125;
brickY[14] = 125;
brickY[15] = 125;
brickY[16] = 125;
brickY[17] = 125;
brickY[18] = 125;
brickY[19] = 125;
brickY[20] = 200;
brickY[21] = 200;
brickY[22] = 200;
brickY[23] = 200;
brickY[24] = 200;
brickY[25] = 200;
brickY[26] = 200;
brickY[27] = 200;
brickY[28] = 200;
brickY[29] = 200;
brickY[30] = 275;
brickY[31] = 275;
brickY[32] = 275;
brickY[33] = 275;
brickY[34] = 275;
brickY[35] = 275;
brickY[36] = 275;
brickY[37] = 275;
brickY[38] = 275;
brickY[39] = 275;
brickY[40] = 350;
brickY[41] = 350;
brickY[42] = 350;
brickY[43] = 350;
brickY[44] = 350;
brickY[45] = 350;
brickY[46] = 350;
brickY[47] = 350;
brickY[48] = 350;
brickY[49] = 350;
}
void setup(){
size(825,800);
surface.setTitle("Brick breaker");
font1 = createFont("04B_19", 150);
font2 = createFont("04B_19", 35);
brickimg = loadImage("brick.jpeg");
noCursor();
smooth();
brickformation();
}
void paddle(){
noStroke();
fill(white);
rect(paddleX, paddleY, paddleW, paddleH);
}
void ball(){
noStroke();
fill(red);
circle(ballx, bally, balld);
}
void gameover(){
///////////////////////the sign that displays game over.
stroke(black);
fill(white);
rect(0,135, 825, 240);
fill(red);
textFont(font1);
text("GAME OVER", 20, 275);
textFont(font2);
text("Press r to restart", 225, 335);
Game_Over_mode = true;
}
void reset(){
ball_lives = 5;
ballx = 412.5;
bally = 600;
gameover_sign = false;
ball_drop = true;
}
void draw(){
background(black);
paddle();
ball();
for (int i = 0; i < brickX.length; i++){
brickimg.resize(brickW, brickH);
fill(white);
image(brickimg, brickX[i], brickY[i]);
rect(brickX[i], brickY[i], brickW, brickH);
//hits bottom of brick
}
fill(white);
textFont(font2);
text("Lives = " + str(ball_lives), 35, 775);
//uses different collision for paddle to make the ball go different directions based on how they hit the paddle.
//collision for left side of paddle
if (collideLineCircle(paddleX, paddleY, paddleX + (paddleW/2), paddleY, ballx, bally, ballr)){
ball_drop = false;
ballspdY = -1;
ballspdX = 4;
}
//collision for right side of paddle.
if (collideLineCircle(paddleX + (paddleW/2), paddleY, paddleX + paddleW, paddleY, ballx, bally, ballr)){
ball_drop = false;
ballspdY = -1;
ballspdX = -4;
}
//colisions for bricks
for (int i = 0; i < brickX.length; i ++){
//bottom
if (collideLineCircle(brickX[i], brickY[i] + brickH, brickX[i] + brickW, brickY[i] + brickH, ballx, bally, ballr)){
ballspdY = -ballspdY;
brickX[i] = -400;
}
//top
else if (collideLineCircle(brickX[i], brickY[i], brickX[i] + brickW, brickY[i], ballx, bally, ballr)){
ballspdY = -ballspdY;
brickX[i] = -400;
}
else if (collideLineCircle(brickX[i], brickY[i], brickX[i], brickY[i] + brickW, ballx, bally, ballr)){
ballspdX = -ballspdX;
brickX[i] = -400;
}
else if (collideLineCircle(brickX[i] + brickW, brickY[i], brickX[i] + brickW, brickY[i] + brickH, ballx, bally, ballr)){
ballspdX = -ballspdX;
brickX[i] = -400;
}
}
////collisions for different walls of the screeen.
if (ballx + ballr > width || ballx - ballr < 0){
ballspdX = -ballspdX;
}
if (bally - ballr < 0){
ballspdY = 1;
}
if (ball_drop){
ballspdX = 0;
ballspdY = 1;
}
if (ball_lives >= 1){
if (bally >= 800){
ball_lives = ball_lives - 1;
bally = 600;
ballx = 412.5;
ball_drop = true;
}
}
if (ball_lives == 0 && bally > 800){
gameover_sign = true;
}
if (gameover_sign){
gameover();
}
if (right){
if(paddleX > 0){
paddleX -= 4;
}
}
if (left){
if (paddleX + paddleW < width){
paddleX += 4;
}
}
bally += ballspdY/2;
ballx += ballspdX/2;
}
boolean collideLineCircle(float x1, float y1, float x2, float y2, float cx, float cy, float cr){
float A = y2 - y1, B = x1 - x2, C = x2*y1 - x1+y2;
float denom = A+A + B*B;
if (denom == 0){
return dist(x1,y1, cx, cy) < cr;
}
float Ix = (B*B*cx-A*B*cy - A*C)/denom, Iy = (A*A*cy-A*B*cx - B*C)/denom;
if (Ix >= min(x1,x2) && Ix <= max(x1,x2) & Iy >= min(y1,y2) && Iy <= max(y1,y2)) {
return abs (A*cx + B*cy + C)/sqrt(denom) < cr;
}
float d1 = dist(x1,y1,cx,cy), d2 = dist(x2,y2,cx,cy);
return min(d1,d2) < cr;
}
void keyPressed(KeyEvent evt){
if (key == 'r'){
if (Game_Over_mode){
reset();
Game_Over_mode = false;
}
}
if (key == 'a'){
if(paddleX > 0){
right = true;
}
}
else{right = false;}
if (key == 'd'){
if(paddleX + paddleW < width){
left = true;
}
}
else{left = false;}
}
Im trying to create a brick breaker game for a personal project. I am using a array for the different bricks and overlaying the bricks with an image of a brick. I was able to detect the collisions but for some reason the ball is detecting the collisions slightly before it hits the actual brick. I also have a question on what way should the ball go when it hits the brick. I appreciate any help.
code:
color black = color(0,0,0);
color red = color(255,0,0);
color white = color(255,255,255);
float ballx = 412.5, bally = 500, balld = 20, ballr = balld/2, paddleX = 362.5, paddleY = 650;
float paddleW = 100, paddleH = 15;
float ballspdX, ballspdY;
boolean ball_drop = true;
float direction_choice;
float [] brickX = new float [50];
float [] brickY = new float [50];
int brickW = 50, brickH = 25;
int ball_lives = 5;
PFont font1;
PFont font2;
PImage brickimg;
boolean gameover_sign = false;
boolean Game_Over_mode = false;
boolean right = false;
boolean left = false;
void brickformation(){
brickX[0] = 50;
brickX[1] = 125;
brickX[2] = 200;
brickX[3] = 275;
brickX[4] = 350;
brickX[5] = 425;
brickX[6] = 500;
brickX[7] = 575;
brickX[8] = 650;
brickX[9] = 725;
brickX[10] = 50;
brickX[11] = 125;
brickX[12] = 200;
brickX[13] = 275;
brickX[14] = 350;
brickX[15] = 425;
brickX[16] = 500;
brickX[17] = 575;
brickX[18] = 650;
brickX[19] = 725;
brickX[20] = 50;
brickX[21] = 125;
brickX[22] = 200;
brickX[23] = 275;
brickX[24] = 350;
brickX[25] = 425;
brickX[26] = 500;
brickX[27] = 575;
brickX[28] = 650;
brickX[29] = 725;
brickX[30] = 50;
brickX[31] = 125;
brickX[32] = 200;
brickX[33] = 275;
brickX[34] = 350;
brickX[35] = 425;
brickX[36] = 500;
brickX[37] = 575;
brickX[38] = 650;
brickX[39] = 725;
brickX[40] = 50;
brickX[41] = 125;
brickX[42] = 200;
brickX[43] = 275;
brickX[44] = 350;
brickX[45] = 425;
brickX[46] = 500;
brickX[47] = 575;
brickX[48] = 650;
brickX[49] = 725;
brickY[0] = 50;
brickY[1] = 50;
brickY[2] = 50;
brickY[3] = 50;
brickY[4] = 50;
brickY[5] = 50;
brickY[6] = 50;
brickY[7] = 50;
brickY[8] = 50;
brickY[9] = 50;
brickY[10] = 125;
brickY[11] = 125;
brickY[12] = 125;
brickY[13] = 125;
brickY[14] = 125;
brickY[15] = 125;
brickY[16] = 125;
brickY[17] = 125;
brickY[18] = 125;
brickY[19] = 125;
brickY[20] = 200;
brickY[21] = 200;
brickY[22] = 200;
brickY[23] = 200;
brickY[24] = 200;
brickY[25] = 200;
brickY[26] = 200;
brickY[27] = 200;
brickY[28] = 200;
brickY[29] = 200;
brickY[30] = 275;
brickY[31] = 275;
brickY[32] = 275;
brickY[33] = 275;
brickY[34] = 275;
brickY[35] = 275;
brickY[36] = 275;
brickY[37] = 275;
brickY[38] = 275;
brickY[39] = 275;
brickY[40] = 350;
brickY[41] = 350;
brickY[42] = 350;
brickY[43] = 350;
brickY[44] = 350;
brickY[45] = 350;
brickY[46] = 350;
brickY[47] = 350;
brickY[48] = 350;
brickY[49] = 350;
}
void setup(){
size(825,800);
surface.setTitle("Brick breaker");
font1 = createFont("04B_19", 150);
font2 = createFont("04B_19", 35);
brickimg = loadImage("brick.jpeg");
noCursor();
smooth();
brickformation();
}
void paddle(){
noStroke();
fill(white);
rect(paddleX, paddleY, paddleW, paddleH);
}
void ball(){
noStroke();
fill(red);
circle(ballx, bally, balld);
}
void gameover(){
///////////////////////the sign that displays game over.
stroke(black);
fill(white);
rect(0,135, 825, 240);
fill(red);
textFont(font1);
text("GAME OVER", 20, 275);
textFont(font2);
text("Press r to restart", 225, 335);
Game_Over_mode = true;
}
void reset(){
ball_lives = 5;
ballx = 412.5;
bally = 600;
gameover_sign = false;
ball_drop = true;
}
void draw(){
background(black);
paddle();
ball();
for (int i = 0; i < brickX.length; i++){
brickimg.resize(brickW, brickH);
fill(white);
image(brickimg, brickX[i], brickY[i]);
rect(brickX[i], brickY[i], brickW, brickH);
//hits bottom of brick
}
fill(white);
textFont(font2);
text("Lives = " + str(ball_lives), 35, 775);
//uses different collision for paddle to make the ball go different directions based on how they hit the paddle.
//collision for left side of paddle
if (collideLineCircle(paddleX, paddleY, paddleX + (paddleW/2), paddleY, ballx, bally, ballr)){
ball_drop = false;
ballspdY = -1;
ballspdX = 4;
}
//collision for right side of paddle.
if (collideLineCircle(paddleX + (paddleW/2), paddleY, paddleX + paddleW, paddleY, ballx, bally, ballr)){
ball_drop = false;
ballspdY = -1;
ballspdX = -4;
}
//colisions for bricks
for (int i = 0; i < brickX.length; i ++){
//bottom
if (collideLineCircle(brickX[i], brickY[i] + brickH, brickX[i] + brickW, brickY[i] + brickH, ballx, bally, ballr)){
ballspdY = -ballspdY;
brickX[i] = -400;
}
//top
else if (collideLineCircle(brickX[i], brickY[i], brickX[i] + brickW, brickY[i], ballx, bally, ballr)){
ballspdY = -ballspdY;
brickX[i] = -400;
}
else if (collideLineCircle(brickX[i], brickY[i], brickX[i], brickY[i] + brickW, ballx, bally, ballr)){
ballspdX = -ballspdX;
brickX[i] = -400;
}
else if (collideLineCircle(brickX[i] + brickW, brickY[i], brickX[i] + brickW, brickY[i] + brickH, ballx, bally, ballr)){
ballspdX = -ballspdX;
brickX[i] = -400;
}
}
////collisions for different walls of the screeen.
if (ballx + ballr > width || ballx - ballr < 0){
ballspdX = -ballspdX;
}
if (bally - ballr < 0){
ballspdY = 1;
}
if (ball_drop){
ballspdX = 0;
ballspdY = 1;
}
if (ball_lives >= 1){
if (bally >= 800){
ball_lives = ball_lives - 1;
bally = 600;
ballx = 412.5;
ball_drop = true;
}
}
if (ball_lives == 0 && bally > 800){
gameover_sign = true;
}
if (gameover_sign){
gameover();
}
if (right){
if(paddleX > 0){
paddleX -= 4;
}
}
if (left){
if (paddleX + paddleW < width){
paddleX += 4;
}
}
bally += ballspdY/2;
ballx += ballspdX/2;
}
boolean collideLineCircle(float x1, float y1, float x2, float y2, float cx, float cy, float cr){
float A = y2 - y1, B = x1 - x2, C = x2*y1 - x1+y2;
float denom = A+A + B*B;
if (denom == 0){
return dist(x1,y1, cx, cy) < cr;
}
float Ix = (B*B*cx-A*B*cy - A*C)/denom, Iy = (A*A*cy-A*B*cx - B*C)/denom;
if (Ix >= min(x1,x2) && Ix <= max(x1,x2) & Iy >= min(y1,y2) && Iy <= max(y1,y2)) {
return abs (A*cx + B*cy + C)/sqrt(denom) < cr;
}
float d1 = dist(x1,y1,cx,cy), d2 = dist(x2,y2,cx,cy);
return min(d1,d2) < cr;
}
void keyPressed(KeyEvent evt){
if (key == 'r'){
if (Game_Over_mode){
reset();
Game_Over_mode = false;
}
}
if (key == 'a'){
if(paddleX > 0){
right = true;
}
}
else{right = false;}
if (key == 'd'){
if(paddleX + paddleW < width){
left = true;
}
}
else{left = false;}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论