A simple Game of Life implementation in Java
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.6 KiB

  1. package edu.stuy.goldfish;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import java.awt.image.*;
  5. import javax.swing.*;
  6. public class Render extends Canvas implements Runnable, MouseListener,
  7. MouseMotionListener, ActionListener, ItemListener {
  8. private static final long serialVersionUID = 1L;
  9. public static String title = "Goldfish";
  10. public static int width;
  11. public static int height;
  12. public static int scale;
  13. public static int max_fps = 15;
  14. public boolean paused;
  15. public String rule;
  16. private Grid _grid;
  17. private BufferedImage _image;
  18. private int[] _pixels;
  19. private long _lastTick;
  20. private String[] _rules;
  21. private JFrame _frame;
  22. public Render(int width, int height, Grid g, String[] rules) {
  23. addMouseListener(this);
  24. addMouseMotionListener(this);
  25. Render.width = width;
  26. Render.height = height;
  27. setScale();
  28. paused = false;
  29. rule = rules[0];
  30. _grid = g;
  31. _image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  32. _pixels = ((DataBufferInt) _image.getRaster().getDataBuffer()).getData();
  33. _lastTick = 0;
  34. _rules = rules;
  35. Dimension size = new Dimension(width * scale, height * scale);
  36. setPreferredSize(size);
  37. setFrame();
  38. }
  39. public Render(int width, int height, Grid g) {
  40. this(width, height, g, new String[0]);
  41. }
  42. public Render(int width, int height) {
  43. this(width, height, new Grid(width, height));
  44. }
  45. public Render() {
  46. this(256, 256);
  47. }
  48. private void setScale() {
  49. if (height <= 128 || width <= 128) {
  50. Render.scale = 4;
  51. } else if (height <= 256 || width <= 256) {
  52. Render.scale = 2;
  53. } else {
  54. Render.scale = 1;
  55. }
  56. }
  57. private void setFrame() {
  58. JMenuBar menuBar = new JMenuBar();
  59. JMenu menuMain = new JMenu("Menu");
  60. JMenu menuAlgo = new JMenu("Algorithms");
  61. for (String rule : _rules) {
  62. JMenuItem menuAlgoItem = new JMenuItem(rule);
  63. menuAlgo.add(menuAlgoItem);
  64. menuAlgoItem.addActionListener(this);
  65. }
  66. menuMain.add(menuAlgo);
  67. menuBar.add(menuMain);
  68. JCheckBoxMenuItem pauseButton = new JCheckBoxMenuItem("Pause");
  69. menuBar.add(pauseButton);
  70. pauseButton.addItemListener(this);
  71. _frame = new JFrame();
  72. _frame.setJMenuBar(menuBar);
  73. _frame.setResizable(false);
  74. _frame.setTitle(title);
  75. _frame.add(this);
  76. _frame.pack();
  77. _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  78. _frame.setLocationRelativeTo(null);
  79. _frame.setVisible(true);
  80. }
  81. private void update() {
  82. int state;
  83. int states = Goldfish.getMaxStates(rule);
  84. for (int i = 0; i < width; i++) {
  85. for (int j = 0; j < height; j++) {
  86. state = _grid.getPatch(i, j).getState();
  87. if(_pixels[i + j * width] == state) {
  88. } else {
  89. draw(i, j, (int) ((state/((double) states - 1)) * 0xffffff));
  90. }
  91. }
  92. }
  93. }
  94. public void run() {
  95. BufferStrategy bs;
  96. Graphics g;
  97. bs = getBufferStrategy();
  98. if (bs == null) {
  99. createBufferStrategy(1);
  100. return;
  101. }
  102. update();
  103. g = bs.getDrawGraphics();
  104. g.drawImage(_image, 0, 0, getWidth(), getHeight(), null);
  105. g.dispose();
  106. bs.show();
  107. }
  108. public void sleep() {
  109. long since = System.currentTimeMillis() - _lastTick;
  110. if (since < 1000 / max_fps) {
  111. try {
  112. Thread.sleep(1000 / max_fps - since);
  113. } catch (InterruptedException e) {
  114. return;
  115. }
  116. }
  117. _lastTick = System.currentTimeMillis();
  118. }
  119. public void setGrid(Grid g) {
  120. _grid = g;
  121. }
  122. public void draw(int x, int y, int color) {
  123. _pixels[x + y * width] = color;
  124. }
  125. @Override
  126. public void mouseDragged(MouseEvent e) {
  127. int states = Goldfish.getMaxStates(rule) - 1;
  128. if (e.getX() < 0 || e.getY() < 0 || e.getX() / scale > width || e.getY() / scale > height)
  129. return;
  130. _grid.getPatch(e.getX() / scale, e.getY() / scale).setState(states);
  131. e.consume();
  132. }
  133. @Override
  134. public void mouseClicked(MouseEvent e) {
  135. int states = Goldfish.getMaxStates(rule) - 1;
  136. _grid.getPatch(e.getX() / scale, e.getY() / scale).setState(states);
  137. e.consume();
  138. }
  139. @Override
  140. public void mouseEntered(MouseEvent e) {
  141. }
  142. @Override
  143. public void mouseExited(MouseEvent e) {
  144. }
  145. @Override
  146. public void mousePressed(MouseEvent e) {
  147. int states = Goldfish.getMaxStates(rule) - 1;
  148. _grid.getPatch(e.getX() / scale, e.getY() / scale).setState(states);
  149. e.consume();
  150. }
  151. @Override
  152. public void mouseReleased(MouseEvent e) {
  153. }
  154. @Override
  155. public void mouseMoved(MouseEvent e) {
  156. }
  157. // Affects the algorithms menu
  158. @Override
  159. public void actionPerformed(ActionEvent event) {
  160. rule = event.getActionCommand();
  161. }
  162. // Affects the pause button
  163. @Override
  164. public void itemStateChanged(ItemEvent event) {
  165. if (event.getStateChange() == ItemEvent.SELECTED)
  166. paused = true;
  167. else
  168. paused = false;
  169. return;
  170. }
  171. }