xxxxxxxxxx
946
/*
Anthony Hanley
keonhanl@buffalo.edu
DMS 121, University at Buffalo, Fall 2020
This work is about passing the time with some light weight competition. While it may not be cutthroat, it is someone funny to beat the computer players. It is also a message that making a game is not as easy as it looks. This took longer than expected. It took runescape 10 years to be turned into a living game. So have some fun and laugh at the dump NPCs.
https://editor.p5js.org/keonhanl/full/lyK7D3ci3
References: https://www.youtube.com/playlist?list=PLBDInqUM5B26FjwMMZqGDxqQr1kX5V9Ul
*/
var coinList;
var localPlayer;
var activeKeys;
var platformsList;
var state;
var titleScreenCoin;
var lobbyTimer;
var updateTime;
var clock = 120;
var clockTimer;
var NPCnum = 1;
var NPCList = [];
var coinFrameList = [];
var platformImg;
var backdrop;
var coinCollect;
var jumpSound;
var mezmer8Bit;
var x2Speed;
var playerFrameRight = [];
var playerFrameLeft = [];
var npcWin;
var playerWin;
var tie;
function preload() {
//Loads the coin image frams
for (var coinF = 0; coinF < 7; coinF++) {
var coinImg = loadImage("assets/Frame " + coinF + ".png")
coinFrameList.push(coinImg);
}
//platform boxes
platformImg = loadImage("assets/WoodenCrate.png")
//background mountains
backdrop = loadImage("assets/Backdrop.png")
//Game Sounds
coinCollect = loadSound('assets/coinCollect.mp3');
jumpSound = loadSound('assets/jump.mp3');
mezmer8Bit = loadSound('assets/Mezmer.mp3');
//x2 Speed icon
x2Speed = loadImage('assets/SpeedBoost.png')
//loads frames for both directions.
for (var spriteSheet = 1; spriteSheet < 19; spriteSheet++) {
playerFrameRight.push(loadImage("assets/frame_0" + spriteSheet + ".png"));
playerFrameLeft.push(loadImage("assets/framer_00" + spriteSheet + ".png"));
}
//announcer says who wins
npcWin = loadSound('assets/NPC Wins.mp3');
playerWin = loadSound('assets/Player Wins.mp3');
tie = loadSound('assets/You Tied.mp3');
}
function setup() {
createCanvas(900, 900);
frameRate(600);
//smooth(16);
textAlign(CENTER);
imageMode(CENTER);
coinCollect.setVolume(0.15);
jumpSound.setVolume(0.15);
mezmer8Bit.loop();
coinList = [];
for (i = 0; i < 30; i++) {
coinList.push(new Coin());
}
localPlayer = new Player();
activeKeys = [];
platformsList = [];
for (var platN = 0; platN < int(width * 0.0125); platN++) {
platformsList[platN] = new Platforms((width * 0.25) * platN, width / 8, 10);
}
rectMode(CENTER);
state = 1;
titleScreenCoin = new Coin();
//multiplayer
playerList = [];
lobbyTimer = millis();
}
function draw() {
background(220);
image(backdrop, width / 2, height / 2 + backdrop.height + 10);
//Seperates the draw into states
if (state == 1) {
homeScreen();
} else if (state == 2) {
npcGame();
} else if (state == 3) {
//These states are now deprecated. One day I will get them to work.
initializeLobby();
} else if (state == 4) {
playMulti();
} else if (state == 5) {
resetLobby();
state = 1;
}
}
function homeScreen() {
mezmer8Bit.setVolume(0.15);
mezmer8Bit.pause();
//black bar in the middle
noStroke(0)
fill(0);
rect(width / 2, height / 2, 5, height);
//Selections
//Grey background
fill(200);
noStroke();
rect(width / 4, height / 2, width / 2, height);
//Button sections
fill(0);
textSize(width * 0.05);
fill(127);
rect(width / 4, height / 3 - 10, 350, 125, 20);
fill(255);
stroke(0);
strokeWeight(5);
text("Player vs Bot", width / 4, height / 3);
textSize(width * 0.025);
text("Up to 3 Bots!", width / 4, height / 3 + 75);
noStroke();
//UP ARROW
textSize(width * 0.0375);
fill(127);
rect(width / 4 + 200, height / 3 - 60, 40, 50, 20);
fill(0);
text("↑", width / 4 + 200, height / 3 - 50);
if (mouseX >= (width / 4 + 200) - 20 && mouseX <= (width / 4 + 200) + 20 && mouseY >= (height / 3 - 60) - 25 && mouseY <= (height / 3 - 60) + 25) {
noFill();
strokeWeight(5);
stroke(0);
rect(width / 4 + 200, height / 3 - 60, 40, 50, 20);
strokeWeight(1);
noStroke();
}
//Number of NPCs
fill(0);
text(NPCnum, width / 4 + 200, height / 3 + 5);
//DOWN ARROW
fill(127);
rect(width / 4 + 200, height / 3 + 40, 40, 50, 20);
fill(0);
text("↓", width / 4 + 200, height / 3 + 50);
if (mouseX >= (width / 4 + 200) - 20 && mouseX <= (width / 4 + 200) + 20 && mouseY >= (height / 3 + 50) - 25 && mouseY <= (height / 3 + 50) + 25) {
noFill();
strokeWeight(5);
stroke(0);
rect(width / 4 + 200, height / 3 + 40, 40, 50, 20);
strokeWeight(1);
noStroke();
fill(0);
}
stroke(0);
fill(0, 0);
if (mouseX >= width / 4 - 175 && mouseX <= width / 4 + 175 && mouseY >= height / 3 - 62.5 && mouseY <= height / 3 + 62.5) {
strokeWeight(5);
rect(width / 4, height / 3 - 10, 350, 125, 20);
strokeWeight(1);
}
fill(0);
textSize(width * 0.0175);
noStroke();
text("Message From Developer: Welcome to Coin Game. \n This is a representation of my broken dreams. \n Once again, Icarus has flown too close to the sun. Have fun.", width / 4, height - height / 3);
//Titles
fill(255);
textSize(width * 0.075);
stroke(0);
strokeWeight(5);
text("Coin Game", width - width / 4, height / 2);
noStroke(0);
titleScreenCoin.x = width - width / 4;
titleScreenCoin.y = height / 2 + (width * 0.075);
titleScreenCoin.moveInc = 0;
titleScreenCoin.coinSpinWidth = width * 0.05;
titleScreenCoin.coinUpdate();
titleScreenCoin.imageScale = 1;
}
//Sets up tha game with chosen number of bots. Pushes new bots into a list that will be updated through iterations.
function initiateNPCGame() {
mezmer8Bit.play();
for (var npcInt = 0; npcInt < NPCnum; npcInt++) {
NPCList.push(new ComputerPlayer());
NPCList[npcInt].playerNum = npcInt + 1;
NPCList[npcInt].playerTag = NPCList[npcInt].playerTag + " " + NPCList[npcInt].playerNum;
}
}
//resets the game to prevent score carry over
function resetNPCGame() {
localPlayer.score = 0;
NPCList = [];
}
//Game of player vs Bots
function npcGame() {
//Draws the platforms on teh screen
for (var platI = 0; platI < platformsList.length; platI++) {
platformsList[platI].platformDraw();
}
//updates every coin in the list.
for (index = 0; index < coinList.length; index++) {
coinList[index].coinUpdate();
}
localPlayer.playerMove();
//iterates through the list to move the NPCs.
for (var npcPlay = 0; npcPlay < NPCList.length; npcPlay++) {
NPCList[npcPlay].npcMove();
}
}
function mousePressed() {
//Button that starts the game.
if (state == 1) {
if (mouseX >= width / 4 - 175 && mouseX <= width / 4 + 175 && mouseY >= height / 3 - 62.5 && mouseY <= height / 3 + 62.5) {
state = 2;
initiateNPCGame();
lobbyTimer = millis();
clockTimer = second();
}
//UP ARROW to increase bot number
if (mouseX >= (width / 4 + 200) - 20 && mouseX <= (width / 4 + 200) + 20 && mouseY >= (height / 3 - 60) - 25 && mouseY <= (height / 3 - 60) + 25 && NPCnum < 3) {
NPCnum++;
NPCnum = NPCnum % 4;
if (NPCnum == 0) {
NPCnum += 1;
}
}
//DOWN ARROW to decrease bot numbers. In theory we can have as many as we want. Howerver they are not smart enough to win that way.
if (mouseX >= (width / 4 + 200) - 20 && mouseX <= (width / 4 + 200) + 20 && mouseY >= (height / 3 + 50) - 25 && mouseY <= (height / 3 + 50) + 25) {
NPCnum--;
NPCnum = NPCnum % 4;
if (NPCnum == 0) {
NPCnum += 1;
}
}
}
}
//This is the function that dictates who wins by sorting the scores. Rather simple, really.
function compareScores(a, b) {
if (a < b) {
return 1;
}
if (a > b) {
return -1;
}
return 0;
}
//This plays the correct sounds when th egame ends. Who wins? You decide!
function winner() {
var scores = [];
scores.push(localPlayer.score);
for (var npcScoreN = 0; npcScoreN < NPCList.length; npcScoreN++) {
scores.push(NPCList[npcScoreN].npcScore);
}
scores.sort(compareScores);
if (scores[0] == localPlayer.score && localPlayer.score > scores[1]) {
playerWin.setVolume(0.15)
playerWin.play();
} else if (scores[0] == localPlayer.score) {
tie.setVolume(0.15)
tie.play();
} else {
npcWin.setVolume(0.15)
npcWin.play();
}
}
//COIN CLASS
class Coin {
//The coins are generated and are never deleted. They are reset with random values to appear off screen and will fall until reset again.
constructor() {
this.x = random(10, width - 10);
this.y = random(-50, -height);
this.moveInc = this.moveInc = random(width * 0.00025, width * 0.00125);
this.pointVal = 10;
this.coinWidth = 20;
this.coinSpinWidth = 20;
this.switch = 1;
this.imageScale = 0.23255813953;
this.currentFrame = 0;
this.isSpeedBoost = false;
}
coinUpdate() {
//moves the coin
this.y = lerp(this.y, this.y + this.moveInc, 1);
//Spins the coin
this.coinWidth -= 0.5 * this.switch;
if (this.coinWidth >= this.coinSpinWidth || this.coinWidth <= 0) {
this.switch *= -1;
}
//Draws the coin while giving it a spin by iterating through the coin images
if (frameCount % 15 == 0) {
this.currentFrame++;
}
this.currentFrame = this.currentFrame % 7;
var img;
//Every coin has a chance of becoming a x2 Speed Boost. If it become that, the look will change.
if (this.isSpeedBoost == false) {
img = coinFrameList[this.currentFrame];
image(img, this.x, this.y, img.width * this.imageScale, img.height * this.imageScale);
} else {
img = x2Speed;
image(img, this.x, this.y);
}
//resets the coin when it is below the screen
if (this.y > height + 10) {
this.resetCoin();
}
}
getX() {
return this.x;
}
getY() {
return this.y;
}
//resets the coins with varying values. Some are fast and others slow.
resetCoin() {
this.x = random(10, width - 10);
this.y = random(-10, -30);
this.moveInc = random(0.1, 0.5);
var check = random(0, 51);
if (int(check) == 25) {
this.isSpeedBoost = true;
} else {
this.isSpeedBoost = false;
}
}
}
//Player Class
class Player {
constructor() {
this.playerX = 10;
this.playerY = height - 20;
this.playerVelo = 1.5;
this.playerDir = 0;
this.score = 0;
this.currentGround = height;
this.playerDirection = "D";
this.spriteSheetCounter = 0;
//jump variables
this.jump = false;
this.gravDir = 1;
this.yVelocity = 2;
this.jumpPower = width * 0.025;
this.fallingSpeed = 2;
this.fallingMultiplyer = 1;
this.minHeight = height - 20;
this.maxHeight = 100;
this.jumpCounter = 0;
this.speedClock = 0;
this.speedTime = 0;
}
playerMove() {
//This allows for the most recent input to take priority.
if (activeKeys[0] == 'A') {
this.playerDir = -1;
this.playerDirection = "A"
} else if (activeKeys[0] == 'D') {
this.playerDir = 1;
this.playerDirection = "D"
}
//No active left, right? No horizontal movement.
if (activeKeys.length == 0 ||
(activeKeys.indexOf('A') == -1 && activeKeys.indexOf('D') == -1)) {
this.playerDir = 0;
}
//JUMPING
let element = activeKeys.indexOf("W")
if (element > -1) {
this.jump = true;
}
if (this.playerY >= this.minHeight && !this.jump) {
//if on ground dont fall
this.playerY = this.playerY;
this.jumpCounter = 0;
} else {
//else fall
this.playerY += (this.gravDir * this.yVelocity);
}
//This allows the platforms to have collision detection whenever a jump has been activated.
if (this.jump) {
if (this.playerY <= this.maxHeight || this.jumpCounter >= this.jumpPower) {
for (var platE = 0; platE < platformsList.length; platE++) {
if (this.playerY >= this.minHeight) {
this.playerY = this.minHeight;
} else if (this.playerX + 10 >= platformsList[platE].x - platformsList[platE].width / 2 && this.playerX - 10 <= platformsList[platE].x + platformsList[platE].width / 2 && this.playerY + 20 >= platformsList[platE].y - platformsList[platE].height / 2 && this.playerY + 20 <= platformsList[platE].y + platformsList[platE].height / 2) {
//checks for colliion again to prevent falling through
this.playerY = platformsList[platE].y - platformsList[platE].height / 2 - 20;
} else {
this.yVelocity = this.fallingSpeed * this.fallingMultiplyer; //fall at max
}
}
} else {
this.yVelocity = -this.jumpPower;
this.jumpCounter += width * 0.0025;
}
} else {
this.yVelocity = this.fallingSpeed * this.fallingMultiplyer;
}
//Collision once jump has finnished. I tried to put them together but it just became even more janky.
for (var platI = 0; platI < platformsList.length; platI++) {
this.platformCollisions(platformsList[platI]);
}
//This moves your character. It uses velocity and direction. since this is a 2D plane, no direction means no movement. -1 is left, 1 is right
if (this.playerX > 9 && this.playerX < width + 11) {
this.playerX = lerp(this.playerX, this.playerX +
(this.playerVelo * this.playerDir), 1);
}
//This prevents player from walking off screen
if (this.playerX <= 9) {
this.playerX = 10;
}
if (this.playerX >= width - 11) {
this.playerX = width - 10;
}
this.catchCoin();
fill(200);
//Iterates through character frams much like it doe with coins. This time it keeps track of last direction you were facing. This direction variable takes the form of key presses.
if (frameCount % 4 == 0) {
this.spriteSheetCounter++;
}
var avatar;
if (this.playerDirection == "D" && activeKeys[0] == "D") {
avatar = playerFrameRight[(this.spriteSheetCounter % 18)];
} else if (this.playerDirection == "A" && activeKeys[0] == "A") {
avatar = playerFrameLeft[(this.spriteSheetCounter % 18)];
} else if (this.playerDirection == "D") {
avatar = playerFrameRight[5];
} else {
avatar = playerFrameLeft[5];
}
image(avatar, this.playerX, this.playerY, 17.6, 40);
//Display Name and score above player.
textSize(15);
fill(0);
strokeWeight(1);
stroke(255);
text("Player 1 | Score: " + this.score, this.playerX, this.playerY - 25)
stroke(0);
//Places a 10 second timer on the player when double speeed is activated.
if (this.speedClock >= 10) {
this.speedTimer = 0;
this.playerVelo = 1.5;
this.speedClock = 0;
}
if (this.speedTimer != 0 && this.speedTimer != second()) {
this.speedClock++;
this.speedTimer = second();
}
}
//Coin collisons. When rect to point collision occurs it captures the coin.
catchCoin() {
for (index = 0; index < coinList.length; index++) {
if (coinList[index].getX() > this.playerX - 10 &&
coinList[index].getX() < this.playerX + 10) {
if (coinList[index].getY() > this.playerY - 20 &&
coinList[index].getY() < this.playerY + 20) {
if (coinList[index].isSpeedBoost == false) {
this.score += 10;
} else {
this.playerVelo *= 2;
this.speedTimer = second();
}
coinList[index].resetCoin()
if (!coinCollect.isPlaying()) {
coinCollect.play();
}
}
}
}
}
//platformCollisions that stop you from falling into the ground when holding "W"
platformCollisions(plats) {
if (this.playerX + 10 >= plats.x - plats.width / 2 && this.playerX - 10 <= plats.x + plats.width / 2 &&
this.playerY + 20 >= plats.y - plats.height / 2 && this.playerY + 20 <= plats.y + plats.height / 2 &&
this.jump == false) {
this.playerY = plats.y - plats.height / 2 - 20;
this.yVelocity = 0;
this.jumpCounter = 0;
}
}
}
//Adds the key to active keys list to the very beginning.
function keyPressed() {
if (key.toUpperCase() == 'A') {
activeKeys.unshift(key.toUpperCase());
}
if (key.toUpperCase() == 'D') {
//localPlayer.playerDir = 1;
activeKeys.unshift(key.toUpperCase());
}
if (key.toUpperCase() == 'W') {
activeKeys.push(key.toUpperCase());
//localPlayer.jump = true;
if (!jumpSound.isPlaying() && localPlayer.jump == false) {
jumpSound.setVolume(0.15);
jumpSound.play();
}
}
}
//Removes the key from the active Keys list
function keyReleased() {
let element = activeKeys.indexOf(key.toUpperCase())
if (element > -1) {
activeKeys.splice(element, 1);
if (key.toUpperCase() == "W") {
localPlayer.jump = false;
}
}
}
class Platforms {
constructor(xPos, pWidth, pHeight) {
this.x = xPos;
//This should prevent the platforms from being out of whack when screen size changes.
if (this.x % width / 2 == 0) {
this.y = width * 0.6875;
} else {
this.y = width * 0.8125;
}
this.width = pWidth;
this.height = pHeight;
}
platformDraw() {
//Draws the platforms using small, wodden crates
var platList = [];
for (var platImg = 0; platImg < this.width / this.height; platImg++) {
platList.push(image(platformImg, (this.x - this.width / 2) + (this.height) * platImg, this.y, this.height, this.height));
}
}
getX() {
return this.x;
}
getY() {
return this.y;
}
getWidth() {
return this.width;
}
getheight() {
return this.height;
}
}
//This is a near carbon copy of normal player class.
class ComputerPlayer {
constructor() {
this.npcX = random(10, width - 10);
this.npcY = height - 20;
this.npcVelo = 1.5;
this.npcDir = 0;
this.npcScore = 0;
this.currentGround = height;
//jump variables
this.npcJump = false;
this.gravDir = 1;
this.npcYVelocity = 2;
this.npcJumpPower = width * 0.025;
this.fallingSpeed = 2;
this.npcFallingMultiplyer = 1;
this.npcMinHeight = height - 20;
this.npcMaxHeight = 100;
this.npcJumpCounter = 0;
this.npcSpriteSheetCounter = 0;
this.npcColor = (random(0, 255), random(0, 255), random(0, 255));
//target coin data
this.targetCoin = null;
this.time = millis();
this.destX = width / 200;
this.targetDist = null;
this.shortDist = random(10, 900);
this.keys = [];
this.DIRECTION = "D";
this.playerTag = "CPU"
this.playerNum = 0;
this.npcSpeedClock = 0;
this.npcSpeedTimer = 0;
}
npcMove() {
//The computer players keep the time. when clock runs out the game ends and the winner is announced.
if (clockTimer != second()) {
clockTimer = second();
clock--;
if (clock <= 0) {
winner();
state = 1;
clock = 120;
resetNPCGame();
}
}
//Countdown
textSize(width * 0.02777777777);
fill(0);
text("TIME: " + int(clock), width / 2, height / 2);
if (this.npcX <= this.destX) {
this.npcX += this.npcVelo;
}
if (this.npcX >= this.destX) {
this.npcX -= this.npcVelo;
}
//What to do if target coin is off screen. No cheating
if (this.targetCoin != null && this.targetCoin.getY() < 0) {
this.targetCoin = null;
this.shortDist = random(0, 900);
this.targetDist = null;
this.keys = [];
}
//Have a target coin? Then use target distance
if (this.targetCoin != null) {
this.targetDist = dist(this.targetCoin.getX(), this.targetCoin.getY(), this.npcX, this.npcY);
}
//Not sure why this is here but it breaks when i delete it. Will keep until further notice. Left over from java run through
if (abs(this.npcX - this.destX) > this.npcVelo) {
var dirElement = this.keys.indexOf(this.DIRECTION);
if (dirElement > -1) {
this.keys.splice(dirElement, 1);
}
}
/* This one is to target coins based on npc distance,, player distance, other npc distance and will recalculate when coin is captured or enough time has passed. Due to multiple npcs now, the class has more randomness to prevent them from constantly chasing the same coin.*/
if (this.targetCoin == null || (millis() - this.time) >= int(random(0, 10)) || this.targetCoin.getY() < 0) {
this.time = millis();
for (var tarCoin = 0; tarCoin < coinList.length; tarCoin++) {
var tempDist = dist(coinList[tarCoin].getX(), coinList[tarCoin].getY(), this.npcX, this.npcY);
if (tempDist < this.shortDist && coinList[tarCoin].getY() >= 0) { //Which coin has the shortest distance and is currently on-screen
for (var NPCListNum = 0; NPCListNum < NPCList.length; NPCListNum++) {
if (NPCList[NPCListNum].playerNum != this.playerNum && tempDist < dist(coinList[tarCoin].getX(), coinList[tarCoin].getY(), NPCList[NPCListNum].npcX, NPCList[NPCListNum].npcY) && (NPCList[NPCListNum].targetCoin != coinList[tarCoin] || NPCList[NPCListNum].targetCoin != this.targetCoin) && tempDist < dist(coinList[tarCoin].getX(), coinList[tarCoin].getY(), localPlayer.playerX, localPlayer.playerY)) {
this.shortDist = tempDist;
this.targetCoin = coinList[tarCoin];
this.destX = this.targetCoin.getX();
}
}
//ignore the monster above if only 1 npc.
if (NPCList.length == 1) {
this.shortDist = tempDist;
this.targetCoin = coinList[tarCoin];
this.destX = this.targetCoin.getX();
}
}
}
//We have a coin! make that our destination.
if (this.targetCoin != null) {
this.destX = this.targetCoin.getX();
} else {
this.shortDist = random(0, 900);
}
} else {
//maybe if i dream hard enough, the npcs will choose a location on the map and stay away from each other
if (frameCount % int(random(0, 9000)) == 0) {
this.destX = random(10, width - 10);
}
}
//JUMPING. Same madness as with player class
if (this.targetCoin != null && this.npcY - height * 0.2625 <= this.targetCoin.getY() && this.targetDist <= 225) {
this.npcJump = true;
}
if (this.npcY >= this.npcMinHeight && !this.npcJump) {
//if on ground dont fall
this.npcY = this.npcY;
this.npcJumpCounter = 0;
} else {
//else fall
this.npcY += (this.gravDir * this.npcYVelocity);
}
if (this.npcJump) {
if (this.npcY <= this.npcMaxHeight || this.npcJumpCounter >= this.npcJumpPower) {
for (var platE = 0; platE < platformsList.length; platE++) {
if (this.npcY >= this.npcMinHeight) {
this.npcY = this.npcMinHeight;
} else if (this.npcX + 10 >= platformsList[platE].x - platformsList[platE].width / 2 && this.npcX - 10 <= platformsList[platE].x + platformsList[platE].width / 2 && this.npcY + 10 >= platformsList[platE].y - platformsList[platE].height / 2 && this.npcY + 10 <= platformsList[platE].y + platformsList[platE].height / 2) {
//checks for colliion again to prevent falling through
this.npcY = platformsList[platE].y - platformsList[platE].height / 2 - 10;
} else {
this.npcYVelocity = this.fallingSpeed * this.npcFallingMultiplyer; //fall at max
}
}
} else {
this.npcYVelocity = -this.npcJumpPower;
this.npcJumpCounter += width * 0.0025;
}
} else {
this.npcYVelocity = this.fallingSpeed * this.npcFallingMultiplyer;
}
for (var platI = 0; platI < platformsList.length; platI++) {
this.platformCollisions(platformsList[platI]);
}
//No walking off screen today, jimbo
if (this.npcX > 9 && this.npcX < width + 11) {
this.npcX = lerp(this.npcX, this.npcX +
(this.npcVelo * this.npcDir), 1);
}
if (this.npcX <= 9) {
this.npcX = 10;
}
if (this.npcX >= width - 11) {
this.npcX = width - 10;
}
this.catchCoin();
//The bots dont have avatars because it made the game hault to a fram or less persecond despite following the same logic that works well for our player. Instead, different color circles.
fill(this.npcColor);
rect(this.npcX, this.npcY, 20, 20, 20);
textSize(15);
fill(0);
strokeWeight(1);
stroke(255);
text(this.playerTag + " | Score: " + this.npcScore, this.npcX, this.npcY - 20)
stroke(0);
//text(nf(int(this.score), [4], [0]), width / 2, 100, 20);
if (this.npcSpeedClock == 10) {
this.npcSpeedTimer = 0;
this.npcVelo = 1.5;
this.npcSpeedClock = 0;
}
if (this.speedTimer != 0 && this.speedTimer != second()) {
this.npcSpeedClock++;
this.npcSpeedTimer = second();
}
}
//Coin collisons
catchCoin() {
for (index = 0; index < coinList.length; index++) {
if (coinList[index].getX() > this.npcX - 10 &&
coinList[index].getX() < this.npcX + 10) {
if (coinList[index].getY() > this.npcY - 10 &&
coinList[index].getY() < this.npcY + 10) {
if (coinList[index].isSpeedBoost == false) {
this.npcScore += 10;
} else {
this.npcVelo *= 2;
this.npcSpeedTimer = second();
}
coinList[index].resetCoin()
if (!coinCollect.isPlaying()) {
coinCollect.play();
}
this.targetCoin = null;
this.npcJump = false;
this.shortDist = 900;
this.targetDist = null;
this.keys = [];
}
}
}
}
//platformCollisions
platformCollisions(plats) {
if (this.npcX + 10 >= plats.x - plats.width / 2 && this.npcX - 10 <= plats.x + plats.width / 2 &&
this.npcY + 10 >= plats.y - plats.height / 2 && this.npcY + 10 <= plats.y + plats.height / 2 &&
this.npcJump == false) {
this.npcY = plats.y - plats.height / 2 - 10;
this.npcYVelocity = 0;
this.npcJumpCounter = 0;
}
}
}