/** Checks of the player hits a stone wall or a door. */ boolean checkCollision() { return dukeSprite.collidesWith(myWalls, true); }
/** * respond to keystrokes by deciding where to move and then moving the pieces and the view window * correspondingly. */ public void requestMove(int hdirection, int vdirection) { // vdirection < 0 indicates that the user has // pressed the UP button and would like to jump. // therefore, if we're not currently jumping, // we begin the jump. if ((myIsJumping == NO_JUMP) && (vdirection < 0)) { myIsJumping++; } else if (myIsJumping == NO_JUMP) { // if we're not jumping at all, we need to check // if the duke should be falling: // we (temporarily) move the duke down and see if that // causes a collision with the floor: dukeSprite.move(0, 1); // if the duke can move down without colliding // with the floor, then we set the duke to // be falling. The variable myIsJumping starts // negative while the duke is jumping up and // is zero or positive when the duke is coming // back down. We therefore set myIsJumping to // zero to indicate that the duke should start // falling. if (!checkCollision()) { myIsJumping = 0; } // we move the duke Sprite back to the correct // position she was at before we (temporarily) moved // her down to see if she would fall. dukeSprite.move(0, -1); } // if the duke is currently jumping or falling, // advance the jump (change the vertical distance // the duke is supposed to move) if ((myIsJumping <= MAX_FREE_FALL) && (myIsJumping != NO_JUMP)) { myIsJumping++; } // also accellerate the horizontal motion if the duke // runs runs in the same horizontal direction for more than // one game tick: myIsRunning++; // But don't accellerate past the maximum speed: if (myIsRunning > MAX_SPEED) { myIsRunning = MAX_SPEED; } int horizontal = MOVE_LENGTH * myIsRunning; // if the duke is currently jumping or falling, // we calculate the vertical distance she should move. // This is a parabola given by y = (x*x) * (a + b/c) // where x is how far we have advanced in the jump // or fall (myIsJumping), and a, b, and c are constants // based on the screen size. (The actual values are // read from a properties file and were originally // computed through trial and error.) int vertical = 0; if (myIsJumping != NO_JUMP) { vertical = myIsJumping * myIsJumping * JUMP_INT + (myIsJumping * myIsJumping * JUMP_FRAC_NUM) / JUMP_FRAC_DENOM; // for the first half of the jump we go up, // then for the second half go down: if (myIsJumping < 0) { vdirection = -1; } else { vdirection = 1; } } // set the sprite to the correct frame based // on the duke's current motion: updateSprite(hdirection, vdirection); boolean vcrash = false; boolean hcrash = false; // now calculate the motion one pixel at a time // (vertically then horizontally) to see precisely // how far the duke can move in each of the // requested directions: while ((vertical >= 1 && !vcrash) || (horizontal >= 1 && !hcrash)) { dukeSprite.move(0, vdirection); if (checkCollision()) { dukeSprite.move(0, -vdirection); vcrash = true; } else { vertical -= 1; vcrash = false; myViewWindowY += vdirection; } dukeSprite.move(MOVE_BUFFER * hdirection, 0); if (checkCollision()) { dukeSprite.move(-MOVE_BUFFER * hdirection, 0); hcrash = true; } else { dukeSprite.move(-MOVE_BUFFER * hdirection, 0); dukeSprite.move(hdirection, 0); horizontal -= 1; hcrash = false; myViewWindowX += hdirection; } } // If the duke is blocked vertically, // then the jump or fall in progress stops: if (vcrash) { myIsJumping = NO_JUMP; } // If the duke is blocked horizontally, // forget any horizontal accelleration: if (hcrash) { myIsRunning = 0; } if (dukeSprite.collidesWith(jamesSprite, true)) { myCanvas.setGameOver(); return; } }