diff --git a/public/assets/monster.png b/public/assets/monster.png deleted file mode 100644 index 9cb1c46..0000000 Binary files a/public/assets/monster.png and /dev/null differ diff --git a/public/assets/nubzuki.png b/public/assets/nubzuki.png new file mode 100644 index 0000000..bb0f5a6 Binary files /dev/null and b/public/assets/nubzuki.png differ diff --git a/public/assets/nubzuki_chat.png b/public/assets/nubzuki_chat.png new file mode 100644 index 0000000..999bf01 Binary files /dev/null and b/public/assets/nubzuki_chat.png differ diff --git a/src/game/constants.js b/src/game/constants.js new file mode 100644 index 0000000..5543dc7 --- /dev/null +++ b/src/game/constants.js @@ -0,0 +1,22 @@ + +export const GAME_COLORS = { + background: '#e8e2d6', + basicPlat: '#6c8ae4', + movingPlat: '#4cc9f0', + springPlat: '#80ed99', + oneTimePlat: '#e76f51', + startingPlat: '#f4a261' +}; + +export const PLATFORMS_GAP = 80; +export const PLATFORM_WIDHT = 70; +export const PLATFORM_HEIGHT= 15; + +export const PLAT_TYPE = { + BASIC: 'basic', + MOVING: 'moving', + SPRING: 'spring', + ONE_TIME: 'one-time' +}; + + diff --git a/src/game/game.js b/src/game/game.js index 2a1832b..12ff3cb 100644 --- a/src/game/game.js +++ b/src/game/game.js @@ -1,25 +1,36 @@ +import { updatePlayerPosition } from './gameUtils.js'; +import { initPlatforms, moveWorld} from './platforms.js'; +import { GAME_COLORS, PLATFORMS_GAP } from './constants.js'; + // Game state let player; -let platform; let platforms; let pendingWorldMove = 0; -import { updatePlayerPosition } from './gameUtils.js'; -import { initPlatforms, moveWorld, PLATFROMS_GAP } from './platforms.js'; function createPlayer() { player = new Sprite(); - player.diameter = 100; - player.scale = 0.3; player.x = width / 2; player.y = 700; + + player.scale = 0.20; + player.img = "assets/nubzuki.png"; + + player.rotationLock = true; + + player.w = 20; + player.h = 20; + player.offset.y = 25; + player.bounciness = 0; player.elevation = 0; return player; } + export function initializeGame() { - world.debug = true; //TODO remove + //world.debug = true; //TODO remove + //allSprites.debug = true; //TODO remove world.gravity.y = 10; platforms = initPlatforms(); player = createPlayer(); @@ -27,17 +38,19 @@ export function initializeGame() { export function updateGame() { clear(); - background(200); + background(GAME_COLORS.background); + pendingWorldMove += updatePlayerPosition(player, platforms); - if (pendingWorldMove > PLATFROMS_GAP) { + + if (pendingWorldMove > PLATFORMS_GAP) { const move = Math.min(pendingWorldMove, 5); pendingWorldMove -= move; platforms = moveWorld(platforms, player.elevation, move); player.y += move; - player.bounciness = 0; // needed becouse bug in p5.play that rests bounciness + player.bounciness = 0; } - + player.rotation = player.vel.x * 1.5; // UI diff --git a/src/game/gameUtils.js b/src/game/gameUtils.js index 2c1861d..72bc336 100644 --- a/src/game/gameUtils.js +++ b/src/game/gameUtils.js @@ -1,6 +1,31 @@ +import { PLAT_TYPE } from './constants.js'; + + +function handleJump(player, platform) { + + let elevationGain = 0; + if (player.elevation < platform.elevation) { + elevationGain = platform.elevation - player.elevation; + player.elevation = platform.elevation; + } + + switch (platform.type) { + case PLAT_TYPE.ONE_TIME: + player.vel.y = -7.5; + platform.remove(); + break; + case PLAT_TYPE.SPRING: + player.vel.y = -13; + break; + default: + player.vel.y = -7.5; + } + + return elevationGain; +} export function updatePlayerPosition(player, platforms) { - let elevationGain = 0; + // Controls player.vel.x = 0; if (keyIsDown(LEFT_ARROW)) { @@ -10,7 +35,7 @@ export function updatePlayerPosition(player, platforms) { player.vel.x = 5; } - // Wrap horizontally around canvas edges + // Wrap horizontally if (player.x > width) { player.x = 0; } else if (player.x < 0) { @@ -19,7 +44,7 @@ export function updatePlayerPosition(player, platforms) { // Jumping thrue platforms for (let plat of platforms) { - if (player.vel.y <= 0 && player.y > plat.y) { + if (player.vel.y <= 0 && player.y + player.offset.y > plat.y) { plat.collider = 'none'; } else { plat.collider = 'static'; @@ -27,19 +52,14 @@ export function updatePlayerPosition(player, platforms) { } // Automatic jumping - if(player.vel.y >= 0) { - for (let plat of platforms) { - if (player.colliding(plat)) { - player.vel.y = -7.5; - - if (player.elevation < plat.elevation) { - elevationGain = plat.elevation - player.elevation; - player.elevation = plat.elevation; - } - break; + if (player.vel.y >= 0) { + for (let i = 0; i < platforms.length; i++) { + + if (player.colliding(platforms[i])) { + return handleJump(player, platforms[i]); } } } - - return elevationGain; + + return 0; } diff --git a/src/game/platforms.js b/src/game/platforms.js index f691908..05e5d99 100644 --- a/src/game/platforms.js +++ b/src/game/platforms.js @@ -1,56 +1,140 @@ -export const PLATFROMS_GAP = 80; -const PLATFORM_COLORS = [ - '#c44545', - '#c98a1f', - '#1f8f86', - '#2c3e5e', - '#9c2f2f', - '#b36f14' -]; +import { PLATFORM_WIDHT, PLATFORM_HEIGHT, PLAT_TYPE, PLATFORMS_GAP, GAME_COLORS } from './constants.js'; -function createPlatform(x, y, elevation, width = 70) { +function drawBasePlatform(platform) { + fill(platform.color); + stroke(0); + strokeWeight(1); + rect(0, 0, platform.w, platform.h, 15); +} + +function drawSpringPlatform() { + drawBasePlatform(this); + + fill(0); + noStroke(); + textAlign(CENTER, CENTER); + textSize(15); + //textStyle(BOLD); + text('⮝ ⮝ ⮝', 0, 2); + textStyle(NORMAL); +} + +function drawOneTimePlatform() { + drawBasePlatform(this); + + stroke(0); + strokeWeight(1.1); + noFill(); + + const drawCrack = (offsetX) => { + beginShape(); + vertex(offsetX, -this.h * 0.45); + vertex(offsetX - this.w * 0.08, -this.h * 0.1); + vertex(offsetX + this.w * 0.08, this.h * 0.2); + vertex(offsetX, this.h * 0.45); + endShape(); + }; + + drawCrack(-this.w * 0.25); + drawCrack(0); + drawCrack(this.w * 0.25); +} + +function addMovingBehavior(platform) { + platform.direction = random() < 0.5 ? -1 : 1; + platform.speed = random(1, 2); + + platform.move = function () { + this.x += this.direction * this.speed; + + if (this.x < this.w / 2 || this.x > width - this.w / 2) { + this.direction *= -1; + } + }; +} + + + +function addTypeSpecifics(platform, type) { + switch (platform.type) { + case PLAT_TYPE.MOVING: + platform.color = GAME_COLORS.movingPlat; + platform.draw = function () { + drawBasePlatform(this); + }; + addMovingBehavior(platform); + break; + + case PLAT_TYPE.SPRING: + platform.color = GAME_COLORS.springPlat; + platform.draw = drawSpringPlatform; + break; + + case PLAT_TYPE.ONE_TIME: + platform.color = GAME_COLORS.oneTimePlat; + platform.draw = drawOneTimePlatform; + break; + + default: + platform.color = GAME_COLORS.basicPlat; + platform.draw = function () { + drawBasePlatform(this); + }; + break; + } +} + +function selectPlatformType(elevation) { + const r = random(); + switch (true) { + case elevation >= 0 && r < 0.15: + return PLAT_TYPE.ONE_TIME; + case elevation >= 0 && r < 0.30: + return PLAT_TYPE.MOVING; + case elevation >= 0 && r < 0.45: + return PLAT_TYPE.SPRING; + default: + return PLAT_TYPE.BASIC; + } +} + +function createPlatform(x, y, elevation, type, startingPlatform = false) { const platform = new Sprite(); + platform.x = x; platform.y = y; platform.elevation = elevation; - platform.w = width; - platform.h = 15; + + platform.w = startingPlatform ? width - 10 : PLATFORM_WIDHT; + platform.h = PLATFORM_HEIGHT; + platform.collider = 'static'; platform.bounciness = 0; - platform.color = random(PLATFORM_COLORS); - platform.draw = function () { - fill(this.color); - stroke(0); - strokeWeight(1); - rect(0, 0, this.w, this.h, 15); - }; - /* platform debug TODO remove - platform.draw = function() { - fill(200); - rect(0, 0, this.w, this.h); - fill(0); - textAlign(CENTER, CENTER); - text(this.elevation, this.w / 2, this.h / 2); - }; - */ + platform.type = type; + + addTypeSpecifics(platform, type); + return platform; } function generateNewPlatforms(platforms, currentHighestPlat) { - let spawnY = currentHighestPlat.y - PLATFROMS_GAP; + let spawnY = currentHighestPlat.y - PLATFORMS_GAP; let i = 0; while (spawnY > 0) { i++; + const elevation = currentHighestPlat.elevation + i * PLATFORMS_GAP; const newPlat = createPlatform( - random(40, width - 40), + random(PLATFORM_WIDHT / 2, width - PLATFORM_WIDHT / 2), spawnY, - currentHighestPlat.elevation + i * PLATFROMS_GAP + elevation, + selectPlatformType(elevation), ); platforms.add(newPlat); - spawnY -= PLATFROMS_GAP; + spawnY -= PLATFORMS_GAP; } - platforms.bounciness = 0; // needed becouse bug in p5.play that rests bounciness + platforms.bounciness = 0; + return platforms; } @@ -71,16 +155,18 @@ export function moveWorld(platforms, elevation, move) { if (highestPlat.y > 0) { platforms = generateNewPlatforms(platforms, highestPlat); - } + } return platforms; } export function initPlatforms() { let platforms = new Group(); - const basePlatform = createPlatform(width / 2, height - 10, 0, width); + const basePlatform = createPlatform(width / 2, height - 10, 0, PLAT_TYPE.BASIC, true); + basePlatform.color = GAME_COLORS.startingPlat; platforms.add(basePlatform); generateNewPlatforms(platforms, basePlatform); return platforms; } +