Advertisement
Guest User

Untitled

a guest
Apr 29th, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.62 KB | None | 0 0
  1. import java.awt.*;
  2. import java.util.*;
  3.  
  4. public class Project3 { //FINAL VERSION
  5.  
  6. // General constants
  7. public static final Random RANDOM = new Random();
  8.  
  9. public static final int PANEL_WIDTH = 500;
  10. public static final int PANEL_HEIGHT = 400;
  11. public static final int SLEEP_TIME = 50;
  12. public static final Color BACKGROUND_COLOR = Color.WHITE;
  13.  
  14. // Shooter values
  15. public static final Color SHOOTER_COLOR = Color.RED;
  16. public static final int SHOOTER_SIZE = 20;
  17. public static final int GUN_SIZE = 10;
  18. public static final int SHOOTER_POSITION_Y = PANEL_HEIGHT - SHOOTER_SIZE;
  19. public static final int SHOOTER_INITIAL_POSITION_X = PANEL_WIDTH/2;
  20. public static int shooterPositionX;
  21. public static double gunAngle; // in degrees
  22. public static int shooterHitTimer;
  23.  
  24. // Target values
  25. public static final int TARGET_POSITION_Y = 50;
  26. public static final Color TARGET_COLOR = Color.BLUE;
  27. public static final Color TARGET_HIT_COLOR = Color.BLACK;
  28. public static final int TARGET_SIZE = 20;
  29. public static final int TARGET_DELTA_X = 1;
  30. public static int targetPositionX;
  31. public static int targetDeltaX;
  32. public static boolean targetMovement = true;
  33. public static int targetHitTimer; // target hit recently if greater than 0
  34.  
  35. // Shield values
  36. public static final Color SHIELD_COLOR = Color.CYAN;
  37. public static final Color SHIELD_HIT_COLOR = Color.BLACK;
  38. public static boolean shieldActive = true;
  39. public static int shieldHitTimer; // shield hit recently if greater than 0
  40.  
  41.  
  42. // Missile values
  43. public static final int MISSILE_SIZE = 4;
  44. public static final Color MISSILE_COLOR = Color.BLACK;
  45. public static final double MISSILE_SPEED = 1.0;
  46. public static final int HIT_TIMER_MAX = 50;
  47. public static boolean missileActive;
  48. public static double missilePositionX;
  49. public static double missilePositionY;
  50. public static double oldMissilePositionX;
  51. public static double oldMissilePositionY;
  52. public static double missileDeltaX;
  53. public static double missileDeltaY;
  54.  
  55. // Key values
  56. public static final int KEY_SPACE = 32;
  57. public static final int KEY_LEFT_ARROW = 37;
  58. public static final int KEY_UP_ARROW = 38;
  59. public static final int KEY_RIGHT_ARROW = 39;
  60. public static final int KEY_DOWN_ARROW = 40;
  61. public static final int KEY_HOME = 36;
  62. public static final int KEY_PAGE_UP = 33;
  63.  
  64. // scoring values
  65. public static int hitCount;
  66. public static int shooterHitCount;
  67. public static String hitDisplayString;
  68. public static int HEALTH_HEIGHT = 10;
  69. public static int HEALTH_WIDTH = 20;
  70. public static int health;
  71. public static int MAX_HEALTH = 5;
  72. public static boolean gameOver;
  73.  
  74. //target missile values
  75. public static Color TARGET_MISSILE_COLOR = TARGET_COLOR;
  76. public static double TARGET_MISSILE_SPEED = MISSILE_SPEED;
  77. public static double TARGET_SHOOT_PROBABILITY = .1;
  78. public static int MAX_MISSILES = 10;
  79. public static double[] targetMissilePositionX = new double[MAX_MISSILES] ;
  80. public static double[] targetMissilePositionY = new double[MAX_MISSILES];
  81. public static double[] targetMissileDeltaX = new double[MAX_MISSILES];
  82. public static double[] targetMissileDeltaY = new double[MAX_MISSILES];
  83. public static boolean[] targetMissileActive = new boolean[MAX_MISSILES];
  84.  
  85. // main method does initialization and calls startGrame
  86. public static void main(String[] args) {
  87. DrawingPanel panel = new DrawingPanel(PANEL_WIDTH, PANEL_HEIGHT);
  88. Graphics g = panel.getGraphics( );
  89. initialize();
  90. startGame(panel, g);
  91. }
  92.  
  93. // start the main game loop which runs forever
  94. public static void startGame(DrawingPanel panel, Graphics g) {
  95. while(true) {
  96. panel.sleep(SLEEP_TIME);
  97. handleKeys(panel,g);
  98. moveTarget(g);
  99. moveMissile(g);
  100. for(int i=0; i<MAX_MISSILES; i++){
  101. moveTargetMissile(g,i);
  102. }
  103. shieldHitTimer--;
  104. targetHitTimer--;
  105. health = (hitCount - shooterHitCount) * HEALTH_WIDTH;
  106. drawAll(g);
  107. }
  108. }
  109.  
  110. // reset all parameters to start over
  111. public static void reset(Graphics g) {
  112. g.setColor(BACKGROUND_COLOR);
  113. g.fillRect(0,0,PANEL_WIDTH,PANEL_HEIGHT);
  114. initialize();
  115. }
  116.  
  117. // initialize parameters for the start of the program
  118. public static void initialize() {
  119. shooterPositionX = SHOOTER_INITIAL_POSITION_X;
  120. gunAngle = 0;
  121. targetPositionX = PANEL_WIDTH/2;
  122. missileActive = false;
  123. gameOver = false;
  124. hitCount = 0;
  125. shooterHitCount = 0;
  126. targetDeltaX = 0;
  127. targetHitTimer = 0;
  128. shieldHitTimer = 0;
  129. for(int i=0; i<MAX_MISSILES; i++){
  130. targetMissileActive[i] = false;
  131. }
  132. hitDisplayString = "Hits: ";
  133. }
  134.  
  135. // draw everything in its current position
  136. public static void drawAll(Graphics g) {
  137. if(!gameOver){
  138. g.setColor(Color.BLACK);
  139. g.drawString("Project 3 ANNICKMORRIS",10,15);
  140. g.drawString(hitDisplayString,10,30);
  141. drawHealthBar(g);
  142. drawShooter(g,SHOOTER_COLOR);
  143. if (targetHitTimer > 0)
  144. drawTarget(g,TARGET_HIT_COLOR);
  145. else
  146. drawTarget(g,TARGET_COLOR);
  147. Color shieldColor = BACKGROUND_COLOR; // default: do not draw
  148. if (shieldActive) {
  149. if (shieldHitTimer > 0)
  150. shieldColor = SHIELD_HIT_COLOR;
  151. else
  152. shieldColor = SHIELD_COLOR;
  153. }
  154. drawShield(g, shieldColor);
  155. if(gameOver){
  156. g.setColor(Color.MAGENTA);
  157. if(hitCount > shooterHitCount)
  158. g.drawString("YOU WIN!", PANEL_WIDTH/2 - 30, PANEL_HEIGHT/2);
  159. else if(hitCount < shooterHitCount)
  160. g.drawString("YOU LOSE!", PANEL_WIDTH/2 -30, PANEL_HEIGHT/2);
  161. }
  162. }
  163. }
  164.  
  165. // draw the shooter (and gun) in a given color
  166. public static void drawShooter(Graphics g, Color c) {
  167. g.setColor(c);
  168. g.fillOval(shooterPositionX - SHOOTER_SIZE/2,
  169. SHOOTER_POSITION_Y - SHOOTER_SIZE/2,
  170. SHOOTER_SIZE,SHOOTER_SIZE);
  171. // draw gun
  172. int gunx1 = shooterPositionX + (int)Math.round(triangleX(gunAngle,SHOOTER_SIZE/2));
  173. int guny1 = SHOOTER_POSITION_Y - (int)Math.round(triangleY(gunAngle,SHOOTER_SIZE/2));
  174. int gunx2 = shooterPositionX + (int)Math.round(triangleX(gunAngle,SHOOTER_SIZE/2 + GUN_SIZE));
  175. int guny2 = SHOOTER_POSITION_Y - (int)Math.round(triangleY(gunAngle,SHOOTER_SIZE/2 + GUN_SIZE));
  176. g.drawLine(gunx1,guny1,gunx2,guny2);
  177. }
  178.  
  179. // draw the target in a given color
  180. // shoot a missile with a probability of .02
  181. // don't shoot a missile if the target is displayed in black
  182. public static void drawTarget(Graphics g, Color c) {
  183. g.setColor(c);
  184. g.fillOval(targetPositionX - TARGET_SIZE/2,
  185. TARGET_POSITION_Y - TARGET_SIZE/2,
  186. TARGET_SIZE, TARGET_SIZE);
  187. double randomValue = RANDOM.nextDouble();
  188. if(targetHitTimer > 0) {
  189. randomValue = 1;
  190. }
  191. if(randomValue <= TARGET_SHOOT_PROBABILITY){
  192. shootTargetMissile(g);
  193. }
  194. }
  195.  
  196. // draw the shield in a given color
  197. public static void drawShield(Graphics g, Color c) {
  198. g.setColor(c);
  199. g.drawLine(targetPositionX - TARGET_SIZE,
  200. TARGET_POSITION_Y + TARGET_SIZE,
  201. targetPositionX + TARGET_SIZE,
  202. TARGET_POSITION_Y + TARGET_SIZE);
  203. }
  204.  
  205. // move the shooter by a given amount
  206. public static void moveShooter(Graphics g, int deltaX) {
  207. drawShooter(g,BACKGROUND_COLOR);
  208. shooterPositionX = shooterPositionX + deltaX;
  209. if (shooterPositionX + SHOOTER_SIZE/2 > PANEL_WIDTH)
  210. shooterPositionX = PANEL_WIDTH - SHOOTER_SIZE/2;
  211. if (shooterPositionX - SHOOTER_SIZE/2 < 0)
  212. shooterPositionX = SHOOTER_SIZE/2;
  213. drawShooter(g,SHOOTER_COLOR);
  214. }
  215.  
  216. // change the gun angle by the given amount (in degrees)
  217. // make sure gun points at least a little bit up
  218. public static void moveGun(Graphics g, double gunDelta) {
  219. drawShooter(g,BACKGROUND_COLOR);
  220. gunAngle += gunDelta;
  221. if (gunAngle > 85)
  222. gunAngle = 85;
  223. if (gunAngle < -85)
  224. gunAngle = -85;
  225. drawShooter(g,SHOOTER_COLOR);
  226. }
  227.  
  228. // move the target horizontally by targetDeltaX
  229. // don't move the target if it is displayed in black
  230. // reset targetDeltaX with probabilty .06.
  231. // If changed, it is changed to 0, TARGET_DELTA_X, or -TARGET_DELTA_X with equal probability
  232. public static void moveTarget(Graphics g) {
  233. if (!targetMovement)
  234. return;
  235. drawTarget(g, BACKGROUND_COLOR);
  236. drawShield(g, BACKGROUND_COLOR);
  237. targetPositionX += targetDeltaX;
  238. if (targetPositionX + TARGET_SIZE/2 > PANEL_WIDTH)
  239. targetDeltaX = -TARGET_DELTA_X;
  240. if (targetPositionX - TARGET_SIZE/2 < 0)
  241. targetDeltaX = TARGET_DELTA_X;
  242. double randomMove = RANDOM.nextDouble();
  243. if (randomMove > .98)
  244. targetDeltaX = TARGET_DELTA_X;
  245. else if (randomMove > .96)
  246. targetDeltaX = -TARGET_DELTA_X;
  247. else if (randomMove > .94)
  248. targetDeltaX = 0;
  249. if(targetHitTimer > 0){
  250. targetDeltaX = 0;
  251. }
  252. }
  253.  
  254. // shoot a missile unless one is already active
  255. public static void shootMissile(Graphics g) {
  256. if (missileActive)
  257. return;
  258. missileActive = true;
  259. double gunx1 = shooterPositionX + triangleX(gunAngle,SHOOTER_SIZE/2);
  260. double guny1 = SHOOTER_POSITION_Y - triangleY(gunAngle,SHOOTER_SIZE/2);
  261. double gunx2 = shooterPositionX + triangleX(gunAngle,SHOOTER_SIZE/2 + GUN_SIZE);
  262. double guny2 = SHOOTER_POSITION_Y - triangleY(gunAngle,SHOOTER_SIZE/2 + GUN_SIZE);
  263. missilePositionX = gunx1;
  264. missilePositionY = guny1;
  265. missileDeltaX = (gunx2-gunx1) * MISSILE_SPEED;
  266. missileDeltaY = (guny2-guny1) * MISSILE_SPEED;
  267. oldMissilePositionX = missilePositionX;
  268. oldMissilePositionY = missilePositionY;
  269. }
  270.  
  271. // draw the missile in the given color
  272. public static void drawMissile(Graphics g, Color c) {
  273. int x = (int)(missilePositionX + .5) - MISSILE_SIZE/2;
  274. int y = (int)(missilePositionY + .5) - MISSILE_SIZE/2;
  275. g.setColor(c);
  276. g.fillOval(x,y,MISSILE_SIZE,MISSILE_SIZE);
  277. }
  278.  
  279. // move the missile if it is active
  280. // check to see if the missile:
  281. // hits the target
  282. // hits the shield
  283. // bounces off the top or sides
  284. // disappears off the bottom of the screen
  285. public static void moveMissile(Graphics g) {
  286. if (!missileActive)
  287. return;
  288. drawMissile(g,BACKGROUND_COLOR);
  289. oldMissilePositionX = missilePositionX;
  290. oldMissilePositionY = missilePositionY;
  291. missilePositionX += missileDeltaX;
  292. missilePositionY += missileDeltaY;
  293. drawMissile(g,MISSILE_COLOR);
  294. if (missilePositionY > PANEL_HEIGHT) {
  295. drawMissile(g,BACKGROUND_COLOR);
  296. missileActive = false;
  297. }
  298. if (missilePositionY - MISSILE_SIZE/2 < 0)
  299. missileDeltaY = Math.abs(missileDeltaY);
  300. if (missilePositionX - MISSILE_SIZE/2 < 0)
  301. missileDeltaX = Math.abs(missileDeltaX);
  302. if (missilePositionX + MISSILE_SIZE/2 > PANEL_WIDTH)
  303. missileDeltaX = -Math.abs(missileDeltaX);
  304. if (missileActive && shieldActive && (shieldHitTimer <= 0) && detectShieldHit()) {
  305. drawMissile(g,BACKGROUND_COLOR);
  306. missileActive = false;
  307. shieldHitTimer = HIT_TIMER_MAX;
  308. }
  309. if (missileActive && detectHitTarget()) {
  310. drawMissile(g,BACKGROUND_COLOR);
  311. missileActive = false;
  312. targetHitTimer = HIT_TIMER_MAX;
  313. hitCount++;
  314. hitDisplayString += "*";
  315. }
  316. }
  317.  
  318. //move the target missile if it is active
  319. //check to see if the missile disappears off the botttom of the screen, or bounces off the sides
  320. public static void moveTargetMissile(Graphics g, int i) {
  321. if (!targetMissileActive[i])
  322. return;
  323. drawTargetMissile(g,BACKGROUND_COLOR, i);
  324. targetMissilePositionX[i] += targetMissileDeltaX[i];
  325. targetMissilePositionY[i] += targetMissileDeltaY[i];
  326. drawTargetMissile(g,MISSILE_COLOR, i);
  327. if (targetMissilePositionY[i] > PANEL_HEIGHT) {
  328. drawTargetMissile(g,BACKGROUND_COLOR, i);
  329. targetMissileActive[i] = false;
  330. }
  331. if (targetMissilePositionY[i] - MISSILE_SIZE/2 < 0)
  332. targetMissileDeltaY[i] = Math.abs(targetMissileDeltaY[i]);
  333. if (targetMissilePositionX[i] - MISSILE_SIZE/2 < 0)
  334. targetMissileDeltaX[i] = Math.abs(targetMissileDeltaX[i]);
  335. if (targetMissilePositionX[i] + MISSILE_SIZE/2 > PANEL_WIDTH)
  336. targetMissileDeltaX[i] = -Math.abs(targetMissileDeltaX[i]);
  337. if (targetMissileActive[i] && detectHitShooter(i)) {
  338. drawTargetMissile(g,BACKGROUND_COLOR, i);
  339. targetMissileActive[i] = false;
  340. shooterHitTimer = HIT_TIMER_MAX;
  341. shooterHitCount++;
  342. hitDisplayString += "!";
  343. }
  344. }
  345.  
  346. // returns true if the circle at (x1,y1) with radius r1 intersects the circle at (x2,y2) with radius r2
  347. public static boolean detectIntersection(int x1, int y1, int r1, int x2, int y2, int r2) {
  348. return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) < (r1+r2)*(r1+r2);
  349. }
  350.  
  351. // returns true if the missile has hit the target
  352. public static boolean detectHitTarget() {
  353. return detectIntersection(targetPositionX, TARGET_POSITION_Y, TARGET_SIZE/2,
  354. (int)(missilePositionX + .5),(int)(missilePositionY + .5),
  355. MISSILE_SIZE/2);
  356. }
  357.  
  358. //returns true if the target missile has hit the shooter
  359. public static boolean detectHitShooter(int i) {
  360. return detectIntersection(shooterPositionX, SHOOTER_POSITION_Y, TARGET_SIZE/2,
  361. (int)(targetMissilePositionX[i] + .5),(int)(targetMissilePositionY[i] + .5),
  362. MISSILE_SIZE/2);
  363. }
  364.  
  365. // return true if the missile has hit the shield
  366. // Use the old missile position and the new missile position to see
  367. // if the line segment between these two intersects the shield
  368. // Only check if the missile is moving up
  369. public static boolean detectShieldHit() {
  370. double intersectX;
  371. int shieldPositionY = TARGET_POSITION_Y + TARGET_SIZE;
  372. if ((oldMissilePositionY < shieldPositionY) ||
  373. (missilePositionY > shieldPositionY))
  374. return false;
  375. if (oldMissilePositionX == missilePositionX)
  376. intersectX = missilePositionX;
  377. else {
  378. double slope = (oldMissilePositionY-missilePositionY)/(oldMissilePositionX-missilePositionX);
  379. intersectX = (shieldPositionY-missilePositionY)/slope + missilePositionX;
  380. }
  381. return (intersectX >= targetPositionX - TARGET_SIZE) &&
  382. (intersectX <= targetPositionX + TARGET_SIZE);
  383. }
  384.  
  385. // return the side opposite the given angle of a right triangle with given hypotenuse
  386. public static double triangleX(double angleDegrees, double hypotenuse) {
  387. double angleRadians = angleDegrees * Math.PI/180;
  388. return hypotenuse * Math.sin(angleRadians);
  389. }
  390.  
  391. // return the side adjacent to the given angle of a right triangle with the given hypotenuse
  392. public static double triangleY(double angleDegrees, double hypotenuse) {
  393. double angleRadians = angleDegrees * Math.PI/180;
  394. return hypotenuse * Math.cos(angleRadians);
  395. }
  396.  
  397. // draw the target missile in the given color
  398. public static void drawTargetMissile(Graphics g, Color c, int i) {
  399. int x = (int)(targetMissilePositionX[i] + .5) - MISSILE_SIZE/2;
  400. int y = (int)(targetMissilePositionY[i] + .5) - MISSILE_SIZE/2;
  401. g.setColor(c);
  402. g.fillOval(x,y,MISSILE_SIZE,MISSILE_SIZE);
  403. }
  404.  
  405. // shoot a target missile unless one is already active
  406. public static void shootTargetMissile(Graphics g) {
  407. if (findTargetMissilePosition() == -1)
  408. return;
  409. int i = findTargetMissilePosition();
  410. targetMissileActive[i] = true;
  411. targetMissilePositionX[i] = targetPositionX;
  412. targetMissilePositionY[i] = TARGET_POSITION_Y;
  413.  
  414. int angle = RANDOM.nextInt();
  415.  
  416. targetMissileDeltaX[i] = triangleX(angle, TARGET_SIZE/2);
  417. targetMissileDeltaY[i] = triangleY(0, TARGET_SIZE/2);
  418. }
  419.  
  420. //return the index of a missile that is not active
  421. public static int findTargetMissilePosition(){
  422. int x = -1;
  423. for(int i=0; i<MAX_MISSILES; i++){
  424. if(targetMissileActive[i] == false)
  425. x = i;
  426. }
  427. return x;
  428. }
  429.  
  430. //draws the health bar on the top right of the screen
  431. //uses hitCount and shooterHitCount to calculate who is winning
  432. //draws in appropriate color
  433. public static void drawHealthBar(Graphics g){
  434. g.setColor(BACKGROUND_COLOR);
  435. g.fillRect(PANEL_WIDTH - 4 - (HEALTH_WIDTH*MAX_HEALTH), 5, HEALTH_WIDTH*MAX_HEALTH, HEALTH_HEIGHT);
  436. health = Math.abs(hitCount - shooterHitCount);
  437. if(health == MAX_HEALTH)
  438. gameOver = true;
  439. if(hitCount > shooterHitCount)
  440. g.setColor(SHOOTER_COLOR);
  441. else if(hitCount < shooterHitCount)
  442. g.setColor(TARGET_COLOR);
  443. if(health != 0){
  444. g.fillRect(PANEL_WIDTH - 4 - (health*HEALTH_WIDTH), 5, health*HEALTH_WIDTH, HEALTH_HEIGHT);
  445. }
  446. g.setColor(Color.BLACK);
  447. g.drawRect(PANEL_WIDTH - 4 - (HEALTH_WIDTH*MAX_HEALTH), 5, HEALTH_WIDTH*MAX_HEALTH, HEALTH_HEIGHT);
  448. }
  449.  
  450.  
  451.  
  452. // take action based on which key is pressed
  453. public static void handleKeys(DrawingPanel panel, Graphics g) {
  454. int keyCode = panel.getKeyCode();
  455. if (keyCode == KEY_SPACE)
  456. reset(g);
  457. else if (keyCode == KEY_RIGHT_ARROW)
  458. moveShooter(g,1);
  459. else if (keyCode == KEY_LEFT_ARROW)
  460. moveShooter(g,-1);
  461. else if (keyCode == KEY_HOME)
  462. moveGun(g,-1);
  463. else if (keyCode == KEY_PAGE_UP)
  464. moveGun(g,1);
  465. else if (keyCode == KEY_UP_ARROW)
  466. shootMissile(g);
  467. else if (keyCode == 'S')
  468. shieldActive = !shieldActive;
  469. else if (keyCode == 'M')
  470. targetMovement = !targetMovement;
  471. }
  472.  
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement