import java.awt.*; public class Player { boolean intheAir = false; float x, y; // coordinates of player float Vx, Vy; // velocity of player */ float Ax = 0.0f, Ay = 5.0f; int width, height; // dimensions of the player image int index = 0; // which one of the array of images to show float initVel = -30.0f; // initial velocity of jump CS217 parent; Ball ball; public Player(CS217 parent) { this.parent = parent; Dimension d = parent.size(); width = 60; height = 60; x = parent.dim.width / 3; y = parent.dim.height - height -1; ball = new Ball(this); } public void paint(Graphics g) { g.drawImage(parent.imgs[index], (int) x, (int) y, width, height, parent); ball.paint(g); } public void advance(float deltaTime) { Dimension d = parent.dim; if (intheAir == true) { // use the laws of kinematics to compute new values y = y + Vy * deltaTime + 0.5f * Ay * deltaTime * deltaTime; Vy = Vy + Ay * deltaTime; x = x + Vx * deltaTime + 0.5f * Ax * deltaTime * deltaTime; Vx = Vx + Ax * deltaTime; if ( y > d.height - height - 1 ) { // handle the case of landing y = d.height - height - 1; intheAir = false; if (ball.caught) ball.landTime = System.currentTimeMillis(); } } if (x<1) // constrain to stay within applet bounds x = 1; if (x>d.width - width -1) x = d.width - width - 1; ball.advance(deltaTime); } public void jump() { if (intheAir == false) { intheAir = true; Vy = initVel; Vx = 0.0f; } } public void moveinX(int amount) { if (!intheAir) x = x + amount; } // These two functions are essential to keeping the applet configurable // If one would like to use a different image for a Player, one would // merely specify where the hand of the player is to be found and // ball catch checking will work fine public float gethandX() { return (x + 0.75f * width); } public float gethandY() { return (y + 0.10f * height); } } class Ball { boolean visible = false; boolean caught = false; float x, y; // coordinates of ball float Vx, Vy; // velocity of ball float Ax = 0.0f, Ay = 5.0f; int radius = 5; float initVx = -20.0f; // initial velocity float initVy = -10.0f; long landTime = 0; // at what time did the ball land Player creature; public Ball(Player creature) { this.creature = creature; } public void advance(float deltaTime) { if (visible == true) { if (caught == true) { // if caught keep it in hand x = creature.gethandX(); y = creature.gethandY(); if (creature.intheAir == false && caught) { // "take away" ball from player after 1 second if (System.currentTimeMillis() - landTime > 1000) visible = caught = false; } return; } y = y + Vy * deltaTime + 0.5f * Ay * deltaTime * deltaTime; Vy = Vy + Ay * deltaTime; x = x + Vx * deltaTime + 0.5f * Ax * deltaTime * deltaTime; Vx = Vx + Ax * deltaTime; Dimension d = creature.parent.dim; if ( y > d.height || y < 0 || x > d.width || x < 0 ) { visible = false; landTime = System.currentTimeMillis(); return; } if (successCatch()) { caught = true; creature.Vx = 0.2f * Vx; // player has mass 10, ball has mass 2 creature.Vy = (10.0f * creature.Vy + 2.0f * Vy)/12.0f; landTime = System.currentTimeMillis(); } return; } // Have to work hard - new throw every 3 seconds if (System.currentTimeMillis()-landTime > 3000) throwIt(); } public boolean successCatch() { if ((x < creature.gethandX() + 1.2*radius) && (x > creature.gethandX() - 1.2*radius) && (y < creature.gethandY() + 1.2*radius) && (y > creature.gethandY() - 1.2*radius)) return true; else return false; } public void throwIt() { visible = true; Vx = initVx + (float)Math.random() * initVx; Vy = initVy + (float)Math.random() * initVy; y = creature.parent.dim.height / 2; /* same height over and over */ x = creature.parent.dim.width - 1; if ( Math.random() > 0.5 ) { /* but x changes */ Vx = -Vx; x = 1; } } public void paint( Graphics g) { if (visible) { g.setColor(Color.blue); g.fillOval((int)x-radius, (int)y-radius, radius*2, radius*2); } } }