add platform types

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-28 22:25:20 +09:00
parent 81a5d890ec
commit 7a0bca9938
7 changed files with 201 additions and 60 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

BIN
public/assets/nubzuki.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

22
src/game/constants.js Normal file
View File

@@ -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'
};

View File

@@ -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 // Game state
let player; let player;
let platform;
let platforms; let platforms;
let pendingWorldMove = 0; let pendingWorldMove = 0;
import { updatePlayerPosition } from './gameUtils.js';
import { initPlatforms, moveWorld, PLATFROMS_GAP } from './platforms.js';
function createPlayer() { function createPlayer() {
player = new Sprite(); player = new Sprite();
player.diameter = 100;
player.scale = 0.3;
player.x = width / 2; player.x = width / 2;
player.y = 700; 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.bounciness = 0;
player.elevation = 0; player.elevation = 0;
return player; return player;
} }
export function initializeGame() { export function initializeGame() {
world.debug = true; //TODO remove //world.debug = true; //TODO remove
//allSprites.debug = true; //TODO remove
world.gravity.y = 10; world.gravity.y = 10;
platforms = initPlatforms(); platforms = initPlatforms();
player = createPlayer(); player = createPlayer();
@@ -27,17 +38,19 @@ export function initializeGame() {
export function updateGame() { export function updateGame() {
clear(); clear();
background(200); background(GAME_COLORS.background);
pendingWorldMove += updatePlayerPosition(player, platforms); pendingWorldMove += updatePlayerPosition(player, platforms);
if (pendingWorldMove > PLATFROMS_GAP) {
if (pendingWorldMove > PLATFORMS_GAP) {
const move = Math.min(pendingWorldMove, 5); const move = Math.min(pendingWorldMove, 5);
pendingWorldMove -= move; pendingWorldMove -= move;
platforms = moveWorld(platforms, player.elevation, move); platforms = moveWorld(platforms, player.elevation, move);
player.y += 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 // UI

View File

@@ -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) { export function updatePlayerPosition(player, platforms) {
let elevationGain = 0;
// Controls // Controls
player.vel.x = 0; player.vel.x = 0;
if (keyIsDown(LEFT_ARROW)) { if (keyIsDown(LEFT_ARROW)) {
@@ -10,7 +35,7 @@ export function updatePlayerPosition(player, platforms) {
player.vel.x = 5; player.vel.x = 5;
} }
// Wrap horizontally around canvas edges // Wrap horizontally
if (player.x > width) { if (player.x > width) {
player.x = 0; player.x = 0;
} else if (player.x < 0) { } else if (player.x < 0) {
@@ -19,7 +44,7 @@ export function updatePlayerPosition(player, platforms) {
// Jumping thrue platforms // Jumping thrue platforms
for (let plat of 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'; plat.collider = 'none';
} else { } else {
plat.collider = 'static'; plat.collider = 'static';
@@ -27,19 +52,14 @@ export function updatePlayerPosition(player, platforms) {
} }
// Automatic jumping // Automatic jumping
if(player.vel.y >= 0) { if (player.vel.y >= 0) {
for (let plat of platforms) { for (let i = 0; i < platforms.length; i++) {
if (player.colliding(plat)) {
player.vel.y = -7.5;
if (player.elevation < plat.elevation) { if (player.colliding(platforms[i])) {
elevationGain = plat.elevation - player.elevation; return handleJump(player, platforms[i]);
player.elevation = plat.elevation;
}
break;
} }
} }
} }
return elevationGain; return 0;
} }

View File

@@ -1,56 +1,140 @@
export const PLATFROMS_GAP = 80; import { PLATFORM_WIDHT, PLATFORM_HEIGHT, PLAT_TYPE, PLATFORMS_GAP, GAME_COLORS } from './constants.js';
const PLATFORM_COLORS = [
'#c44545',
'#c98a1f',
'#1f8f86',
'#2c3e5e',
'#9c2f2f',
'#b36f14'
];
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(); const platform = new Sprite();
platform.x = x; platform.x = x;
platform.y = y; platform.y = y;
platform.elevation = elevation; platform.elevation = elevation;
platform.w = width;
platform.h = 15; platform.w = startingPlatform ? width - 10 : PLATFORM_WIDHT;
platform.h = PLATFORM_HEIGHT;
platform.collider = 'static'; platform.collider = 'static';
platform.bounciness = 0; platform.bounciness = 0;
platform.color = random(PLATFORM_COLORS); platform.type = type;
platform.draw = function () {
fill(this.color); addTypeSpecifics(platform, type);
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);
};
*/
return platform; return platform;
} }
function generateNewPlatforms(platforms, currentHighestPlat) { function generateNewPlatforms(platforms, currentHighestPlat) {
let spawnY = currentHighestPlat.y - PLATFROMS_GAP; let spawnY = currentHighestPlat.y - PLATFORMS_GAP;
let i = 0; let i = 0;
while (spawnY > 0) { while (spawnY > 0) {
i++; i++;
const elevation = currentHighestPlat.elevation + i * PLATFORMS_GAP;
const newPlat = createPlatform( const newPlat = createPlatform(
random(40, width - 40), random(PLATFORM_WIDHT / 2, width - PLATFORM_WIDHT / 2),
spawnY, spawnY,
currentHighestPlat.elevation + i * PLATFROMS_GAP elevation,
selectPlatformType(elevation),
); );
platforms.add(newPlat); 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; return platforms;
} }
@@ -78,9 +162,11 @@ export function moveWorld(platforms, elevation, move) {
export function initPlatforms() { export function initPlatforms() {
let platforms = new Group(); 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); platforms.add(basePlatform);
generateNewPlatforms(platforms, basePlatform); generateNewPlatforms(platforms, basePlatform);
return platforms; return platforms;
} }