////////////////////////////////////////////////////////////////////////////
//
// Another One of Those Minimalistic Games
// An Interactive Toy by Keana Almario
//
// Inspired by Marty Daniels' Paddle Game (2014 Interactive Toy),
// I decided to make a minimalistic game so I could get myself to
// think about mechanics instead of focusing only on the aesthetics.
//
// WASD or Arrow Keys to move.
//
////////////////////////////////////////////////////////////////////////////
//Declare color-related variables
float bgR = 10;
float bgG = 10;
float bgB = 10;
int colorCount = 0;
//Declare square-related variables (player)
float sqX;
float sqY;
float sqSize = 20;
float sqDirX = 0;
float sqDirY = 0;
float sqSpeed = 8;
//Declare wall-related variables
float wallX1;
float wallX2;
float wallYA;
float wallYB;
float wallInitialY;
float wallLengthA1;
float wallLengthA2;
float wallLengthB1;
float wallLengthB2;
float wallWidth = 35;
float wallInitialSpeed = 2.5;
float wallSpeed = wallInitialSpeed;
float wallSpeedChange = 0.2;
// Declare losing line and score-related variables
float lineX;
float lineY;
int score = 0;
////////////////////////////////////////////////////////////////////////////
void setup() {
// Set screen size
size(400, 600);
// Set all shapes to no stroke
noStroke();
// Set rect mode to CENTER for convenience
rectMode(CENTER);
// Set initial position of square
sqX = width/2;
sqY = height/2;
// Set initial positions of walls
// Only two sets of walls will be on the screen at any one time (except for the start)
wallInitialY = 0 - wallWidth;
wallYA = wallInitialY;
wallYB = wallYA - (height/2);
wallX1 = 0;
wallX2 = width;
// Set randomly-generated gaps for wall sets
// Each set of wall will have two walls (left and right)
// The gaps will appear in random parts of the set but will always be the same size
wallLengthA1 = random(width/32, width-(width/4)) * 1.8;
wallLengthA2 = abs(width*1.5 - wallLengthA1);
wallLengthB1 = random(width/32, width-(width/4)) * 1.8;
wallLengthB2 = abs(width*1.5 - wallLengthB1);
// Set position of the losing line
lineX = width/2;
lineY = height - (height/60);
}
void draw() {
// Draw the background color
background(bgR, bgG, bgB);
// Move wall sets and squares
updateWall();
updateSq();
// Reposition square so it stays inside screen and outside walls
collideSqOnWall(wallX1, wallYA, wallLengthA1);
collideSqOnWall(wallX2, wallYA, wallLengthA2);
collideSqOnWall(wallX1, wallYB, wallLengthB1);
collideSqOnWall(wallX2, wallYB, wallLengthB2);
constrainSqToBounds();
// Check if the square has passed a wall set, triggering the background color change
checkIfSqPassedWall(wallYA);
checkIfSqPassedWall(wallYB);
// Check if the square has touched the losing line, triggering the YOU LOSE screen
checkIfSqLost();
// Check if the wall set has exited the screen, repositioning it above the screen so it enters again
checkIfWallExited();
// Draw losing line, score bar, walls, and square
drawLosingLine();
drawScore();
drawWall(wallX1, wallYA, wallLengthA1);
drawWall(wallX2, wallYA, wallLengthA2);
drawWall(wallX1, wallYB, wallLengthB1);
drawWall(wallX2, wallYB, wallLengthB2);
drawSq();
}
////////////////////////////////////////////////////////////////////////////
// Move walls
void updateWall() {
wallYA += wallSpeed;
wallYB += wallSpeed;
}
// Draw walls
void drawWall(float wallX, float wallY, float wallLength) {
fill(255, 50);
rect(wallX, wallY, wallLength, wallWidth);
}
// Check if the wall set has exited the screen, repositioning it above the screen so it enters again
void checkIfWallExited() {
if (wallYA - (wallWidth*0.5) > height) {
wallYA = 0 - wallWidth;
wallLengthA1 = random(width/32, width-(width/4)) * 2;
wallLengthA2 = abs(width*1.5 - wallLengthA1);
}
if (wallYB - (wallWidth*0.5) > height) {
wallYB = 0 - wallWidth;
wallLengthB1 = random(width/32, width-(width/4)) * 2;
wallLengthB2 = abs(width*1.5 - wallLengthB1);
}
}
//////////////////////////////////////
//Move square
void updateSq() {
// The new x/y position is a constant speed * a direction
// To move the square, change direction to -1 (when x/y decreases) or 1 (when x/y increases)
// To stop the square, change direction to 0
sqX += sqSpeed * sqDirX;
sqY += sqSpeed * sqDirY;
}
// Draw square
void drawSq() {
fill(255);
rect(sqX, sqY, sqSize, sqSize);
}
// Detemine the walls' collision area and reposition the square outside them
void collideSqOnWall(float wallX, float wallY, float wallLength) {
// Collision of square with top/bottom side of the wall
if (sqY - (sqSize*0.5) < wallY + (wallWidth*0.5) && sqY + (sqSize*0.5) > wallY - (wallWidth*0.5) && sqX - (sqSize*0.5) > wallX - (wallLength*0.50) && sqX + (sqSize*0.5) < wallX + (wallLength*0.50)) {
// Stop the square
sqDirY = 0;
// Determine new location of square depending on whether it is below or above the wall
if (sqY > wallY) {
sqY = wallY + (wallWidth*0.75);
} else if (sqY < wallY) {
sqY = wallY - (wallWidth*0.75);
}
}
// Collision of square with left/right side of the wall
if (sqX + (sqSize*0.5) > wallX - (wallLength*0.50) && sqX - (sqSize*0.5) < wallX + (wallLength*0.50) && sqY - (sqSize*0.5) > wallY - (wallWidth*0.5) && sqY + (sqSize*0.5) < wallY + (wallWidth*0.5)) {
// Stop the square
sqDirX = 0;
// Determine new location of square depending on whether it is left or right of the wall
if (sqX < wallX) {
sqX = wallX - (wallLength*0.55);
} else if (sqX > wallX) {
sqX = wallX + (wallLength*0.55);
}
}
}
// Keep square inside screen
void constrainSqToBounds() {
// Square does not go past the top/bottom bounds of screen
if (sqY - (sqSize*0.5) < 0) {
sqDirY = 0;
sqY = 0 + (sqSize*0.5);
} else if (sqY + (sqSize*0.5) > height) {
sqDirY = 0;
sqY = height - (sqSize*0.5);
}
// Square does not go past the left/right bounds of screen
if (sqX - (sqSize*0.5) < 0) {
sqDirX = 0;
sqX = 0 + (sqSize*0.5);
} else if (sqX + (sqSize*0.5) > width) {
sqDirX = 0;
sqX = width - (sqSize*0.5);
}
}
// Check if the square has passed a wall set
void checkIfSqPassedWall(float wallY_) {
if (sqY == wallY_ || (sqY <= wallY_ && sqY >= wallY_ - (wallWidth*0.3))) {
// Increase wall speed
wallSpeed += wallSpeedChange;
// Increase score
score++;
// Trigger the background color change
colorCount++;
changeColor();
}
}
// Check if the square has touched the losing line
void checkIfSqLost() {
if (sqY + (sqSize*0.5) > lineY) {
// Trigger YOU LOSE screen
drawYouLose();
// Reset background color
bgR = 10;
bgG = 10;
bgB = 10;
colorCount = 0;
// Reset score
score = 0;
// Reset wall speed
wallSpeed = wallInitialSpeed;
}
}
// Draw losing line
void drawLosingLine() {
fill(0, 50);
rect(lineX, lineY, width, (height-lineY) * 2);
// Draw the diagonal line pattern in the losing line
fill(255, 30);
for (int i = 0; i <= width; i += 50) {
quad(i, height, i+(width/13), height-(height/30), i+(width/8), height-(height/30), i+(width/20), height);
}
}
// Draw YOU LOSE screen
void drawYouLose() {
fill(255, 100);
// Set rect mode to CORNERS for convenience
rectMode(CORNERS);
//Y
rect(35, 110, 45, 140);
rect(45, 140, 65, 150);
rect(65, 110, 75, 160);
rect(45, 160, 65, 170);
//O
rect(95, 110, 115, 120);
rect(95, 160, 115, 170);
rect(85, 120, 95, 160);
rect(115, 120, 125, 160);
//U
rect(135, 110, 145, 160);
rect(165, 110, 175, 160);
rect(145, 160, 165, 170);
//L
rect(205, 110, 215, 160);
rect(205, 160, 235, 170);
//O
rect(255, 110, 275, 120);
rect(255, 160, 275, 170);
rect(245, 120, 255, 160);
rect(275, 120, 285, 160);
//S
rect(305, 110, 325, 120);
rect(295, 120, 305, 130);
rect(305, 130, 315, 140);
rect(315, 140, 325, 160);
rect(295, 160, 315, 170);
//E
rect(335, 110, 345, 170);
rect(345, 110, 365, 120);
rect(345, 130, 355, 140);
rect(345, 160, 365, 170);
// Set rect mode back to CENTER
rectMode(CENTER);
}
// Draw score bar
void drawScore() {
fill(255, 30);
rect(width/2, height/10, (score*5) + width/40, width/40);
}
// Change background color when square passes a wall set
void changeColor() {
if (colorCount == 0) {
bgR = 10;
bgG = 10;
bgB = 10;
}
if (colorCount > 0 && colorCount <= 5) {
bgR = 10;
bgG = 10;
bgB = random(40, 90);
}
if (colorCount > 5 && colorCount <= 10) {
bgR = 10;
bgG = random(40, 90);
bgB = random(40, 90);
}
if (colorCount > 10 && colorCount <= 15) {
bgR = 10;
bgG = random(40, 90);
bgB = 10;
}
if (colorCount > 15 && colorCount <= 20) {
bgR = random(40, 90);
bgG = random(40, 90);
bgB = 10;
}
if (colorCount > 20 && colorCount <= 25) {
bgR = random(40, 90);
bgG = 10;
bgB = 10;
}
if (colorCount > 25 && colorCount <= 30) {
bgR = random(40, 90);
bgG = 10;
bgB = random(40, 90);
// Reset color count to start of cycle
colorCount = 0;
}
}
// Set controls
void keyPressed() {
// Get the square moving when WASD/arrow keys are pressed
if (key == 'w' || key == 'W' || keyCode == UP) {
sqDirY = -1;
}
if (key == 's' || key == 'S' || keyCode == DOWN) {
sqDirY = 1;
}
if (key == 'a' || key == 'A' || keyCode == LEFT) {
sqDirX = -1;
}
if (key == 'd' || key == 'D' || keyCode == RIGHT) {
sqDirX = 1;
}
}
void keyReleased() {
// Stop the square from moving when the key pressed is released
if (key == 'w' || key == 'W' || keyCode == UP) {
sqDirY = 0;
} else if (key == 's' || key == 'S' || keyCode == DOWN) {
sqDirY = 0;
} else if (key == 'a' || key == 'A' || keyCode == LEFT) {
sqDirX = 0;
} else if (key == 'd' || key == 'D' || keyCode == RIGHT) {
sqDirX = 0;
}
}