我试图创建一个基本的游泳池游戏,其中一个球击中另一个球并使第二个球以相同的速度在相同的方向上继续并移动与第一个球移动相同的距离。到目前为止,除了让第二球继续下去之外,我已经完成了所有工作。有人能帮我做这个工作吗?我认为我的问题在于代码的click == 4部分,但我不明白如何解决它/添加它。
Ball cue, billiard;
boolean fired = false;
String msg;
int click;
int steps = 20;
int difx, dify;
Boolean move = false;
void setup(){
msg = "";
size(600,300);
click = 0;
cue = new Ball(30, #FFFFFF);
billiard = new Ball(30, #000000);
}
void draw(){
background(#009900);
if(click == 0){
cue.xpos = mouseX;
cue.ypos = mouseY;
billiard.xpos = -15;
billiard.ypos = -15;
msg = "please place the cue ball";
}else if(click == 1){
billiard.xpos = mouseX;
billiard.ypos = mouseY;
msg = "click again to place billiard ball";
}else if(click ==2){
difx = cue.xpos-billiard.xpos;
dify = cue.ypos-billiard.ypos;
}else if(click == 3){
float cdistance = dist(cue.xpos,cue.ypos,billiard.xpos,billiard.ypos);
if(cdistance>billiard.ballDiam/2){
move = true;
cue.xpos-=difx/steps;
cue.ypos-=dify/steps;
msg = "You got it! Push c on your keyboard to restart";
}else{
move = false;
cue.visible = true;
click = 4;
}
}else if(click == 4){
float cdistance = dist(cue.xpos,cue.ypos,billiard.xpos,billiard.ypos);
if(cdistance<billiard.ballDiam){
if (dist(cue.xpos, cue.ypos, billiard.xpos, billiard.ypos) < sqrt(sq(difx)+sq(dify))) {
move = true;
billiard.xpos-=difx/steps;
billiard.ypos-=difx/steps;
}
}
}
cue.update();
billiard.update();
textSize(20);
text(msg,0,height-5);
}
void mouseClicked(){
if(!move){
click++;
}
}
class Ball{
int xpos, ypos;
int ballDiam;
color myColor;
boolean visible = true;
Ball(int tempdiam,color tempColor){
ballDiam=tempdiam;
myColor=tempColor;
}
void update(){
if(visible){
fill(myColor);
ellipse(xpos,ypos,ballDiam,ballDiam);
}
}
}
答案 0 :(得分:0)
您的第一站应该是Processing附带的示例,特别是Motion部分内的CircleCollision示例。这个例子包括使用或多或少逼真的物理学将球弹射出来的所有逻辑。
/**
* Circle Collision with Swapping Velocities
* by Ira Greenberg.
*
* Based on Keith Peter's Solution in
* Foundation Actionscript Animation: Making Things Move!
*/
Ball[] balls = {
new Ball(100, 400, 20),
new Ball(700, 400, 80)
};
void setup() {
size(640, 360);
}
void draw() {
background(51);
for (Ball b : balls) {
b.update();
b.display();
b.checkBoundaryCollision();
}
balls[0].checkCollision(balls[1]);
}
class Ball {
PVector position;
PVector velocity;
float r, m;
Ball(float x, float y, float r_) {
position = new PVector(x, y);
velocity = PVector.random2D();
velocity.mult(3);
r = r_;
m = r*.1;
}
void update() {
position.add(velocity);
}
void checkBoundaryCollision() {
if (position.x > width-r) {
position.x = width-r;
velocity.x *= -1;
}
else if (position.x < r) {
position.x = r;
velocity.x *= -1;
}
else if (position.y > height-r) {
position.y = height-r;
velocity.y *= -1;
}
else if (position.y < r) {
position.y = r;
velocity.y *= -1;
}
}
void checkCollision(Ball other) {
// get distances between the balls components
PVector bVect = PVector.sub(other.position, position);
// calculate magnitude of the vector separating the balls
float bVectMag = bVect.mag();
if (bVectMag < r + other.r) {
// get angle of bVect
float theta = bVect.heading();
// precalculate trig values
float sine = sin(theta);
float cosine = cos(theta);
/* bTemp will hold rotated ball positions. You
just need to worry about bTemp[1] position*/
PVector[] bTemp = {
new PVector(), new PVector()
};
/* this ball's position is relative to the other
so you can use the vector between them (bVect) as the
reference point in the rotation expressions.
bTemp[0].position.x and bTemp[0].position.y will initialize
automatically to 0.0, which is what you want
since b[1] will rotate around b[0] */
bTemp[1].x = cosine * bVect.x + sine * bVect.y;
bTemp[1].y = cosine * bVect.y - sine * bVect.x;
// rotate Temporary velocities
PVector[] vTemp = {
new PVector(), new PVector()
};
vTemp[0].x = cosine * velocity.x + sine * velocity.y;
vTemp[0].y = cosine * velocity.y - sine * velocity.x;
vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
/* Now that velocities are rotated, you can use 1D
conservation of momentum equations to calculate
the final velocity along the x-axis. */
PVector[] vFinal = {
new PVector(), new PVector()
};
// final rotated velocity for b[0]
vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
vFinal[0].y = vTemp[0].y;
// final rotated velocity for b[0]
vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
vFinal[1].y = vTemp[1].y;
// hack to avoid clumping
bTemp[0].x += vFinal[0].x;
bTemp[1].x += vFinal[1].x;
/* Rotate ball positions and velocities back
Reverse signs in trig expressions to rotate
in the opposite direction */
// rotate balls
PVector[] bFinal = {
new PVector(), new PVector()
};
bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
// update balls to screen position
other.position.x = position.x + bFinal[1].x;
other.position.y = position.y + bFinal[1].y;
position.add(bFinal[0]);
// update velocities
velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
}
}
void display() {
noStroke();
fill(204);
ellipse(position.x, position.y, r*2, r*2);
}
}
答案 1 :(得分:-1)
这是您的解决方案(但您也必须重新设计您的计划):
Ball cue, billiard;
boolean fired = false;
String msg;
int click;
int steps = 20;
int difx, dify;
Boolean move = false;
Boolean continueMoving;
void setup() {
msg = "";
size(600, 300);
click = 0;
cue = new Ball(30, #FFFFFF);
billiard = new Ball(30, #000000);
continueMoving = false;
}
void draw() {
background(#009900);
if (click == 0) {
cue.xpos = mouseX;
cue.ypos = mouseY;
billiard.xpos = -15;
billiard.ypos = -15;
msg = "please place the cue ball";
}
else if (click == 1) {
billiard.xpos = mouseX;
billiard.ypos = mouseY;
msg = "click again to place billiard ball";
}
else if (click ==2) {
difx = cue.xpos-billiard.xpos;
dify = cue.ypos-billiard.ypos;
}
else if (click == 3) {
float cdistance = dist(cue.xpos, cue.ypos, billiard.xpos, billiard.ypos);
if (cdistance>billiard.ballDiam/2) {
move = true;
cue.xpos-=difx/steps;
cue.ypos-=dify/steps;
msg = "You got it! Push c on your keyboard to restart";
}
else {
move = false;
cue.visible = true;
click = 4;
}
}
else if (click == 4)
{
float cdistance = dist(cue.xpos, cue.ypos, billiard.xpos, billiard.ypos);
if (cdistance<billiard.ballDiam)
{
if (dist(cue.xpos, cue.ypos, billiard.xpos, billiard.ypos) < sqrt(sq(difx)+sq(dify))) {
move = true;
continueMoving = true;
billiard.xpos-=difx/steps;
billiard.ypos-=dify/steps;
//print(click);
}
}
}
if (continueMoving)
{
billiard.xpos-=difx/steps;
billiard.ypos-=dify/steps;
}
cue.update();
billiard.update();
textSize(20);
text(msg, 0, height-5);
print(click);
}//draw
void mouseClicked() {
if (!move) {
click++;
}
}
class Ball
{
int xpos, ypos;
int ballDiam;
color myColor;
boolean visible = true;
Ball(int tempdiam, color tempColor) {
ballDiam=tempdiam;
myColor=tempColor;
}
void update() {
if (visible) {
fill(myColor);
ellipse(xpos, ypos, ballDiam, ballDiam);
}
}
}//Ball class
首先,使用if else
而不是switch
语句。其次,不要将所有代码放在draw
函数中。您可以将switch语句放在那里,但是将条件中的代码转移到draw
函数之外的某些函数。 Google了解其他人如何制作斯诺克/台球游戏,并且您将了解其他不同类型的逻辑。大多数情况下,他们将使用for
或while
循环来保持游戏的进行。该循环与您的draw
函数相同。
如果您是StackOverflow的新用户,可以点击此页面上的箭头按钮,为我的答案提供几点,然后点击勾选标记将其标记为已接受的答案。