PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/game/Game.java

https://github.com/kflorence/pathfinding-java
Java | 432 lines | 219 code | 83 blank | 130 comment | 19 complexity | c82bd5318cd32f75a0cebedd9753928e MD5 | raw file
  1. package game;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.FontMetrics;
  5. import java.awt.Graphics2D;
  6. import java.awt.image.BufferStrategy;
  7. import java.util.ArrayList;
  8. import javax.swing.JFrame;
  9. import game.map.*;
  10. import game.modules.Graphics;
  11. import game.modules.MouseEvents;
  12. import game.modules.WindowEvents;
  13. import game.entities.*;
  14. // Static class Game
  15. public class Game
  16. {
  17. /**
  18. *
  19. * DEBUG AND TESTING VARIABLES
  20. *
  21. **/
  22. // Screen refresh information
  23. private static long timeElapsed, frameDelay;
  24. private static int frameCount, framesPerSecond;
  25. // Number of entities in our game (will be dynamic later)
  26. private static int entityCount = 1;
  27. /**
  28. *
  29. * PERMANENT VARIABLES
  30. *
  31. **/
  32. // Variables relating to the game environment
  33. private static Map map;
  34. // Variables for the window environment
  35. private static JFrame frame;
  36. // The title of the game
  37. public static final String GAMETITLE = "jUntitled";
  38. // Font settings
  39. public static Font font;
  40. public static int fontWidth;
  41. public static int fontHeight;
  42. public static FontMetrics fontMetrics;
  43. // Game States
  44. public static final int MENU = 0;
  45. public static final int ABOUT = 1;
  46. public static final int SCORES = 2;
  47. public static final int PLAY = 3;
  48. public static final int GAMEOVER = 4;
  49. // Initial game state
  50. private static int state = MENU;
  51. // The width and height of the game window
  52. public static final int WIDTH = 800;
  53. public static final int HEIGHT = 600;
  54. // Frame delay rates (milliseconds)
  55. private static final int DELAY = 10;
  56. private static final int DEBUGDELAY = 10;
  57. // Variables relating to the state of the game
  58. private static boolean debug = true;
  59. private static boolean waiting = true;
  60. private static boolean running = true;
  61. // KeyHandler conditions
  62. private static boolean paused = false;
  63. private static boolean locked = false;
  64. // Entity lists for keeping track of the entities in the game
  65. private static ArrayList<Entity> entityList = new ArrayList<Entity>();
  66. private static ArrayList<Entity> removeList = new ArrayList<Entity>();
  67. /**
  68. *
  69. * Private functions
  70. *
  71. **/
  72. // Initializes the game
  73. private static void initialize()
  74. {
  75. // TODO: this is where most of the initial loading/parsing will take place
  76. // - load resource file (links to images, sounds and files)
  77. // - load map file (grid size, node information) * passed to Map
  78. // - load entity file (entity images, states and other information)
  79. // Initialize frame and set properties
  80. frame = new JFrame();
  81. // Frame settings
  82. frame.setTitle(GAMETITLE);
  83. frame.setResizable(false);
  84. // Font settings
  85. font = new Font("Arial", Font.PLAIN, 12);
  86. fontMetrics = frame.getFontMetrics(font);
  87. fontWidth = fontMetrics.getMaxAdvance();
  88. fontHeight = fontMetrics.getHeight();
  89. // Add our graphics handler
  90. frame.add(new Graphics());
  91. // Add a window listener to the frame
  92. frame.addWindowListener(new WindowEvents());
  93. // Make this window visible
  94. frame.pack();
  95. frame.setVisible(true);
  96. // TODO: make this dynamic (FileChooser)
  97. map = new Map("maps/default.xml");
  98. // Start the game loop
  99. Game.loop();
  100. }
  101. // The bread and butter of Main, this is the games infinite loop.
  102. private static void loop()
  103. {
  104. String s;
  105. Graphics2D g;
  106. long delta, lastLoopTime = System.nanoTime();
  107. // Grab our strategy from GraphicsHandler
  108. BufferStrategy strategy = Graphics.getStrategy();
  109. // The main game loop
  110. while (running)
  111. {
  112. // The elapsed time between now and the last loop, for movement purposes
  113. delta = System.nanoTime() - lastLoopTime;
  114. lastLoopTime = System.nanoTime();
  115. // Grab the graphics context and buffer strategy from GraphicsHandler
  116. g = Graphics.getGraphics2D();
  117. // Blank graphics context for the accelerated graphics
  118. g.setColor(Color.black);
  119. g.fillRect(0, 0, WIDTH, HEIGHT);
  120. // Game state handler
  121. switch(state)
  122. {
  123. // The user is playing the game
  124. case PLAY:
  125. // Set clip for graphics context (drawable area)
  126. g.setClip(0, 0, WIDTH, HEIGHT);
  127. // Draw the Map image
  128. g.drawImage(Map.getMap(), 0, 0, null);
  129. // Draw grid if showGrid is enabled
  130. if (Map.showGrid()) g.drawImage(Map.getGrid(), 0, 0, null);
  131. //g.drawImage(Map.getTest(), 0, 0, null);
  132. // Process mouse events
  133. MouseEvents.processList();
  134. // What to draw if the game is paused
  135. if (paused)
  136. {
  137. // Display notification
  138. g.setColor(Color.white);
  139. s = "The game is paused.";
  140. g.drawString(s, 10, 20);
  141. }
  142. // What to draw if game is in waiting state
  143. else if (waiting)
  144. {
  145. // Display notification
  146. g.setColor(Color.white);
  147. s = "Press SPACEBAR to start the next round.";
  148. g.drawString(s, 10, 20);
  149. }
  150. // What to draw if the game is in debug mode
  151. if (debug)
  152. {
  153. // Update frameCount and elapsed time
  154. frameCount++;
  155. timeElapsed += delta;
  156. // If a second has passed...
  157. if (timeElapsed >= 1000000000)
  158. {
  159. // Set our new FPS
  160. framesPerSecond = frameCount;
  161. // Reset our variables
  162. frameCount = 0;
  163. timeElapsed = 0;
  164. }
  165. // Display FPS
  166. g.setColor(Color.white);
  167. s = "Frame Delay: " + frameDelay + " (FPS: " + framesPerSecond + ")";
  168. g.drawString(s, WIDTH - (fontMetrics.stringWidth(s)) - 10, 20);
  169. }
  170. // Update entity position, draw it, and update it's logic for the next loop
  171. for (Entity entity : entityList)
  172. {
  173. // Make sure the game isn't paused
  174. if (!paused && !waiting)
  175. {
  176. // If it's a logical entity, update it's logic
  177. if (entity.isLogical()) entity.doLogic();
  178. // If it's an animated entity, update it's animation
  179. if (entity instanceof AnimatedEntity) entity.update(delta);
  180. // If it's a moveable entity, update it's movement
  181. if (entity instanceof MovableEntity) entity.move(delta);
  182. }
  183. // Draw bounding box and path if in debug mode
  184. if (debug)
  185. {
  186. // Set this entity's color
  187. g.setColor(entity.getColor());
  188. // Draw this entity's bounding box
  189. g.fill(entity.getBounds());
  190. // Draw path
  191. g.drawImage(((MovableEntity) entity).getPath(), 0, 0, null);
  192. }
  193. // Add the entity to our graphics context
  194. entity.draw(g);
  195. }
  196. // Remove any entities that need to be removed here
  197. if (!removeList.isEmpty())
  198. {
  199. // Remove any entities that have been marked for deletion
  200. entityList.removeAll(removeList);
  201. // Clear the remove list
  202. removeList.clear();
  203. // Clear visible entity paths
  204. //if (isDebug()) Map.draw();
  205. }
  206. // Populate our entityList if it's empty
  207. if (entityList.isEmpty())
  208. {
  209. // The round has ended, wait for key press to start next round
  210. waiting = true;
  211. // Create the entities for the next round
  212. // TODO: make dynamic later, as well as their placement positions
  213. for (int i = 0; i < entityCount; i++)
  214. {
  215. entityList.add(
  216. new AlienEntity(
  217. new java.awt.Point(6 + i, 1),
  218. new java.awt.Point(6 + i, 20)
  219. )
  220. );
  221. }
  222. }
  223. break;
  224. // Main menu
  225. case MENU:
  226. g.setColor(Color.white);
  227. s = "Menu will be here soon. Press 'S' to start.";
  228. g.drawString(s, 10, 20);
  229. break;
  230. // About section
  231. case ABOUT:
  232. g.setColor(Color.white);
  233. s = "About: Game development by Kyle Florence.";
  234. g.drawString(s, 10, 20);
  235. break;
  236. // High scores section
  237. case SCORES:
  238. g.setColor(Color.white);
  239. s = "Someday, there will be high scores here.";
  240. g.drawString(s, 10, 20);
  241. break;
  242. // Game over, player has no more lives left
  243. case GAMEOVER:
  244. break;
  245. }
  246. // We are done drawing, clean up
  247. g.dispose();
  248. // Flip over our buffered strategy (page flipping)
  249. strategy.show();
  250. try {
  251. /*
  252. * Each frame is shown for 10 milliseconds. This is to give the
  253. * game some leeway in running through the loop process. That
  254. * way our animation stays smooth instead of getting choppy when
  255. * certain loops take longer than others. So, in order to know
  256. * how long we have left to wait we calculate the time of the last
  257. * loop plus 10 milliseconds, then subtract the time now and we
  258. * are left with our answer (a little buggy with large calculations).
  259. */
  260. frameDelay = ((lastLoopTime + (debug ? DEBUGDELAY : DELAY) * 1000000 - System.nanoTime()) / 1000000);
  261. // Sleep for specified time
  262. Thread.sleep(frameDelay);
  263. }
  264. // This loop took longer than 10 milliseconds
  265. catch (Exception e) { /* Do nothing */ }
  266. }
  267. }
  268. /**
  269. *
  270. * Public functions
  271. *
  272. */
  273. // Remove an entity from the game
  274. public static void removeEntity(Entity entity)
  275. {
  276. // Mark this entity for deletion
  277. removeList.add(entity);
  278. }
  279. // FOR DEBUG
  280. // Returns the number of the most recent entity in entityList
  281. public static int entityNumber() {
  282. return entityList.size() + 1;
  283. }
  284. // Returns the list of entities
  285. public static ArrayList<Entity> getEntities() {
  286. return entityList;
  287. }
  288. // Returns a reference to the Map class
  289. public static Map getMap() {
  290. return map;
  291. }
  292. // Return the state of the game
  293. public static int getState() {
  294. return state;
  295. }
  296. // Toggle waiting state
  297. public static void toggleWait() {
  298. waiting = !waiting;
  299. }
  300. // Toggle debug mode
  301. public static void toggleDebug() {
  302. debug = !debug;
  303. }
  304. // Toggle paused mode
  305. public static void togglePause() {
  306. paused = !paused;
  307. }
  308. // Toggle key lock
  309. public static void toggleLock() {
  310. locked = !locked;
  311. }
  312. // Whether or not the game is in the waiting state
  313. public static boolean isWaiting() {
  314. return waiting;
  315. }
  316. // Whether or not we are in debug mode
  317. public static boolean isDebug() {
  318. return debug;
  319. }
  320. // Whether or not the game is paused
  321. public static boolean isPaused() {
  322. return paused;
  323. }
  324. // Whether or not the keys are locked
  325. public static boolean isLocked() {
  326. return locked;
  327. }
  328. // Starts the game
  329. public static void start()
  330. {
  331. if (getState() != PLAY)
  332. {
  333. state = PLAY;
  334. paused = false;
  335. }
  336. }
  337. // This function is called when the JAR is opened
  338. public static void main(String[] args)
  339. {
  340. // Handle arguments here
  341. // ...
  342. Game.initialize();
  343. }
  344. // Not yet implemented
  345. //private void newGame() {}
  346. //private void removeEntity() {}
  347. //private void notifyLevelChange() {}
  348. //private void notifyGameOver() {}
  349. }