/** * @(#)Player.java 1.0.1 98/12/04 *
* Copyright (C) 1998 David E. Wexler *
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. See * license.txt for a full copy of the GNU GPL. *
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. *
* To Contact the author send e-mail to vagabond@netdragon.com or send * snailmail to: 511 Bobcat Ct, Punta Gorda, FL 3398. */ import java.applet.Applet; import java.awt.*; /** * Nelzan - Handles all information dealing with the player *
* Controls Player Movement, shields, weapons, lives, score, painting, * and collisions. * *
* @author David Wexler (vagabond@netdragons.com)
* @version 1.0.2
* @since Nelzan1.0.1
*/
class Player {
private Image[] myImages;
private int myX;
private int myY;
private int dir;
private int prevX[] = new int[5];
private int prevY[] = new int[5];
private int activeWeapon = 0;
private int weapon[] = {4, 3, 0, 0};
private static final int weaponDamage[] = {10, 8, 5, 10};
private static final int weaponRange[] = {1, 3, 8, 5};
private static final int weaponSpeed[] = {13, 12, 8, 10};
private int fire[] = {-1, -1, -1, -1, -1};
private int fireX[] = {-1, -1, -1, -1, -1};
private int fireY[] = {-1, -1, -1, -1, -1};
private int count = 0;
private int invincible = 0; // 0 - 20 invencible
private int originalX, originalY;
/**
* Player Score.
*/
public int score = 0;
/**
* Number of lives the player has.
*/
public int lives = 3;
/**
* Current Level of shields.
*/
public int shields = 100;
/**
* Level Player is on.
*/
public int level = 1;
/**
* Array for storing directions.
*/
boolean[] direction = {false, false, false, false};
/**
* Array used for more acurate game play. Will cause the user's
* movement to speed up when motion is continued, and not to stop
* instantly.
*/
private int[] speed = { 0, 0, 0, 0 };
/**
* Array of colors used for drawing Shields and weapons.
*/
public Color shieldColor[];
/**
* Instance of Applet, for call backs.
*/
Applet comp;
/**
* Creates a player at and an x, y location with specified images.
*
* @param img Images that represent the player.
* @param startX Players starting X location.
* @param startY Players starting Y location.
* @param c Instance of an Applet, for call backs.
*/
Player(Image[] img, int startX, int startY, Applet c) {
myImages = img;
myX = startX;
myY = startY;
originalX = startX;
originalY = startY;
comp = c;
for (int i = 4; i > -1; i--) {
prevX[i] = startX + i*3;
prevY[i] = startY;
}
shieldColor = new Color[100];
buildShieldColor();
}
/**
* Used to paint the player and weapons.
*
* @param g Graphics to paint to.
*/
public void paint(Graphics g) {
if (invincible%2 == 0) {
if (direction[0])
g.drawImage(myImages[1], myX, myY, comp);
else if (direction[2])
g.drawImage(myImages[2], myX, myY, comp);
else
g.drawImage(myImages[0], myX, myY, comp);
}
for (int i = 4; i > 0; i--) {
g.setColor(shieldColor[i*19]);
g.fillRect(prevX[i]+2, prevY[i]+3+(i/2), 2, 5-i);
prevX[i] = prevX[i-1]-2;
prevY[i] = prevY[i-1];
}
for (int i = 0; i < 5; i++) {
if (fire[i] != -1) {
for (int j = 0; j < weapon[fire[i]]; j++) {
g.setColor(shieldColor[j*9]);
if (fire[i] == 0) {
g.drawLine(fireX[i]-j, fireY[i]-j, fireX[i]+10-j, fireY[i]-j);
g.drawLine(fireX[i]-j, fireY[i]+j, fireX[i]+10-j, fireY[i]+j);
} else if (fire[i] == 1) {
g.drawLine(fireX[i], fireY[i]-(j*2), fireX[i]+12-j/2, fireY[i]-(j*2));
g.drawLine(fireX[i], fireY[i]+(j*2), fireX[i]+12-j/2, fireY[i]+(j*2));
} else if (fire[i] == 2) {
g.drawArc(fireX[i], fireY[i]-j*6, j*12, j*12, 90,-180);
} else if (fire[i] == 3) {
g.drawLine(fireX[i]-j, fireY[i]-j*4, fireX[i]+10+j*3, fireY[i]);
g.drawLine(fireX[i]-j, fireY[i]+j*4, fireX[i]+10+j*3, fireY[i]);
}
}
if (fireX[i] > 620)
killFire(i);
}
}
dir = 0;
}
/**
* Updates player and fired ammo location.
*/
public void update() {
for (int i = 0; i < 5; i++) {
if (fire[i] != -1)
fireX[i] += weaponSpeed[fire[i]];
}
for (int i = 0; i < 4; i++) {
if (direction[i])
move(i, 1);
else if (speed[i] > 0)
move(i, -1);
}
if (invincible < 40)
invincible += 1;
if (shields < 0)
killMe();
}
/**
* Gets the number of the current weapon.
*
* @return an int based on the selected weapon.
*/
public int getActiveWeapon() {
return activeWeapon;
}
/**
* Gets the currently selected Weapons level.
*
* @return an int based on the selected weapon's level.
*/
public int getWeaponLevel() {
return weapon[activeWeapon];
}
/**
* Sets players weapon to inputed value. It only does this if the
* level of the weapon is greater than 0.
*
* @param i Weapon number to set to.
*/
public void setActiveWeapon(int i) {
if (weapon[i] != 0)
activeWeapon = i;
}
/**
* Tells the player to fire it's weapon if it can.
*/
public void fire() {
if (count < 5) {
fire[count] = activeWeapon;
fireX[count] = myX + 100;
fireY[count++] = myY + 25;
}
}
/**
* Sets direction[i] to true. This is used so the player will continually
* move in the selected direction until setMoveFalse(i) is called.
*
* @param i The direction to set.
* @see #setMoveFalse(int i).
*/
public void setMoveTrue(int i) {
direction[i] = true;
}
/**
* Sets direction[i] to false. This is used so the player will stop
* moving in the selected direction.
*
* @param i The direction to set.
*/
public void setMoveFalse(int i) {
direction[i] = false;
}
/**
* Tells the player to move in direction i.
*
* @param i The Direction to move.
*/
public void move(int i, int a) {
switch (i) {
case 0: myY -= (5+setSpeed(i,a));
break;
case 1: myX += (3+setSpeed(i,a));
break;
case 2: myY += (5+setSpeed(i,a));
break;
case 3: myX -= (3+setSpeed(i,a));
break;
}
if (checkBounds()) {
dir = i;
for (i = 4; i > 0; i--) {
prevX[i] = prevX[i-1]-2;
prevY[i] = prevY[i-1];
}
prevX[0] = myX;
prevY[0] = myY;
}
}
/**
* Function allows enemy weapons to home in on players location. Depending
* on the weapons location, the function will return a positive, negative,
* or zero.
*
* @param y Fired weapons y location.
* @return 2 if y > player Y, -2
* otherwise.
*/
public int getYMovement(int y) {
if (y+10 < myY)
return 2;
else if (y-10 > myY)
return -2;
return 0;
}
/**
* This fuction handles collisions. If the player or the players'
* weapons hit the an enemy object, this function will return the
* damage that is done, and cause damage when needed.
*
* @param x Enemy x location.
* @param y Enemy y location.
* @param w Enemy's width.
* @param h Enemy's height.
* @param t Enemy's Type.
* @param d Enemy's Shield level.
* @return WeaponDamage if getting hit by weapon,
* d if coliding with player,
* 0 otherwise.
*/
public int damage(int x, int y, int w, int h, int t, int d) {
for (int i = 0; i < 4; i++) {
if (fire[i] != -1) {
int range = weaponRange[fire[i]];
if (x > fireX[i] - range - w && x < fireX[i] + range &&
y > fireY[i] - range - h && y < fireY[i] + range) {
int damage = weaponDamage[fire[i]] * weapon[i];
killFire(i);
return damage;
}
}
}
if (x > myX - w && x < myX + 100 && y > myY - h && y < myY + 30 &&
invincible == 40) {
if (t < 0 && t != -10)
givePowerUp(t);
else
shields -= d;
return d+1;
}
return 0;
}
/**
* Checks to see if the Enemy's weapon is hitting the player.
*
* @param x Enemy x location.
* @param y Enemy y location.
* @param w Enemy's width.
* @param h Enemy's height.
* @param d How much damage the weapon will cause.
* @return true if the weapon hits,
* false otherwise.
*/
public boolean checkAttack(int x, int y, int w, int h, int d) {
if (x > myX - w && x < myX + 100 && y > myY - h && y < myY + 30 &&
invincible == 40) {
shields -= d;
return true;
}
return false;
}
/**
* Function handles giving the player powerup's like shields, weapons,
* and extra lives.
*
* @param i Type of power up to give.
*/
private void givePowerUp(int t) {
switch (t) {
case -1: addShield(100);
break;
case -2:
case -3:
case -4:
case -5: addWeapon(-t - 2);
break;
case -6: addLife();
break;
}
}
/**
* Addes power back to the player's shields. Shields cannot exceed 200,
* so proper checks are in place.
*
* @param a Value to add to current shield levels.
*/
private void addShield(int a) {
shields += a;
if (shields > 200)
shields = 200;
}
/**
* Addes one level to a Weapon. Weapons cannot exceed a level of 10,
* so proper checks are in place.
*
* @param i Weapon number to add 1 to.
*/
private void addWeapon(int i) {
weapon[i] += 1;
if (weapon[i] > 10)
weapon[i] = 10;
}
/**
* Addes one life to the player. Lives cannot exceed 7, so proper
* checks are in place.
*/
private void addLife() {
lives += 1;
if (lives > 7)
lives = 7;
}
/**
* Makes sure the player doesn't leave the playing area.
*
* @return true if the player is out of bounds,
* false otherwise.
*/
private boolean checkBounds() {
if (myX < 5) {
myX = 5;
return false;
} if (myX > 350) {
myX = 350;
return false;
} if (myY < 5) {
myY = 5;
return false;
} if (myY > 335) {
myY = 335;
return false;
}
return true;
}
/**
* Removes a fired weapon from the array. Because weapons can move at
* different speeds this is a little more complex, but it gets the job done.
*
* @param w Weapon to kill.
*/
private void killFire(int w) {
boolean removed = false;
for (int i = 0; i < 4; i++) {
if (i == w)
removed = true;
if (removed) {
fire[i] = fire[i+1];
fireX[i] = fireX[i+1];
fireY[i] = fireY[i+1];
}
}
fire[4] = -1;
count -= 1;
}
/**
* Kills the player. Causes them to move back to the original starting x,
* y, and will give them about 2 second "free" play.
*/
public void killMe() {
invincible = 0;
shields = 100;
level = 1;
myX = originalX;
myY = originalY;
for (int i = 0; i < 4; i++) {
if (weapon[i] > 0)
weapon[i] -= 1;
direction[i] = false;
}
if (weapon[0] < 2)
weapon[0] = 2;
lives -= 1;
}
/**
* Adds or subtracts to speed array.
*
* @param i speed to manipulate
* @param a Ammount to add or subtract
* @return The current speed level
*/
private int setSpeed(int i, int a) {
speed[i] += a;
if (speed[i] > 3)
speed[i] = 3;
if (a > 0)
return speed[i];
else
return 3-speed[i];
}
/**
* Builds an array of shield colors for later use. This Array and function
* is designed to save speed at runtime.
*/
private void buildShieldColor() {
for (int i = 0; i < 100; i++) {
shieldColor[i] = new Color(250-(i*2),0,i*2+50);
}
}
}