import java.awt.*;
/*
*----------------------------------------------------------------------
*
* Player.java
*/
/**
This class controls the players.
*/
/*
*----------------------------------------------------------------------
*/
public class Player extends Moving {
/**
How many bullets each player has.
Currently set to 6, and will always be.
*/
public static final int magSize = 6;
private Bullet bullets[] = new Bullet[magSize];
private int ammo = magSize;
/*
* Vertical offset to where the bullets start.
*/
private int gunY;
private int sizeX, sizeY;
/*
* Rectangle that determines where the player has his feet.
* Used to prevent the player to walk over obstacles.
*/
private Rectangle walk;
/*
* Rectangle that determines the area the player is sensitive
* to bullets.
*/
private Rectangle hit;
/*
* Offsets the walk/hit rectangle and coord is translated
* with when the player turns around.
*/
private int turnWalk, turnHit, turn;
private Image frames[];
private int framePointer;
private int dx, dy; // Player speed.
private boolean faceRight;
/*
* Every scene first two obstacles are ammo boxes,
* so the obstacle with index playerId is this
* player ammo box.
*/
private int playerId;
/**
* Used to be able to give the other player points
* when hit by a bullet and to find out which player died.
*/
public int otherPlayer;
/*
* Only animate the player when this gets zero.
*/
private int anim_counter = 0;
/*
* Animate player every animRate update.
*/
private int animRate;
/*
*----------------------------------------------------------------------
*
* Player
*/
/**
@param f Player frames.
@param props Contains a lot of different values that initialises the player.
See the Player.java and
Gunfighter.java for more details.
@param fr Determines if the player starts facing right or not.
Also used to determine which player the player is.
*/
/*
*----------------------------------------------------------------------
*
*/
public Player(Image f[], int props[], boolean fr) {
coord = new Point(props[0], props[1]);
frames = f;
framePointer = props[2];
for (int n = 0; n < magSize; n++) {
bullets[n] = new Bullet();
}
faceRight = fr;
if (faceRight) {
playerId = 0;
otherPlayer = 1;
} else {
playerId = 1;
otherPlayer = 0;
}
hit = new Rectangle(coord.x + props[3], coord.y + props[4],
props[5], props[6]);
turnHit = props[7];
walk = new Rectangle(coord.x + props[8], coord.y + props[9],
props[10], props[11]);
turnWalk = props[12];
turn = props[13];
sizeX = props[14];
sizeY = props[15];
gunY = props[16];
animRate = props[17];
}
/*
*----------------------------------------------------------------------
*
* die
*/
/**
This method is called when the player been hit by a bullet.
Makes the player scream. Updates the score too.
*/
/*
*----------------------------------------------------------------------
*
*/
public void die() {
for (int n = 0; n < 4; n++) { // Silence other sound effects.
Gunfighter.sfx[n].stop();
}
Gunfighter.sfx[4].play(); // Scream.
Gunfighter.kills[otherPlayer]++; // Update score.
Gunfighter.latestPoint = otherPlayer;
Gunfighter.gameState = 4; // New duel.
}
/*
*----------------------------------------------------------------------
*
* draw
*/
/**
Draws the player.
Uncomment the commented lines if you would like to see how
the walk and hit rectangles work.
*/
/*
*----------------------------------------------------------------------
*
*/
public void draw(Graphics g) {
g.drawImage(frames[framePointer], coord.x, coord.y, null);
// g.drawRect(hit.x, hit.y, hit.width, hit.height);
// g.drawRect(walk.x, walk.y, walk.width, walk.height);
}
/*
*----------------------------------------------------------------------
*
* drawBullets
*/
/**
Draws the players moving bullets.
*/
/*
*----------------------------------------------------------------------
*
*/
public void drawBullets(Graphics g) {
for (int n = 0; n < magSize; n++) {
if (!bullets[n].dead) {
bullets[n].draw(g);
}
}
}
/*
*----------------------------------------------------------------------
*
* getAmmo
*/
/**
@return How many bullets the player has left.
@see Gunfighter#drawStatus
*/
/*
*----------------------------------------------------------------------
*
*/
public int getAmmo() {
return ammo;
}
/*
*----------------------------------------------------------------------
*
* getHit
*/
/**
@return The rectangle where it's fatal to get a bullet.
*/
/*
*----------------------------------------------------------------------
*
*/
public Rectangle getHit() {
return hit;
}
/*
*----------------------------------------------------------------------
*
* shoot
*/
/**
Fire the gun.
But only if we have ammo and we're able.
*/
/*
*----------------------------------------------------------------------
*
*/
public void shoot() {
if (ammo > 0) {
int shot = ableToShoot();
if (shot < magSize) {
Gunfighter.sfx[0].play();
ammo--;
if (faceRight) {
bullets[shot].fire(coord.x + sizeX, coord.y + gunY, 6);
} else {
bullets[shot].fire(coord.x, coord.y + gunY, -6);
}
} else {
Gunfighter.sfx[2].play();
}
} else {
Gunfighter.sfx[2].play();
}
}
/*
*----------------------------------------------------------------------
*
* update
*/
/**
Updates the player and his bullets.
*/
/*
*----------------------------------------------------------------------
*
*/
public void update() {
if (!collide(2 * dx, 2 * dy)) {
coord.translate(dx, dy);
walk.translate(dx, dy);
hit.translate(dx, dy);
}
if (anim_counter == 0) {
animate();
anim_counter = animRate;
} else {
anim_counter--;
}
for (int n = 0; n < magSize; n++) {
if (!bullets[n].dead) {
bullets[n].update();
}
}
}
/*
*----------------------------------------------------------------------
*
* userInput
*/
/**
Acts on user input if the player doesn't collide with something.
*/
/*
*----------------------------------------------------------------------
*
*/
public void userInput(int key, boolean key_pressed) {
if (key_pressed && !collide(2 * dx, 2 * dy)) {
switch(key) {
case 1: // Go up.
dy = -2;
break;
case 2: // Go right.
if (!faceRight) { // Turn around if we need and can.
if (!collide(turnWalk, 0)) {
faceRight = true;
walk.translate(turnWalk, 0);
hit.translate(turnHit, 0);
coord.translate(turn, 0);
framePointer = 0;
dx = 2;
}
} else {
dx = 2;
}
break;
case 3: // Go down.
dy = 2;
break;
case 4: // Go left.
if (faceRight) { // Turn around if we need and can.
if (!collide(-turnWalk, 0)) {
faceRight = false;
walk.translate(-turnWalk, 0);
hit.translate(-turnHit, 0);
coord.translate(-turn, 0);
framePointer = 3;
dx =-2;
}
} else {
dx = -2;
}
break;
case 5: // Try to shoot.
shoot();
break;
default:
break;
}
} else { // Key released.
switch(key) {
case 1:
dy = 0; // Stop walking up.
break;
case 2:
dx = 0; // Stop walking right.
break;
case 3:
dy = 0; // Stop walking down.
break;
case 4:
dx = 0; // Stop walking left.
break;
default:
break;
}
}
}
/*
*----------------------------------------------------------------------
*
* ableToShoot
*
* Checks if the player is able to shoot.
* Return the index of first available bullet.
*
*----------------------------------------------------------------------
*
*/
private int ableToShoot() {
/*
* Check if we stand in a valid position to prevent
* shooting across the vertical borders without giving
* the other player a chance to see the bullet coming.
*/
if (ammo > 0 && ((faceRight && coord.x < Gunfighter.screenWidth - 110 - sizeX) ||
(!faceRight && coord.x > 110))) {
for (int n = 0; n < magSize; n++) {
if (bullets[n].dead) {
return n;
}
}
}
return magSize; // Not able to shoot
}
/*
*----------------------------------------------------------------------
*
* animate
*
* Animates the player.
* Frame 0-2 when facing right and 5-3 facing left.
*
*----------------------------------------------------------------------
*/
private void animate() {
if (faceRight) {
if (dx > 0 || dy != 0 ) {
if (++framePointer > 2) {
framePointer=0;
}
}
} else {
if (dx < 0 || dy != 0) {
if (--framePointer < 3) {
framePointer=5;
}
}
}
}
/*
*----------------------------------------------------------------------
*
* collide
*
* Checks if the player can move in desired direction.
*
*----------------------------------------------------------------------
*
*/
private boolean collide(int x, int y) {
int i=0;
int j=0;
boolean collision = false;
Rectangle helpRect = new Rectangle(walk.x, walk.y, walk.width, walk.height);
helpRect.translate(x,y);
/*
* Check against the screen borders.
*/
if ((helpRect.x < 0) || ((hit.y + dy)< 0) ||
((helpRect.x + helpRect.width) > Gunfighter.screenWidth) ||
((helpRect.y + helpRect.height) > Gunfighter.screenHeight - 40) ) {
collision = true;
} /*
* Check for collision with the other player.
*/
else if (helpRect.intersects(Gunfighter.actor[otherPlayer].walk)) {
collision = true;
} else {
/*
* Check the obstacles.
*/
while (!collision && (i < Gunfighter.obstacles.length)) {
Polygon poly = Gunfighter.obstacles[i].getPolygon();
/*
* Check if close to an obstacle
*/
if (helpRect.intersects(poly.getBoundingBox())) {
/*
* Yes, check if some of the
* new walk rectangles corners are inside the
* obstacles polygon...
*/
if ( poly.inside(helpRect.x, helpRect.y) ||
poly.inside(helpRect.x, helpRect.y + helpRect.height) ||
poly.inside(helpRect.x + helpRect.width, helpRect.y)||
poly.inside(helpRect.x + helpRect.width, helpRect.y +
helpRect.height) ) {
collision = true;
} /*
* ...or if one the obstacles points are inside
* the new walk rectangle.
*/
else while(!collision && (j < poly.npoints)) {
if (helpRect.inside(poly.xpoints[j], poly.ypoints[j])) {
collision = true;
}
j++;
}
}
i++;
j=0;
}
if ((i - 1) == playerId) { // Bumped into our ammo box.
reload();
}
}
return collision;
}
/*
*----------------------------------------------------------------------
*
* reload
*
* Reloads the gun, but only wheen needed.
*
*----------------------------------------------------------------------
*
*/
private void reload() {
if (ammo != magSize) {
Gunfighter.sfx[3].play();
ammo = magSize;
}
}
}