为了在 Processing 3 (Java) 中检测 PNG 精灵和绘制的圆圈之间的碰撞,我应该在我的代码中做什么?
What should I do in my code in order to make a collision detection between a PNG sprite and a drawn circle occur in Processing 3 (Java)?
我一直在为我的学术工作编写一个非常简单的游戏,其中 PNG 蜜蜂精灵要 运行 远离橙色球。如果蜜蜂与橙色球相撞,她就会死去。除此之外,我打算包括一个计时器,当蜜蜂成功 运行 远离球时,它会继续前进。球自动在整个屏幕上移动,而蜜蜂则通过箭头键和重力在屏幕上弹跳。
我在 Processing 论坛上看到了一些关于碰撞检测的解释,但是我仍然不明白在圆 x 圆碰撞、矩形 x 圆碰撞等情况下如何发生此事件
请原谅我乱七八糟的代码。另外,请原谅我对我想知道的内容描述不当。
这是我在屏幕上看到的:
我的代码:
//background
PImage background;
// keys | keyboard
boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;
// bee player character
PImage charImage;
float charSpeed = 5.5;
float charX = 0;
float charY = 450;
float gravity = 1.5;
float vy = 0;
float bounce = -0.8;
// platforms
PImage bee;// bee
float beeX = 300;
float beeY = 490;
PImage hi; // hi
float hiX = 400;
float hiY = 300;
PImage ve; // ve
float veX = 420;
float veY = 440;
// more beehives
PImage beehive4;// beehive4
float bee4X = 120;
float bee4Y = 90;
PImage beehive5; // beehive5
float bee5X = 200;
float bee5Y = 300;
PImage beehive6; // beehive6
float bee6X = 30;
float bee6Y = 400;
PImage beehive7; // beehive7
float bee7X = 496;
float bee7Y = 90;
// enemy ball
float ballX = 100;
float ballY = 100;
float xspeed = 100;
float yspeed = 100;
//////
public void setup() {
size(600, 800);
noStroke();
smooth();
noFill(); // to adjust the image in the screen properly in fullscreen
//load beehives
bee = loadImage("beehive 1.png");
bee.resize(100, 100);
hi = loadImage("beehive 2.png");
hi.resize(100,100);
ve = loadImage("beehive 3.png");
ve.resize(100, 100);
// load more beehives
beehive4 = loadImage("beehive 4.png");
beehive4.resize(100, 100);
beehive5 = loadImage("beehive 5.png");
beehive5.resize(100, 100);
beehive6 = loadImage("beehive 6.png");
beehive6.resize(100, 100);
beehive7 = loadImage("beehive 7.png");
beehive7.resize(100, 100);
}
/*********** drawing section !***********/
public void draw() {
background(244, 240, 219);
noStroke();
// render beehives
image(bee, beeX, beeY);
image(hi, hiX, hiY);
image(ve, veX, veY);
// render more beehives
image(beehive4, bee4X, bee4Y);
image(beehive5, bee5X, bee5Y);
image(beehive6, bee6X, bee6Y);
image(beehive7, bee7X, bee7Y);
// render bee
charImage = loadImage("bee walk 3.png");
charImage.resize(200, 200);
vy += gravity; // it applies gravity to the bee sprite
charY += vy;
if(charY > height - 150 )
vy *= bounce; // bouncing bee
// Add the current speed to the location.
ballX = ballX + xspeed;
ballY = ballY + yspeed;
// Check for bouncing
if ((ballX > width) || (ballX < 0)) {
xspeed = xspeed * -1;
}
if ((ballY > height) || (ballY < 0)) {
yspeed = yspeed * -1;
}
// Display at x,y location
stroke(0);
fill(179, 98, 0);
ellipse(ballX, ballY,80,80);
// update keys
if (upPressed) {
charY--;
}
if (downPressed) {
charY++;
}
if (leftPressed) {
charX--;
}
if (rightPressed) {
charX++;
}
if(keyPressed){
if(keyCode == UP && charY > 0){
charY -= 30;
}
if(keyCode == DOWN && charY < height){
charY += 10;
}
if(keyCode == LEFT && charX > 0){
charX -= 30;
}
if(keyCode == RIGHT && charX < width){
charX += 10;
}
}
// render beecharacter on screen
image(charImage, charX, charY);
}
有多种方法可以解决这个问题。
碰撞检测可以是粗略的:不太准确但更快(更简单)或更详细(例如像素级精度)但更慢(更复杂)。
就简单的碰撞检测而言,两个选项可以是矩形或圆形相交。
可以手动或使用Rectangle
's intersects()
method实现矩形相交。
圆相交是微不足道的:如果第一个圆心和第二个圆心之间的距离(dist()
)小于两个半径则它们必须相交。
这是一个说明圆相交的基本示例:
// check collision: circle
if (dist(ballX, ballY, charX, charY) < charImage.width) {
// tint red to display collision: placeholder for subtracting bee health
tint(192, 0, 0);
}else{
noTint();
}
这个条件可以在draw()
的这个部分之前添加:
// render beecharacter on screen
image(charImage, charX, charY);
碰撞检测相当粗糙:像素不完美,但希望是一个好的起点。如果发生碰撞,它应该把所有东西都染成红色。
我还有两个小建议:
- 将
xspeed
、yspeed
减少到 10 或更小的值将使游戏更具可玩性。 100px/frame 对人来说太快了,蜜蜂很可能会在用户反应过来之前立即发生碰撞。
- 而不是
boolean beeIsAlive
类型的变量,一旦击中球立即切换为 true 作为游戏规则也可能过于苛刻。考虑像 int beeHealth = 100;
这样的事情,每次碰撞逐渐降低生命值将使游戏更具可玩性。
我一直在为我的学术工作编写一个非常简单的游戏,其中 PNG 蜜蜂精灵要 运行 远离橙色球。如果蜜蜂与橙色球相撞,她就会死去。除此之外,我打算包括一个计时器,当蜜蜂成功 运行 远离球时,它会继续前进。球自动在整个屏幕上移动,而蜜蜂则通过箭头键和重力在屏幕上弹跳。
我在 Processing 论坛上看到了一些关于碰撞检测的解释,但是我仍然不明白在圆 x 圆碰撞、矩形 x 圆碰撞等情况下如何发生此事件
请原谅我乱七八糟的代码。另外,请原谅我对我想知道的内容描述不当。
这是我在屏幕上看到的:
我的代码:
//background
PImage background;
// keys | keyboard
boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;
// bee player character
PImage charImage;
float charSpeed = 5.5;
float charX = 0;
float charY = 450;
float gravity = 1.5;
float vy = 0;
float bounce = -0.8;
// platforms
PImage bee;// bee
float beeX = 300;
float beeY = 490;
PImage hi; // hi
float hiX = 400;
float hiY = 300;
PImage ve; // ve
float veX = 420;
float veY = 440;
// more beehives
PImage beehive4;// beehive4
float bee4X = 120;
float bee4Y = 90;
PImage beehive5; // beehive5
float bee5X = 200;
float bee5Y = 300;
PImage beehive6; // beehive6
float bee6X = 30;
float bee6Y = 400;
PImage beehive7; // beehive7
float bee7X = 496;
float bee7Y = 90;
// enemy ball
float ballX = 100;
float ballY = 100;
float xspeed = 100;
float yspeed = 100;
//////
public void setup() {
size(600, 800);
noStroke();
smooth();
noFill(); // to adjust the image in the screen properly in fullscreen
//load beehives
bee = loadImage("beehive 1.png");
bee.resize(100, 100);
hi = loadImage("beehive 2.png");
hi.resize(100,100);
ve = loadImage("beehive 3.png");
ve.resize(100, 100);
// load more beehives
beehive4 = loadImage("beehive 4.png");
beehive4.resize(100, 100);
beehive5 = loadImage("beehive 5.png");
beehive5.resize(100, 100);
beehive6 = loadImage("beehive 6.png");
beehive6.resize(100, 100);
beehive7 = loadImage("beehive 7.png");
beehive7.resize(100, 100);
}
/*********** drawing section !***********/
public void draw() {
background(244, 240, 219);
noStroke();
// render beehives
image(bee, beeX, beeY);
image(hi, hiX, hiY);
image(ve, veX, veY);
// render more beehives
image(beehive4, bee4X, bee4Y);
image(beehive5, bee5X, bee5Y);
image(beehive6, bee6X, bee6Y);
image(beehive7, bee7X, bee7Y);
// render bee
charImage = loadImage("bee walk 3.png");
charImage.resize(200, 200);
vy += gravity; // it applies gravity to the bee sprite
charY += vy;
if(charY > height - 150 )
vy *= bounce; // bouncing bee
// Add the current speed to the location.
ballX = ballX + xspeed;
ballY = ballY + yspeed;
// Check for bouncing
if ((ballX > width) || (ballX < 0)) {
xspeed = xspeed * -1;
}
if ((ballY > height) || (ballY < 0)) {
yspeed = yspeed * -1;
}
// Display at x,y location
stroke(0);
fill(179, 98, 0);
ellipse(ballX, ballY,80,80);
// update keys
if (upPressed) {
charY--;
}
if (downPressed) {
charY++;
}
if (leftPressed) {
charX--;
}
if (rightPressed) {
charX++;
}
if(keyPressed){
if(keyCode == UP && charY > 0){
charY -= 30;
}
if(keyCode == DOWN && charY < height){
charY += 10;
}
if(keyCode == LEFT && charX > 0){
charX -= 30;
}
if(keyCode == RIGHT && charX < width){
charX += 10;
}
}
// render beecharacter on screen
image(charImage, charX, charY);
}
有多种方法可以解决这个问题。
碰撞检测可以是粗略的:不太准确但更快(更简单)或更详细(例如像素级精度)但更慢(更复杂)。
就简单的碰撞检测而言,两个选项可以是矩形或圆形相交。
可以手动或使用Rectangle
's intersects()
method实现矩形相交。
圆相交是微不足道的:如果第一个圆心和第二个圆心之间的距离(dist()
)小于两个半径则它们必须相交。
这是一个说明圆相交的基本示例:
// check collision: circle
if (dist(ballX, ballY, charX, charY) < charImage.width) {
// tint red to display collision: placeholder for subtracting bee health
tint(192, 0, 0);
}else{
noTint();
}
这个条件可以在draw()
的这个部分之前添加:
// render beecharacter on screen
image(charImage, charX, charY);
碰撞检测相当粗糙:像素不完美,但希望是一个好的起点。如果发生碰撞,它应该把所有东西都染成红色。
我还有两个小建议:
- 将
xspeed
、yspeed
减少到 10 或更小的值将使游戏更具可玩性。 100px/frame 对人来说太快了,蜜蜂很可能会在用户反应过来之前立即发生碰撞。 - 而不是
boolean beeIsAlive
类型的变量,一旦击中球立即切换为 true 作为游戏规则也可能过于苛刻。考虑像int beeHealth = 100;
这样的事情,每次碰撞逐渐降低生命值将使游戏更具可玩性。