/** * @(#)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); } } }