Maze Game
Idea:
The idea for my game is to have a player cross a maze in which they will have to avoid a number of enemies. The player will have a limit visibility of the maze (delimited by a circle around the player character). The player will be able, however, to see the position of the enemies (at least that is the idea). It is kind of a PacMan inspired game but with a twist, you could say.
Here is a rough sketch of how the game will look (kind of):
I also very recently came up with the idea to set a theme for the game (I am creating my own sprites so I needed inspiration). Up until now, I have settled for a Harry Potter theme (I have a friend who is obsessed with Harry Potter) because I found these sprites on internet while I was looking for examples and they reminded me of it.
These are the sprites:
The following made me think about the dementors in the series.
Progress:
For this week I decided to focus on creating the maze (more specifically, been able to generate random mazes) and on going through the PGraphics library. I went through the documentation some online tutorials to better understand how to use it.
Note: the fact that I wrote that I decided to focus on these things means that I actually took a long time to understand PGraphics and even more on creating the code to generate the maze.
To create the maze, I decided to create a grid with cells. The program starts at the upper left cell. It checks for neighboring cells and selects a non-visited cell (one the program has not gone through) and removes a wall (line of the grid). Then it moves to that cell and checks for neighbor cells: the process repeats until a path has been formed. Then the program fills in the left out non-visited cells and randomly removes a wall from them to make them look like a maze. The program is recursive so the last position will be that at the beginning of the maze.
The following is a description of my thought process along with the written algorithm (taken from Wikipedia , there are a lot of options to choose from there).
I had a lot of problems writing the code.
At the beginning it was ok. I manage to create a grid and to be able to place in a different color the visited cell.
The problem came when we started to check the neighboring cells. The problem was the edges: sometimes the program will run well and would move to the neighbor cell, however, when the current cell was an edge, sometimes it choose a neighboring cell outside the canvas, so I had to write a case for that.
This is how it would look:
It was also quite hard to figure out how to assign the cells to certain variable (there was a lot of sketching and thinking involved behind that and it took a lot of time to figure out just how to show and remove the walls).
In many cases, what generate was something that did kind of look like a maze but that had no solution.
The problems where almost always associated with logic with what wall I was telling the program to remove. I watched some YouTube videos regarding maze generation to see how they removed the walls (all of them were in other programming languages, but the pseudocode was all I really needed to start fixing this mess).
After much struggling, yesterday I was finally able to generate a maze.
However in the morning, something happened (I think I might have erased something by accident). My code wasn’t working anymore.
After smashing my head against the wall all morning on my birthday because I couldn’t figure what was wrong, Professor Aaron illuminated me by asking with which function the cell was moving. I had accidentally erased the part in which the cell moved to the next to create a new path, and I completely missed it. Perhaps I’ve been staring at this code for so long that my mind was just assuming that it was there, because I swear, the fact that that part of the code was missing just completely went over my head.
I know have a code that works, 7amdullah!
This is the final result (also, yes, I keep switching colors and size because I wasn’t sure about which would look good, but now I decided for the theme of Harry Potter, I settled for this yellow color. Hopefully I won’t change it again).
Code:
Main Tab
int cols, rows;
int cellSize = 50;
ArrayList<Cell> grid = new ArrayList<Cell>();
Cell currentCell;
ArrayList<Cell> stack = new ArrayList<Cell>();
void setup()
{
size(900, 900);
//fullScreen();
cols = floor(width/cellSize);
rows = floor(height/cellSize);
//create Cell objects and add them to array list
for (int j = 0; j < rows; j++)
{
for (int i = 0; i < cols; i++)
{
Cell newCell = new Cell(i, j);
grid.add(newCell);
}
}
//start the path at grid 0
currentCell = grid.get(0);
}
void draw()
{
background(51);
//check that the grid displays correctly
for (int i = 0; i < grid.size(); i++)
{
//I made the mistake of writing grid.length() instead of grid.size()
grid.get(i).show();
}
currentCell.visited = true;
currentCell.highlight();
//currentCell.checkAdjacentCells();
// STEP 1
Cell nextCell = currentCell.checkAdjacentCells();
if (nextCell != null)
{
nextCell.visited = true;
// STEP 2
stack.add(currentCell);
//STEP 3: remove the walls
removeWalls(currentCell, nextCell);
// STEP 4
currentCell = nextCell;
}
//this is what corrected the problem with the null value
else if (stack.size() > 0)
{
currentCell = stack.remove(stack.size()-1);
}
}
void removeWalls(Cell current, Cell next)
{
int x = current.i - next.i;
if (x == 1)
{
//remove left wall
current.walls[3] = false;
//remove right wall
next.walls[1] = false;
} else if (x == -1)
{
//remove left wall
current.walls[1] = false;
//remove right wall
next.walls[3] = false;
}
int y = current.j - next.j;
if (y == 1)
{
//remove bottom wall
current.walls[0] = false;
//remove top wall
next.walls[2] = false;
} else if (y == -1)
{
//remove top wall
current.walls[2] = false;
//remove bottom wall
next.walls[0] = false;
}
}
Cell Object
class Cell {
int i, j;
//order of the walls is top, right, bottom, left
//this will allow us to remove walls in the grid
boolean[] walls = {true, true, true, true};
boolean visited = false;
Cell(int indexI, int indexJ) {
i = indexI;
j = indexJ;
}
int index(int i, int j)
{
//return 0 for edge cases
if (i < 0 || j < 0 || i > cols-1 || j > rows-1)
{
return 0;
}
//formula to calculate index (same as the one to calculate pixels)
int index = i + j * cols;
return index;
}
Cell checkAdjacentCells() {
ArrayList<Cell> adjacentCells = new ArrayList<Cell>();
//get the cells adjacent to the cell the program is currently at
Cell top = grid.get(index(i, j-1));
Cell right = grid.get(index(i+1, j));
Cell bottom = grid.get(index(i, j+1));
Cell left = grid.get(index(i-1, j));
if (top != null && !top.visited) {
adjacentCells.add(top);
}
if (right != null && !right.visited) {
adjacentCells.add(right);
}
if (bottom != null && !bottom.visited) {
adjacentCells.add(bottom);
}
if (left != null && !left.visited) {
adjacentCells.add(left);
}
if (adjacentCells.size() > 0) {
int r = floor(random(0, adjacentCells.size()));
return adjacentCells.get(r);
} else
{
return null;
}
}
void highlight() {
int x = i*cellSize;
int y = j*cellSize;
noStroke();
fill(0, 255, 0);
rect(x, y, cellSize, cellSize);
}
void show() {
int x = i*cellSize;
int y = j*cellSize;
stroke(255);
//if the walls are defined
if (walls[0])
{
line(x, y, x + cellSize, y);
}
if (walls[1])
{
line(x + cellSize, y, x + cellSize, y + cellSize);
}
if (walls[2])
{
line(x + cellSize, y + cellSize, x, y + cellSize);
}
if (walls[3])
{
line(x, y + cellSize, x, y);
}
//line(x , y , x + cellSize, y);
//line(x + cellSize, y , x + cellSize, y + cellSize);
//line(x + cellSize, y + cellSize, x , y + cellSize);
//line(x , y , x+ cellSize , y);
//noFill();
//rect(x, y, cellSize, cellSize);
//change color of a cell if it has been visited
if (visited)
{
noStroke();
fill(255, 204, 102, 150);
rect(x, y, cellSize, cellSize);
}
}
}









