added tree, animated character

This commit is contained in:
haerikimmm
2026-05-07 17:46:16 +09:00
parent 1916bcd7c8
commit e4ca52d256
17 changed files with 144 additions and 28 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 KiB

BIN
assets/tree/tree_full_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 KiB

BIN
assets/tree/tree_full_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

BIN
assets/tree/tree_half_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 KiB

BIN
assets/tree/tree_half_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 KiB

BIN
assets/tree/tree_one_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 KiB

View File

@@ -8,6 +8,7 @@
<body> <body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5play@3/p5play.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="src/Player.js"></script> <script src="src/Player.js"></script>

127
sketch.js
View File

@@ -1,18 +1,24 @@
// ====== GLOBALS ======
let trail = []; let trail = [];
let velocities = []; let velocities = [];
let particles = []; let particles = [];
let flashAlpha = 0; let flashAlpha = 0;
let score = 0; let score = 0;
let bgBlue = 0; // 0=dark, 255=blue, fades out let bgBlue = 0;
let treeImgs = {};
let treeHits = 0;
const TREE_COUNT = 8;
let waveTime = 0;
let idleSprite;
let idleAni;
let coconut = { let coconut = {
x: 0, y: 0, // setup()에서 초기화 x: 0, y: 0,
r: 0, r: 0,
state: 0, state: 0,
shakeX: 0, shakeX: 0,
shakeTimer: 0, shakeTimer: 0,
// fly-away
flying: false, flying: false,
flyVX: 0, flyVY: 0, flyVX: 0, flyVY: 0,
flyAlpha: 255, flyAlpha: 255,
@@ -33,12 +39,36 @@ function preload() {
kakomoraImgs[2] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Mickey-Mouse-Edition-1-250x250.png'); kakomoraImgs[2] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Mickey-Mouse-Edition-1-250x250.png');
kakomoraImgs[3] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Seashell-Edition.png'); kakomoraImgs[3] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Seashell-Edition.png');
kakomoraImgs[4] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Starfish-Edition-250x250.png'); kakomoraImgs[4] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Starfish-Edition-250x250.png');
treeImgs.full = [
loadImage('assets/tree/tree_full_1.png'),
loadImage('assets/tree/tree_full_2.png'),
];
treeImgs.half = [
loadImage('assets/tree/tree_half_1.png'),
loadImage('assets/tree/tree_half_2.png'),
];
treeImgs.one = [loadImage('assets/tree/tree_one_1.png')];
treeImgs.empty = [
loadImage('assets/tree/tree_empty_1.png'),
loadImage('assets/tree/tree_empty_2.png'),
loadImage('assets/tree/tree_empty_3.png'),
];
idleAni = loadAni('assets/kakamora-characters/co_ani_1.png', 5);
} }
// ====== SETUP ====== // ====== SETUP ======
function setup() { function setup() {
createCanvas(windowWidth, windowHeight); createCanvas(windowWidth, windowHeight);
resetCoconutHome(); resetCoconutHome();
world.gravity.y = 0;
idleSprite = new Sprite();
idleSprite.addAni('idle', idleAni);
idleSprite.collider = 'none';
idleSprite.visible = false; // p5play auto-draw 비활성 — 수동으로 그림
idleSprite.ani.frameDelay = 8;
} }
function windowResized() { function windowResized() {
@@ -54,9 +84,11 @@ function resetCoconutHome() {
// ====== DRAW ====== // ====== DRAW ======
function draw() { function draw() {
background(lerpColor(color(30), color(25, 90, 200), bgBlue / 255)); background(lerpColor(color(30, 50, 80), color(25, 90, 200), bgBlue / 255));
if (bgBlue > 0) bgBlue = max(0, bgBlue - 4); if (bgBlue > 0) bgBlue = max(0, bgBlue - 4);
drawBackground();
drawTrees();
updateShake(); updateShake();
updateFlyAway(); updateFlyAway();
drawCoconut(); drawCoconut();
@@ -70,6 +102,83 @@ function draw() {
drawFlyingKakamoraList(); drawFlyingKakamoraList();
} }
// ====== BACKGROUND ======
function drawBackground() {
const horizonY = height * 0.60;
const sandY = height * 0.70;
waveTime += 0.016;
noStroke();
// Ocean base
fill(18, 90, 165);
rect(0, horizonY, width, sandY - horizonY);
// Ocean depth gradient (slightly lighter toward shore)
fill(40, 120, 190, 80);
rect(0, (horizonY + sandY) / 2, width, (sandY - horizonY) / 2);
// 3 animated wave layers (far → near)
const waveLayers = [
{ t: 0.18, amp: 3, freq: 0.007, speed: 0.7, alpha: 60, wh: 3 },
{ t: 0.52, amp: 6, freq: 0.009, speed: 1.1, alpha: 100, wh: 5 },
{ t: 0.82, amp: 9, freq: 0.011, speed: 1.6, alpha: 145, wh: 8 },
];
for (let lyr of waveLayers) {
let wy = horizonY + (sandY - horizonY) * lyr.t;
fill(255, 255, 255, lyr.alpha);
beginShape();
vertex(0, wy + lyr.wh);
for (let x = 0; x <= width; x += 8) {
vertex(x, wy + sin(x * lyr.freq + waveTime * lyr.speed) * lyr.amp);
}
vertex(width, wy + lyr.wh);
endShape(CLOSE);
}
// Shore foam
fill(255, 255, 255, 90);
beginShape();
vertex(0, sandY + 6);
for (let x = 0; x <= width; x += 6) {
vertex(x, sandY + sin(x * 0.013 + waveTime * 2.2) * 4);
}
vertex(width, sandY + 6);
endShape(CLOSE);
// Sand
fill(210, 185, 135);
rect(0, sandY, width, height - sandY);
// Wet sand strip at shore
fill(185, 158, 105, 200);
rect(0, sandY, width, 14);
// Sand highlight
fill(235, 215, 165, 50);
rect(0, sandY + 10, width, 35);
}
// ====== TREES ======
function drawTrees() {
imageMode(CENTER);
for (let i = 0; i < TREE_COUNT; i++) {
let stage = constrain(treeHits - i * 3, 0, 3);
let img;
if (stage === 0) img = treeImgs.full[i % treeImgs.full.length];
else if (stage === 1) img = treeImgs.half[i % treeImgs.half.length];
else if (stage === 2) img = treeImgs.one[0];
else img = treeImgs.empty[i % treeImgs.empty.length];
let x = ((i + 0.5) / TREE_COUNT) * width;
let h = height * (0.30 + (i % 3) * 0.02);
let w = h * (img.width / img.height);
let groundY = height * 0.82;
let cy = groundY - h / 2;
image(img, x, cy, w, h);
}
}
// ====== COCONUT ====== // ====== COCONUT ======
function drawCoconut() { function drawCoconut() {
imageMode(CENTER); imageMode(CENTER);
@@ -81,6 +190,11 @@ function drawCoconut() {
image(coconutImgs[coconut.state], 0, 0, coconut.r * 2, coconut.r * 2); image(coconutImgs[coconut.state], 0, 0, coconut.r * 2, coconut.r * 2);
noTint(); noTint();
pop(); pop();
} else if (coconut.state === 0) {
// idle: p5play 애니메이션 현재 프레임을 수동 렌더링
let frame = idleSprite && idleSprite.ani ? idleSprite.ani.src : null;
let img = frame || coconutImgs[0];
image(img, coconut.x + coconut.shakeX, coconut.y, coconut.r * 2, coconut.r * 2);
} else { } else {
image(coconutImgs[coconut.state], coconut.x + coconut.shakeX, coconut.y, coconut.r * 2, coconut.r * 2); image(coconutImgs[coconut.state], coconut.x + coconut.shakeX, coconut.y, coconut.r * 2, coconut.r * 2);
} }
@@ -107,6 +221,7 @@ function updateFlyAway() {
if (coconut.flyAlpha <= 0 || coconut.y > height + 100) { if (coconut.flyAlpha <= 0 || coconut.y > height + 100) {
if (score < 10) launchKakamoraToSlot(score); if (score < 10) launchKakamoraToSlot(score);
score++; score++;
treeHits++;
coconut.x = width / 2; coconut.x = width / 2;
coconut.y = height * 0.42; coconut.y = height * 0.42;
coconut.state = 0; coconut.state = 0;
@@ -171,7 +286,7 @@ function drawTrail() {
let speed = velocities[i] || 0; let speed = velocities[i] || 0;
strokeWeight(map(speed, 0, 50, 1, 8)); strokeWeight(map(speed, 0, 50, 1, 8));
stroke(255, 200); stroke(255, 200);
line(trail[i-1].x, trail[i-1].y, trail[i].x, trail[i].y); line(trail[i - 1].x, trail[i - 1].y, trail[i].x, trail[i].y);
} }
} }