This commit is contained in:
theyatokami 2023-05-31 16:27:21 +02:00
parent bfe5e45af0
commit 441e3ef887
5 changed files with 159 additions and 105 deletions

View File

@ -1,12 +1,14 @@
import windowInterface.MyInterface;
import windowInterface.WelcomeScreen;
public class Main {
public static void main(String[] args) {
new WelcomeScreen().setVisible(true);
}
public static void main(String[] args) {
// Create a new instance of the WelcomeScreen class
WelcomeScreen welcomeScreen = new WelcomeScreen();
// Set the visibility of the welcome screen to true, making it visible on the screen
welcomeScreen.setVisible(true);
}
}

View File

@ -4,10 +4,10 @@ import java.awt.Color;
public class GameOfLifeSimulation {
private boolean[][] currentGeneration;
private int cellSize;
private int width;
private int height;
private boolean[][] currentGeneration; // Stores the current state of the cells
private int cellSize; // Size of each cell in pixels
private int width; // Width of the simulation area in pixels
private int height; // Height of the simulation area in pixels
public GameOfLifeSimulation(int cellSize, int width, int height) {
this.cellSize = cellSize;
@ -15,6 +15,7 @@ public class GameOfLifeSimulation {
this.height = height / cellSize;
currentGeneration = new boolean[this.width][this.height];
// Initializing the current generation randomly with a probability of 0.2 for each cell to be alive
for (int i = 0; i < this.width; i++) {
for (int j = 0; j < this.height; j++) {
currentGeneration[i][j] = Math.random() < 0.2;
@ -25,26 +26,32 @@ public class GameOfLifeSimulation {
public void update() {
boolean[][] newGeneration = new boolean[width][height];
// Updating each cell based on its neighbors
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int aliveNeighbours = 0;
// Counting the number of alive neighbors for each cell
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
int neighbourX = x + dx;
int neighbourY = y + dy;
// Skipping the current cell itself
if (dx == 0 && dy == 0) continue;
// Wrapping around the edges if a neighbor goes out of bounds
if (neighbourX < 0) neighbourX = width - 1;
if (neighbourY < 0) neighbourY = height - 1;
if (neighbourX >= width) neighbourX = 0;
if (neighbourY >= height) neighbourY = 0;
// Counting the alive neighbors
aliveNeighbours += currentGeneration[neighbourX][neighbourY] ? 1 : 0;
}
}
// Applying the rules of the Game of Life to update the cell's state in the new generation
if (currentGeneration[x][y]) {
newGeneration[x][y] = aliveNeighbours >= 2 && aliveNeighbours <= 3;
} else {
@ -53,13 +60,17 @@ public class GameOfLifeSimulation {
}
}
// Updating the current generation with the new generation
currentGeneration = newGeneration;
}
public void draw(Graphics g) {
// Drawing each cell on the graphics context
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
g.setColor(currentGeneration[x][y] ? Color.WHITE : Color.BLACK);
// Setting the color based on whether the cell is alive or dead
g.setColor(currentGeneration[x][y] ? Color.GRAY : Color.BLACK);
// Drawing a filled rectangle representing the cell
g.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
}
}

View File

@ -6,7 +6,7 @@ import java.io.*;
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import windowInterface.JPanelDraw;
public class Simulator extends Thread {
@ -18,7 +18,7 @@ public class Simulator extends Thread {
public boolean loopingBorder;
public int width;
public int height;
public boolean isGridInitialized;
public Simulator(MyInterface mjfParam) {
mjf = mjfParam;
@ -263,6 +263,7 @@ public class Simulator extends Thread {
}
world = new int[getWidth()][getHeight()];
mjf.reset();
isGridInitialized = false;
}
public void togglePause() {

View File

@ -1,93 +1,132 @@
package windowInterface;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import backend.Simulator;
public class JPanelDraw extends JPanel {
private static final long serialVersionUID = 1L;
private Simulator mySimu;
private MyInterface interfaceGlobal;
public JPanelDraw(MyInterface itf) {
super();
mySimu = null;
interfaceGlobal = itf;
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
if (mySimu == null) {
interfaceGlobal.instantiateSimu();
}
int x = (me.getX() * mySimu.getWidth()) / getWidth();
int y = (me.getY() * mySimu.getHeight()) / getHeight();
if (me.getButton() == MouseEvent.BUTTON1) {
mySimu.toggleCell(x, y);
} else if (me.getButton() == MouseEvent.BUTTON3) {
mySimu.setCell(x, y, 2); // Set cell as population2
}
repaint();
}
});
}
public void setSimu(Simulator simu) {
mySimu = simu;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.black);
if (mySimu != null) {
// Draw Interface from state of simulator
float cellWidth = (float) this.getWidth() / (float) mySimu.getWidth();
float cellHeight = (float) this.getHeight() / (float) mySimu.getHeight();
g.setColor(Color.gray);
for (int x = 0; x < mySimu.getWidth(); x++) {
int graphX = Math.round(x * cellWidth);
g.drawLine(graphX, 0, graphX, this.getHeight());
}
for (int y = 0; y < mySimu.getHeight(); y++) {
int graphY = Math.round(y * cellHeight);
g.drawLine(0, graphY, this.getWidth(), graphY);
}
for (int x = 0; x < mySimu.getWidth(); x++) {
for (int y = 0; y < mySimu.getHeight(); y++) {
int cellContent = mySimu.getCell(x, y);
if (cellContent == 0) {
continue;
}
if (interfaceGlobal.getGameMode() == 0) { // Two Populations mode
g.setColor(Color.WHITE);
} else if (interfaceGlobal.getGameMode() == 1) {
if (cellContent == 1) {
g.setColor(Color.RED);
} else if (cellContent == 2) {
g.setColor(Color.BLUE);
} else if (cellContent == 3) {
g.setColor(Color.yellow);
} else if (cellContent == 4) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.GRAY);
}
} else {
g.setColor(Color.WHITE);
}
g.fillRect((int) Math.round(x * cellWidth), (int) Math.round(y * cellHeight),
(int) Math.round(cellWidth), (int) Math.round(cellHeight));
}
}
}
}
}
package windowInterface;
// necessary imports for GUI, events, and the backend of the game/simulation
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import backend.Simulator;
import java.awt.Font;
import java.awt.FontMetrics;
// custom JPanel for drawing the game/simulation interface
public class JPanelDraw extends JPanel {
// serialization ID
private static final long serialVersionUID = 1L;
// instance of the game/simulation
private Simulator mySimu;
// interface used for controlling the simulation
private MyInterface interfaceGlobal;
// variable to check if the grid has been initialized
public boolean isGridInitialized = false;
// constructor
public JPanelDraw(MyInterface itf) {
super();
mySimu = null;
interfaceGlobal = itf;
// Add a mouse listener to respond to clicks
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
// If the simulator is not yet created, create it
if (mySimu == null) {
interfaceGlobal.instantiateSimu();
}
// translate click coordinates to grid coordinates
int x = (me.getX() * mySimu.getWidth()) / getWidth();
int y = (me.getY() * mySimu.getHeight()) / getHeight();
// handle different mouse button clicks
if (me.getButton() == MouseEvent.BUTTON1) {
mySimu.toggleCell(x, y); // Toggle cell
} else if (me.getButton() == MouseEvent.BUTTON3) {
mySimu.setCell(x, y, 2); // Set cell as population2
}
// set the grid as initialized
isGridInitialized = true;
// repaint the panel after a click
repaint();
}
});
}
// method for setting the simulator
public void setSimu(Simulator simu) {
mySimu = simu;
}
// paintComponent method where the actual drawing happens
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Set the background color of the grid
this.setBackground(Color.black);
if (mySimu != null) {
// Get the size of each cell
float cellWidth = (float) this.getWidth() / (float) mySimu.getWidth();
float cellHeight = (float) this.getHeight() / (float) mySimu.getHeight();
// Draw the grid lines
g.setColor(Color.gray);
for (int x = 0; x < mySimu.getWidth(); x++) {
int graphX = Math.round(x * cellWidth);
g.drawLine(graphX, 0, graphX, this.getHeight());
}
for (int y = 0; y < mySimu.getHeight(); y++) {
int graphY = Math.round(y * cellHeight);
g.drawLine(0, graphY, this.getWidth(), graphY);
}
// Loop through all cells to paint them according to their status
for (int x = 0; x < mySimu.getWidth(); x++) {
for (int y = 0; y < mySimu.getHeight(); y++) {
int cellContent = mySimu.getCell(x, y);
if (cellContent == 0) {
continue; // If cell is empty, do not paint it
}
// Check game mode and set color accordingly
if (interfaceGlobal.getGameMode() == 0) { // Two Populations mode
g.setColor(Color.WHITE);
} else if (interfaceGlobal.getGameMode() == 1) {
// Depending on the cell's state, set a different color
if (cellContent == 1) {
g.setColor(Color.RED);
} else if (cellContent == 2) {
g.setColor(Color.BLUE);
} else if (cellContent == 3) {
g.setColor(Color.yellow);
} else if (cellContent == 4) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.GRAY);
}
} else {
g.setColor(Color.WHITE);
}
// Fill the cell with the color
g.fillRect((int) Math.round(x * cellWidth), (int) Math.round(y * cellHeight),
(int) Math.round(cellWidth), (int) Math.round(cellHeight));
}
}
}
// If the grid is not yet initialized, show a message
if (!isGridInitialized) {
g.setColor(Color.RED);
g.setFont(new Font("Monospaced", Font.BOLD, 30));
FontMetrics metrics = g.getFontMetrics();
String message = "Click to play";
// Center the message
int x = (getWidth() - metrics.stringWidth(message)) / 2;
int y = ((getHeight() - metrics.getHeight()) / 2) + metrics.getAscent();
g.drawString(message, x, y);
}
}
}

View File

@ -53,6 +53,7 @@ public class MyInterface extends JFrame {
private JSlider randSlider;
private JSlider speedSlider;
private int gameMode = 0;
public boolean isGridInitialized = false;