We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, I'm doing a project that's due soon for intro to engineering and comp sci class in which I have to shoot a ball out of a cannon. Everything seems to be working fine except that when the ball hits the ground, only half of it shows up. I think it's because I stop the ball from moving when ypos=0 which is the center of the ball. I want all of the ball to be resting on the ground. I was wondering if anybody knew how to fix this issue.
float v; // velocity
float g; // gravity constant 32 ft
float t_time; // total time
float cur_time; // current time
float cannonAngle; // angle the ball will be shot
float firingAngle; // angle of the ball
float xpos; // function for the x position of the ball
float ypos; // function for the y position of the ball
int targetStart;
int targetWidth = 25;
int attempt; // the number of times the ball has been shot
String status;
void setup ()
{
size(800,300); // size of the screen
v=150; // velocity
cannonAngle=radians(45); // angle of cannon
firingAngle=cannonAngle;
g=32;
t_time =0;
cur_time=0;
targetStart = int(random(100, width-targetWidth));
attempt = 0;
status = "Halt";
xpos=0;
ypos=0;
}
void draw ()
{
PImage img = loadImage("mountains.png"); // background image
image(img, 0, 0);
if (status == "Run"){
if (cur_time>t_time){
checkTarget(); // Stop animation
}
else if(cur_time<t_time){
cur_time += 0.080; // add 0.050 to the current time
}
}
fill(0); // black color
drawTarget();
drawShot(); // shows the ball moving across the screen
PImage wheelback=loadImage("wheel_b.png"); // stationary back wheels
image(wheelback, 5, 271);
drawCannon();
PImage wheelfront=loadImage("wheel_f.png"); // stationary front wheel
image(wheelfront, -5, 268);
drawPosition (); // text in the corners
//reset(); // makes ball sit on ground
}
/* Functions */
void reset() // resetting the ball back ot the beginning
{
if (cur_time>t_time) // if y pos ever goes off the screen
{
ypos=height-27;
}
}
// draws the ball the screen
void drawShot ()
{
xpos= v*cur_time*cos(firingAngle); // x position
ypos = v*cur_time*sin(firingAngle)-(0.5*(g*(sq(cur_time)))); // y position
fill(116,46,0);
ellipse(xpos, height-ypos, 10, 10);
if(ypos<0) // if the y position is greater than ground,
{
ypos=0 ; // set ypos equal to zero
}
}
// draws the cannon
void drawCannon() {
// Start new shape translations
pushMatrix();
fill(0);
// Move screen origin to the lower left hand corner
translate(0, height-10);
// Rotate new shapes cannonAngle degrees counter-clockwise
rotate(cannonAngle * -1);
// Draw rectangle with the new origin and rotation
fill(80,32,0);
rect(0, 0, 50, 15);
// reset shape translations
popMatrix();
}
// fires the shot
void fireCannon()
{
cur_time = 0;
firingAngle = cannonAngle;
t_time = (2*v*sin(firingAngle)/g);
attempt++;
status = "Run";
}
// when user presses key
void keyPressed()
{
if(key == CODED && keyCode == LEFT)
{
cannonAngle = cannonAngle + .01;
if(cannonAngle > HALF_PI){
cannonAngle = HALF_PI;
}
}
else if(key == CODED && keyCode == RIGHT) {
cannonAngle = cannonAngle - .01;
if(cannonAngle<=0.0)
{
cannonAngle=0.0;
}
}
else if(key == ' ') {
cur_time = 0.0;
firingAngle = cannonAngle;
fireCannon();
}
}
// draws the target
void checkTarget() {
if (xpos >= targetStart && xpos <= targetStart + targetWidth) {
status = "HIT";
}
else {
status = "MISS";
}
}
void drawTarget() {
strokeWeight(5);
stroke(255, 0, 0);
line(targetStart, height-1, targetStart + targetWidth, height-1);
stroke(0);
strokeWeight(0);
}
// writes the texts in the corners and such
void drawPosition()
{
fill(255);
rect(2,2, 160, 80);
fill(0);
String text = "Time (sec): " + nf(cur_time, 1, 2)
+ "\nCoordinates: (" + int(xpos) + " , " + int(ypos)+")"
+ "\nCannon Angle: " + degrees(cannonAngle)
+ "\nAttempt(s): " + attempt
+ "\nStatus: " + status;
text(text, 10, 20);
}
Answers
The diameter of your ellipse is 10. Just make the ground yPos=5 (half of the ellipse) ?
It doesn't really make a difference except that at different angles the ball would sometimes be totally off the screen or still halfway, as shown in the pictures.
Actually it does that even if ypos=0.