xxxxxxxxxx
242
let snake;
let fruit;
let GRID_SIZE = 20; // Size of each grid cell
let gameActive;
let WIDTH = 600; // Width of the canvas
let HEIGHT = 600; // Height of the canvas
let gameState; // Variable to track game state ('start', 'playing', 'gameOver')
let showDorm = false; // Flag to track whether to show the dorm room or not
let showCompHighlight = false;
let showMenu = false; // Flag to track if the computer menu should be shown
let computerFont, mainFont, numFont, compHighlight, img;
let currentView = 'menu'; // Tracks the current view (menu, snake)
// p5.js setup function: Initializes the game
function setup() {
createCanvas(WIDTH, HEIGHT); // Creates the canvas
frameRate(6); // Sets the frame rate to 6 frames per second (slow speed)
gameState = 'start'; // Set the initial state to 'start'
snake = new Snake(GRID_SIZE); // Initializes the snake object
fruit = new Fruit(WIDTH, HEIGHT, GRID_SIZE); // Initializes the fruit object
gameActive = true; // Sets the game to active
loadAssets(); // Load assets for dorm and menu
}
// Function to load assets for dorm and menu views
function loadAssets() {
img = loadImage('dormroomp.jpg'); // Load the dorm room image
compHighlight = loadImage('comphighlight.jpg'); // Load the computer highlight image
mainFont = loadFont('MisterGrape.otf');
numFont = loadFont("crashingNumber.ttf");
computerFont = loadFont("computerFont.otf");
}
// p5.js draw function: Runs every frame, continuously updates the game
function draw() {
background(0); // Clear the background
if (currentView === 'menu') {
drawMenu(); // Show computer menu
} else if (currentView === 'snake') {
drawSnakeGame(); // Run the Snake game
}
}
// Function to display the computer menu
function drawMenu() {
background(50); // Menu background color
textFont(computerFont);
textSize(50);
fill(255);
textAlign(CENTER);
text("Computer Menu", WIDTH / 2, 100);
textSize(30);
text("Press 1: Open Drum Machine", WIDTH / 2, 200);
text("Press 2: Play Snake", WIDTH / 2, 300);
text("Press ESC to go back", WIDTH / 2, 400);
}
// Function to handle Snake game display and logic
function drawSnakeGame() {
if (gameState === 'start') {
// Display start screen
fill(255);
textAlign(CENTER);
textSize(72);
text("Snake Game", WIDTH / 2, HEIGHT / 4); // Game title
textSize(36);
text("Press ENTER to Start", WIDTH / 2, HEIGHT / 2); // Instructions to start
}
else if (gameState === 'playing') {
if (gameActive) {
snake.update(); // Update the snake's position
snake.draw(); // Draw the snake
// Check if the snake eats the fruit
if (snake.x === fruit.x && snake.y === fruit.y) {
snake.grow(); // Make the snake grow
fruit.move(); // Move the fruit to a new position
}
fruit.draw(); // Draw the fruit
// Check if the game is over
if (gameOver()) {
gameState = 'gameOver'; // If game over, change state
}
}
}
else if (gameState === 'gameOver') {
// Display "Game Over" screen
fill(255);
textAlign(CENTER);
textSize(72);
text("Game Over", WIDTH / 2, HEIGHT / 4); // Display "Game Over" text
textSize(60);
text(snake.body.length + 1, WIDTH / 2, HEIGHT / 2); // Display the snake's length as score
textSize(36);
text("Press ENTER to Play Again", WIDTH / 2, HEIGHT * 0.75); // Instructions to replay
}
}
// p5.js keyPressed function: Handles key presses to control the game state
function keyPressed() {
if (currentView === 'menu') {
if (key === '2') {
currentView = 'snake'; // Switch to the Snake game when '2' is pressed
gameState='start'
}
}
if (currentView === 'snake') {
if (gameState === 'start' && keyCode === ENTER) {
// Start the Snake game when ENTER is pressed
resetGame();
gameState = 'playing';
}
if (gameState === 'gameOver' && keyCode === ENTER) {
// Replay the Snake game when ENTER is pressed on the game over screen
resetGame();
gameState = 'playing';
}
if (gameState === 'playing') {
snake.action(key); // Pass the key to the snake's action method
}
if (keyCode === ESCAPE) {
currentView = 'menu'; // Go back to the menu when ESC is pressed
}
}
}
// Function to check if the game is over
function gameOver() {
// Check if the snake goes out of bounds
if (snake.x < 0 || snake.x >= WIDTH || snake.y < 0 || snake.y >= HEIGHT) {
return true;
}
// Check if the snake runs into its own body
for (let i = 0; i < snake.body.length; i++) {
if (snake.x === snake.body[i][0] && snake.y === snake.body[i][1]) {
return true;
}
}
return false;
}
// Function to reset the Snake game
function resetGame() {
snake = new Snake(GRID_SIZE); // Reset the snake object
fruit = new Fruit(WIDTH, HEIGHT, GRID_SIZE); // Reset the fruit object
gameActive = true; // Reactivate the game
}
// Snake class to represent the snake in the game
class Snake {
constructor(size) {
this.x = 3 * size; // Initial x position of the snake
this.y = 3 * size; // Initial y position of the snake
this.vx = 1; // Horizontal velocity (moving right by default)
this.vy = 0; // Vertical velocity (not moving vertically by default)
this.size = size; // Size of each segment of the snake
// Initialize the body of the snake as an array of coordinates
this.body = [
[this.x - size, this.y], // First body segment
[this.x - size * 2, this.y] // Second body segment
];
}
// Method to handle the snake's direction based on key input
action(key) {
// Up key (w) - only change direction if not currently moving down
if (key === 'w' && this.vy !== 1) {
this.vx = 0;
this.vy = -1;
}
// Left key (a) - only change direction if not currently moving right
if (key === 'a' && this.vx !== 1) {
this.vx = -1;
this.vy = 0;
}
// Down key (s) - only change direction if not currently moving up
if (key === 's' && this.vy !== -1) {
this.vx = 0;
this.vy = 1;
}
// Right key (d) - only change direction if not currently moving left
if (key === 'd' && this.vx !== -1) {
this.vx = 1;
this.vy = 0;
}
}
// Method to update the snake's position
update() {
this.body.shift(); // Remove the last segment of the body
this.body.push([this.x, this.y]); // Add the current head position to the body
this.x += this.vx * this.size; // Update the x position based on velocity
this.y += this.vy * this.size; // Update the y position based on velocity
}
// Method to grow the snake by adding a new segment
grow() {
this.body.unshift(this.body[0]); // Add a new segment at the head's position
}
// Method to draw the snake on the canvas
draw() {
fill(255); // Set the snake color to white
rect(this.x, this.y, this.size, this.size); // Draw the snake's head
// Draw each body segment
for (let i = 0; i < this.body.length; i++) {
rect(this.body[i][0], this.body[i][1], this.size, this.size);
}
}
}
// Fruit class to represent the fruit in the game
class Fruit {
constructor(width, height, size) {
this.width = width; // Width of the canvas
this.height = height; // Height of the canvas
this.size = size; // Size of the fruit (matches snake's size)
this.move(); // Set the initial position of the fruit
}
// Method to move the fruit to a random position on the grid
move() {
this.x = floor(random(0, this.width - this.size) / this.size) * this.size;
this.y = floor(random(0, this.height - this.size) / this.size) * this.size;
}
// Method to draw the fruit on the canvas
draw() {
fill(200, 0, 0); // Set the fruit color to red
rect(this.x, this.y, this.size, this.size); // Draw the fruit
}
}