xxxxxxxxxx
500
let widthPlayer, heightPlayer;
// ================ Game States ================
let gameState = 'play tutorial';
let gameOver = false;
let gameRound = 1;
// ================ Game Images ================
let startImage;
let tutorialImage;
let playTutorialImage;
let gameOverImage;
let thankYouImage;
// arrows and letter button images
let greenDOWN, greenUP, greenLEFT, greenRIGHT, greenW, greenA, greenS, greenD;
let pinkDOWN, pinkUP, pinkLEFT, pinkRIGHT, pinkW, pinkA, pinkS, pinkD;
let orangeDOWN, orangeUP, orangeLEFT, orangeRIGHT, orangeW, orangeA, orangeS, orangeD;
// ================ Tutorial Variables ================
let tutorialBoxAngle = 20;
let noSkipBoxColor = '#6ec6cd';
let yesSkipBoxColor = '#ffb1a5';
let tutorialWidBox, tutorialHeiBox;
let noXSkipBox, noYSkipBox, yesXSkipBox, yesYSkipBox;
// ================ Player Variables ================
let amplitude = 2; // Height of the bobbing
let frequency = 0.09; // Speed of the bobbing
let player1Color = '#F66954E5';
let player2Color = '#25A4ADE8';
let xPlayerHead, yPlayerhead;
// ================ Creature Variables ================
let scaleComb = 30; // scale for the arrow images to appear
let delayTime = 300; // 300 millisecond delay between user input
let lastRemoveTime = 0; // time since the last arrow/letter removal
let fadeInSpeed = 5; // spawn fade-in speed
let xHitBox, yHitBox; // closest the creatures can be to the characters
let creatureSpeedFactor = 1; // inital creature speed
let creatureTint = 50; // inital transparent of the creature
let creatureColor = {easy: [96, 195, 54, creatureTint], medium: '#d244d2', hard: '#f58219'};
// console.log(Object.keys(creatureColor).length)
// ***** GREEN (easy creatures) *****
let greenNumberofComb = 4; // number of combination for green_ creatures
let greenSpeedx, greenSpeedy;
// ***** PINK (medium creatures)*****
let pinkNumberofComb = 6; // number of combination for pink_ creatures
// ***** ORANGE (hard creatures)*****
let orangeNumberofComb = 8; // number of combination for orange_ creatures
function preload(){
// background images
startImage = loadImage('/background_images/startingScreen.png');
tutorialImage = loadImage('/background_images/tutorial.png');
playTutorialImage = loadImage('/background_images/playTutorial.png');
playGameImage = loadImage('/background_images/playGame.png');
gameOverImage = loadImage('/background_images/gameOver.png');
thankYouImage = loadImage('/background_images/thankyou.png');
// green arrow and letter images
greenDOWN = loadImage('/_arrows/greenDOWN.png');
greenUP = loadImage('/_arrows/greenUP.png');
greenLEFT = loadImage('/_arrows/greenLEFT.png');
greenRIGHT = loadImage('/_arrows/greenRIGHT.png');
greenW = loadImage('/_letters/greenW.png');
greenA = loadImage('/_letters/greenA.png');
greenS = loadImage('/_letters/greenS.png');
greenD = loadImage('/_letters/greenD.png');
// pink arrow and letter images
pinkDOWN = loadImage('/_arrows/pinkDOWN.png');
pinkUP = loadImage('/_arrows/pinkUP.png');
pinkLEFT = loadImage('/_arrows/pinkLEFT.png');
pinkRIGHT = loadImage('/_arrows/pinkRIGHT.png');
pinkW = loadImage('/_letters/pinkW.png');
pinkA = loadImage('/_letters/pinkA.png');
pinkS = loadImage('/_letters/pinkS.png');
pinkD = loadImage('/_letters/pinkD.png');
// orange arrow and letter images
orangeDOWN = loadImage('/_arrows/orangeDOWN.png');
orangeUP = loadImage('/_arrows/orangeUP.png');
orangeLEFT = loadImage('/_arrows/orangeLEFT.png');
orangeRIGHT = loadImage('/_arrows/orangeRIGHT.png');
orangeW = loadImage('/_letters/orangeW.png');
orangeA = loadImage('/_letters/orangeA.png');
orangeS = loadImage('/_letters/orangeS.png');
orangeD = loadImage('/_letters/orangeD.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(220);
if (gameState == 'start'){
startScreen();
}
else if (gameState == 'tutorial'){
tutorialScreen();
}
else if (gameState == 'play tutorial'){
playTutorialScreen();
}
else if (gameState == 'play game') {
playGameScreen();
}
else if (gameState == 'game over') {
gameOverScreen();
}
else if (gameState == 'end game') {
thankYouScreen();
}
}
// =============== SCREENS ===============
function startScreen(){
image(startImage, 0, 0, windowWidth, windowHeight);
}
function tutorialScreen(){
image(tutorialImage, 0, 0, windowWidth, windowHeight);
tutorialBoxAngle = 20;
tutorialWidBox = windowWidth / 3;
tutorialHeiBox = windowHeight / 5;
noXSkipBox = (windowWidth * 2.7 )/ 5;
noYSkipBox = windowHeight / 4;
yesXSkipBox = (windowWidth * 2.7 )/ 5;
yesYSkipBox = windowHeight / 4 + windowHeight /4;
fill(noSkipBoxColor);
rect (noXSkipBox, noYSkipBox, tutorialWidBox, tutorialHeiBox, tutorialBoxAngle);
fill(yesSkipBoxColor);
rect (yesXSkipBox, yesYSkipBox, tutorialWidBox, tutorialHeiBox, tutorialBoxAngle);
if ((mouseX > noXSkipBox && mouseX < noXSkipBox + tutorialWidBox) && (mouseY > noYSkipBox && mouseY < noYSkipBox + tutorialHeiBox)) {
noSkipBoxColor = '#3BAFC9';
}
else {
noSkipBoxColor = '#6ec6cd';
}
if ((mouseX > yesXSkipBox && mouseX < yesXSkipBox + tutorialWidBox) && (mouseY > yesYSkipBox && mouseY < yesYSkipBox + tutorialHeiBox)){
yesSkipBoxColor = '#E97A6A';
}
else {
yesSkipBoxColor = '#ffb1a5';
}
}
function playTutorialScreen(){
image(playTutorialImage, 0, 0, windowWidth, windowHeight);
noStroke();
let playerHead = width / 33; // ~50 pixels
let distanceApart = width/ 26 // ~65 pixels
let player1 = new playerCharacters(player1Color, -distanceApart, 0, playerHead);
let player2 = new playerCharacters(player2Color, distanceApart, 0, playerHead);
let greenComb = [greenDOWN, greenUP, greenLEFT, greenRIGHT, greenW, greenA, greenS, greenD];
player1.player1Moves();
player2.player2Moves();
player1.playerHitBox(player2);
greenSpeedx = width / 825;
greenSpeedy = height/ height;
// Create the creature if it doesn't exist
if (!window.creature1) {
window.creature1 = new creatureSpawn(creatureColor.easy, greenComb, greenNumberofComb, greenSpeedx, greenSpeedy, width, height);
}
// Always draw and update the creature
window.creature1.draw_Creature();
}
function playGameScreen(){
image(playGameImage, 0, 0, windowWidth, windowHeight);
noStroke();
let playerHead = width / 33; // ~50 pixels
let distanceApart = width/ 26 // ~65 pixels
let player1 = new playerCharacters(player1Color, -distanceApart, 0, playerHead);
let player2 = new playerCharacters(player2Color, distanceApart, 0, playerHead);
player1.player1Moves();
player2.player2Moves();
}
function gameOverScreen(){
image(gameOverImage, 0, 0, windowWidth, windowHeight);
}
function thankYouScreen() {
image(thankYouImage, 0, 0, windowWidth, windowHeight);
}
// =============== CHARACTER CLASS ===============
class playerCharacters {
// x1Body, y1Body, x2Body, y2Body, x3Body, y3Body,
constructor(playerColor, xHead, yHead, headSize){
this.amp = amplitude;
this.freq = frequency;
this.playerColor = playerColor;
this.xHead = xHead + width / 2;
this.yHead = yHead + height / 2 + sin(frameCount * this.freq) * this.amp;
this.headSize = headSize;
this.x1Body = this.xHead - width/75;
this.y1Body = this.yHead + height/6.5;
this.x2Body = this.xHead - width/75;
this.y2Body = this.yHead + height/960;
this.x3Body = this.xHead + width/75;
this.y3Body = this.yHead + height/960;
this.x4Body = this.xHead + width/75;
this.y4Body = this.yHead + height/6.5;
this.showBody = true;
// =============== PLAYER VARIATIONS ===============
// Up-Arrow & Down-Arrow + W key & S key
this.yHead_UP_key = height/100; // ~8 pixels
this.yHead_DOWN_key = width / 33; // ~50 pixels
this.playerUpDownVariation = width / 33; // ~50 pixels
// Right-Arrow and D key
this.xHead_RIGHT_key = width/ 45; // ~37 pixels
this.yHead_RIGHT_key = height/ 56; // ~18 pixels
this.x1Body_RIGHT_key = width / 165; // ~10 pixels
this.x2Body_RIGHT_key = width / 42; // ~35 pixels
this.x3Body_RIGHT_key = width / 33; // ~50 pixels
this.x4Body_RIGHT_key = width / 83; // ~20 pixels
this.y3Body_RIGHT_key = height / 56; // ~18 pixels
this.y4Body_RIGHT_key = height / 56; // ~18 pixels
// Left-Arrow and A key
this.xHead_LEFT_key = width/ 45; // ~37 pixels
this.yHead_LEFT_key = height/ 56; // ~18 pixels
this.x1Body_LEFT_key = width / 83; // ~20 pixels
this.x2Body_LEFT_key = width / 33; // ~50 pixels
this.x3Body_LEFT_key = width / 48; // ~18 pixels
this.x4Body_LEFT_key = width / 165; // ~10 pixels
this.y3Body_LEFT_key = height / 56; // ~18 pixels
this.y4Body_LEFT_key = height / 56; // ~18 pixels
}
player1Moves() {
fill(this.playerColor);
if (keyIsDown(UP_ARROW)) {
circle(this.xHead, this.yHead - this.yHead_UP_key, this.headSize);
let y1temp = this.y1Body - this.playerUpDownVariation;
let y4temp = this.y4Body - this.playerUpDownVariation;
bezier(this.x1Body, y1temp, this.x2Body, this.y2Body, this.x3Body, this.y3Body, this.x4Body, y4temp);
}
else if (keyIsDown(DOWN_ARROW)){
circle(this.xHead, this.yHead + this.yHead_DOWN_key, this.headSize);
let y2temp = this.y2Body + this.playerUpDownVariation;
let y3temp = this.y3Body + this.playerUpDownVariation;
bezier(this.x1Body, this.y1Body, this.x2Body, y2temp, this.x3Body, y3temp, this.x4Body, this.y4Body);
}
else if (keyIsDown(RIGHT_ARROW)){
circle(this.xHead + this.xHead_RIGHT_key, this.yHead + this.yHead_RIGHT_key, this.headSize);
let x1temp = this.x1Body + this.x1Body_RIGHT_key;
let x4temp = this.x4Body + this.x4Body_RIGHT_key;
let x2temp = this.x2Body + this.x2Body_RIGHT_key;
let y2temp = this.y2Body + this.y3Body_RIGHT_key;
let x3temp = this.x3Body + this.x3Body_RIGHT_key;
let y3temp = this.y3Body + this.y4Body_RIGHT_key;
bezier(x1temp, this.y1Body, x2temp, y2temp, x3temp, y3temp, x4temp, this.y4Body);
}
else if (keyIsDown(LEFT_ARROW)){
circle(this.xHead - this.xHead_LEFT_key, this.yHead + this.yHead_LEFT_key, this.headSize);
let x1temp = this.x1Body - this.x1Body_LEFT_key;
let x4temp = this.x4Body - this.x4Body_LEFT_key;
let x2temp = this.x2Body - this.x2Body_LEFT_key;
let y2temp = this.y2Body + this.y3Body_LEFT_key;
let x3temp = this.x3Body - this.x3Body_LEFT_key;
let y3temp = this.y3Body + this.y4Body_LEFT_key;
bezier(x1temp, this.y1Body, x2temp, y2temp, x3temp, y3temp, x4temp, this.y4Body);
}
else {
circle(this.xHead, this.yHead, this.headSize);
bezier(this.x1Body, this.y1Body, this.x2Body, this.y2Body, this.x3Body, this.y3Body, this.x4Body, this.y4Body);
}
}
player2Moves() {
fill(this.playerColor);
if (keyIsDown(87)) { // w key
circle(this.xHead, this.yHead - height/100, this.headSize);
let y1temp = this.y1Body - this.playerUpDownVariation;
let y4temp = this.y4Body - this.playerUpDownVariation;
bezier(this.x1Body, y1temp, this.x2Body, this.y2Body, this.x3Body, this.y3Body, this.x4Body, y4temp);
}
else if (keyIsDown(83)){ // s key
circle(this.xHead, this.yHead + (width) / 33, this.headSize);
let y2temp = this.y2Body + this.playerUpDownVariation;
let y3temp = this.y3Body + this.playerUpDownVariation;
bezier(this.x1Body, this.y1Body, this.x2Body, y2temp, this.x3Body, y3temp, this.x4Body, this.y4Body);
}
else if (keyIsDown(68)){ // d key
circle(this.xHead + this.xHead_RIGHT_key, this.yHead + this.yHead_RIGHT_key, this.headSize);
let x1temp = this.x1Body + this.x1Body_RIGHT_key;
let x4temp = this.x4Body + this.x4Body_RIGHT_key;
let x2temp = this.x2Body + this.x2Body_RIGHT_key;
let y2temp = this.y2Body + this.y3Body_RIGHT_key;
let x3temp = this.x3Body + this.x3Body_RIGHT_key;
let y3temp = this.y3Body + this.y4Body_RIGHT_key;
bezier(x1temp, this.y1Body, x2temp, y2temp, x3temp, y3temp, x4temp, this.y4Body);
}
else if (keyIsDown(65)){ // a key
circle(this.xHead - this.xHead_LEFT_key, this.yHead + this.yHead_LEFT_key, this.headSize);
let x1temp = this.x1Body - this.x1Body_LEFT_key;
let x4temp = this.x4Body - this.x4Body_LEFT_key;
let x2temp = this.x2Body - this.x2Body_LEFT_key;
let y2temp = this.y2Body + this.y3Body_LEFT_key;
let x3temp = this.x3Body - this.x3Body_LEFT_key;
let y3temp = this.y3Body + this.y4Body_LEFT_key;
bezier(x1temp, this.y1Body, x2temp, y2temp, x3temp, y3temp, x4temp, this.y4Body);
}
else {
circle(this.xHead, this.yHead, this.headSize);
bezier(this.x1Body, this.y1Body, this.x2Body, this.y2Body, this.x3Body, this.y3Body, this.x4Body, this.y4Body);
}
}
playerHitBox(otherPlayer) {
fill(0,0,0,180)
heightPlayer = this.y1Body - (this.yHead - this.headSize) + height/20;
widthPlayer = otherPlayer.x4Body - this.x1Body + width/15;
xHitBox = width/2;
yHitBox = height/2 + heightPlayer/4 + 5;
// uncomment to see the hitbox
ellipse(xHitBox, yHitBox, widthPlayer, heightPlayer)
}
}
// =============== CREATURE CLASS ===============
class creatureSpawn {
constructor(creatureColor, arrLetterArrow, numberOfComb, creatureSpeedx, creatureSpeedy, xCreature, yCreature){
this.creatureRed = creatureColor[0];
this.creatureGreen = creatureColor[1];
this.creatureBlue = creatureColor[2];
this.creatureTint = creatureColor[3];
this.arrLetterArrow = arrLetterArrow;
this.numberOfComb = numberOfComb;
this.creatureSpeedx = creatureSpeedx;
this.creatureSpeedy = creatureSpeedy;
this.isHitBox = false;
this.creatureCombArr = [];
this.xCreature = xCreature;
this.yCreature = yCreature;
this.xCombArr = xCreature - scaleComb * this.numberOfComb / 2;
this.yCombArr = yCreature - (scaleComb * 1.85);
}
generate_combination(){
for(let i = 0; i < this.numberOfComb; i++) {
let im = random(this.arrLetterArrow);
this.creatureCombArr.push({img: im, x: this.xCombArr, y: this.yCombArr, creatureTint: this.creatureTint });
this.xCombArr += scaleComb;
}
return this.creatureCombArr;
}
draw_Creature() {
fill(this.creatureRed, this.creatureGreen, this.creatureBlue, this.creatureTint);
circle(this.xCreature, this.yCreature, width/ 20);
// Calculate direction towards center
let dx = xHitBox - this.xCreature;
let dy = yHitBox - this.yCreature;
// Calculate distance to center
let distance = dist(this.xCreature, this.yCreature, xHitBox, yHitBox);
// Check if creature is inside hitbox
let a = widthPlayer - (width/ 18); // major axis
let b = heightPlayer; // minor axis
// Equation: ((x - xHitBox)^2 / a^2) + ((y - yHitBox)^2 / b^2) = 1
let insideEllipse = ((this.xCreature - xHitBox) * (this.xCreature - xHitBox)) / (a * a) + ((this.yCreature - yHitBox) * (this.yCreature - yHitBox)) / (b * b) <= 1;
if (this.creatureTint < 255) {
this.creatureTint += fadeInSpeed;
}
if (!insideEllipse) {
// Move creature towards center
this.xCreature += dx / distance * this.creatureSpeedx;
this.yCreature += dy / distance * this.creatureSpeedy;
this.isHitBox = false;
} else {
this.isHitBox = true;
}
}
}
// =============== MOUSE CLICKED ===============
function mouseClicked(){
if (gameState == 'start'){
gameState = 'tutorial';
}
else if (gameState == 'tutorial'){
if ((mouseX > noXSkipBox && mouseX < noXSkipBox + tutorialWidBox) && (mouseY > noYSkipBox && mouseY < noYSkipBox + tutorialHeiBox)){
gameState = 'play tutorial';
}
if ((mouseX > yesXSkipBox && mouseX < yesXSkipBox + tutorialWidBox) && (mouseY > yesYSkipBox && mouseY < yesYSkipBox + tutorialHeiBox)){
gameState = 'play game';
}
}
}
// =============== fullscreen functionalities ===============
function keyTyped() {
if (key === 'f'){
toggleFullScreen();
}
}
function toggleFullScreen() {
let fs = fullscreen();
fullscreen(!fs);
}
function windowResized() {
// Resize the canvas when the window is resized (or fullscreen is toggled)
resizeCanvas(windowWidth, windowHeight);
if (creature1) {
creature1.xCreature = width;
creature1.yCreature = height;
}
}