summaryrefslogtreecommitdiff
path: root/2026/games_submissions/astatinchan/index.js
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-08-17 20:14:16 -0400
committerLLLL Colonq <llll@colonq>2026-08-17 20:14:16 -0400
commitde99c5f7636a952025ea13de02bafd25bcb6bdec (patch)
treebe359424af4f6717103e3b667b6529ae5a4b4e6a /2026/games_submissions/astatinchan/index.js
parent4d4d1f24721f27fbf37e1070be6414de130ace61 (diff)
Fix broken
Diffstat (limited to '2026/games_submissions/astatinchan/index.js')
-rw-r--r--2026/games_submissions/astatinchan/index.js362
1 files changed, 362 insertions, 0 deletions
diff --git a/2026/games_submissions/astatinchan/index.js b/2026/games_submissions/astatinchan/index.js
new file mode 100644
index 0000000..aee6e5a
--- /dev/null
+++ b/2026/games_submissions/astatinchan/index.js
@@ -0,0 +1,362 @@
+var canvas = document.getElementById("game");
+var globalCtx = canvas.getContext("2d");
+
+const STATE_NOT_STARTED = 4;
+const STATE_AIMING = 0;
+const STATE_JUMPING = 1;
+const STATE_WIN = 2;
+const STATE_LOOSE = 3;
+
+const gravity = 1;
+const jumpingSpeed = 13;
+
+const ground = 136;
+const bunnySize = 20;
+
+let imageLoaded = 0;
+let imagesCount = 0;
+const images = {};
+var gameFrame,
+ losecount,
+ arrowAngle,
+ arrowSpeed,
+ bunnyPositionX,
+ bunnyPositionY,
+ bunnyJumpFramesCount,
+ binHeight,
+ bunnyVelocityX,
+ bunnyVelocityY,
+ isOverBin,
+ isIn,
+ endFrames;
+
+var gameState = STATE_NOT_STARTED;
+
+function init(difficulty) {
+ gameFrame = 0;
+ losecount = 0;
+
+ arrowAngle = 0;
+ arrowSpeed = 4;
+
+ bunnyPositionX = 174;
+ bunnyPositionY = ground;
+ bunnyJumpFramesCount = 0;
+
+ level1 = [55, 20, 20, 60, 35];
+ level2 = [15, 25, 30, 40, 50];
+ level3 = [30, 45, 65, 70, 75];
+ level4 = [70, 75, 77, 65, 45];
+ randomness = Math.floor(Math.random() * 5);
+ if (difficulty < 5) {
+ binHeight = level1[randomness];
+ } else if (difficulty < 30) {
+ binHeight = level2[randomness];
+ } else if (difficulty < 50) {
+ binHeight = level3[randomness];
+ } else {
+ binHeight = level4[randomness];
+ }
+
+ gameState = STATE_AIMING;
+
+ bunnyVelocityX = 0;
+ bunnyVelocityY = 0;
+
+ isOverBin = false;
+ isIn = false;
+ endFrames = 30;
+ window.parent.postMessage({ op: "started", verb: "jump!" });
+ document.addEventListener("click", mouseClick);
+}
+
+function loadSprites(callback) {
+ function imageLoadedListener() {
+ imageLoaded += 1;
+ if (imageLoaded == imagesCount) {
+ callback();
+ }
+ }
+ function addImg(key, src) {
+ imagesCount += 1;
+ images[key] = new Image();
+ images[key].src = src;
+ images[key].addEventListener("load", imageLoadedListener);
+ }
+ addImg("bunny1", "./sprites/bunny1.png");
+ addImg("bunny2", "./sprites/bunny2.png");
+ addImg("bunny3", "./sprites/bunny3.png");
+ addImg("bunny4", "./sprites/bunny4.png");
+ addImg("bunnysad", "./sprites/bunnysad.png");
+
+ addImg("bintop", "./sprites/bin-top.png");
+ addImg("binpattern", "./sprites/bin-pattern.png");
+
+ addImg("bg", "./sprites/background.png");
+ addImg("fg", "./sprites/foreground.png");
+
+ addImg("carrot1", "./sprites/carrot1.png");
+ addImg("carrot2", "./sprites/carrot2.png");
+ addImg("carrot3", "./sprites/carrot3.png");
+ addImg("carrot4", "./sprites/carrot4.png");
+ addImg("carrot5", "./sprites/carrot5.png");
+ addImg("carrot6", "./sprites/carrot6.png");
+ addImg("carrot7", "./sprites/carrot7.png");
+ addImg("carrot8", "./sprites/carrot8.png");
+ addImg("carrot9", "./sprites/carrot9.png");
+
+ addImg("jump1", "./sprites/jump-text1.png");
+ addImg("jump2", "./sprites/jump-text2.png");
+ addImg("jump3", "./sprites/jump-text3.png");
+ addImg("jump4", "./sprites/jump-text4.png");
+ addImg("jump5", "./sprites/jump-text5.png");
+ addImg("toobad", "./sprites/toobad.png");
+ addImg("nice", "./sprites/nice.png");
+}
+
+function drawBnuy(ctx) {
+ ctx.fillStyle = "#081820";
+ let bunnySprite = images.bunny1;
+
+ if (gameState == STATE_LOOSE) {
+ bunnySprite = images.bunnysad;
+ } else if (bunnyJumpFramesCount != 0 && bunnyJumpFramesCount < 5) {
+ bunnySprite = images.bunny2;
+ } else if (bunnyVelocityY > 0) {
+ bunnySprite = images.bunny3;
+ } else if (bunnyVelocityY < 0) {
+ bunnySprite = images.bunny4;
+ }
+ ctx.drawImage(bunnySprite, bunnyPositionX - 36 / 2, bunnyPositionY - 48);
+}
+
+// always top to bottom
+function drawVerticalLine(ctx, fromX, fromY, toX, toY, color) {
+ ctx.fillStyle = color;
+ for (let i = 0; i < toY - fromY; i++) {
+ x = (i * (toX - fromX)) / (toY - fromY) + fromX;
+ ctx.fillRect(Math.round(x), Math.round(i + fromY), 1, 1);
+ }
+}
+
+function drawBin(ctx, height) {
+ ctx.fillStyle = "#a6859f";
+ ctx.fillRect(49, ground - 2, 47, 1);
+ ctx.fillStyle = "#1f102a";
+ ctx.fillRect(49, ground - 1, 47, 1);
+ drawVerticalLine(
+ ctx,
+ 72 - 56 / 2,
+ ground - height,
+ 72 - 46 / 2,
+ ground - 1,
+ "#a6859f",
+ );
+ drawVerticalLine(
+ ctx,
+ 71 + 56 / 2,
+ ground - height,
+ 71 + 46 / 2,
+ ground - 1,
+ "#a6859f",
+ );
+ drawVerticalLine(
+ ctx,
+ 72 - 58 / 2,
+ ground - height,
+ 72 - 48 / 2,
+ ground - 1,
+ "#1f102a",
+ );
+ drawVerticalLine(
+ ctx,
+ 71 + 58 / 2,
+ ground - height,
+ 71 + 48 / 2,
+ ground - 1,
+ "#1f102a",
+ );
+
+ const insideBin = new Path2D();
+ insideBin.moveTo(72 - 56 / 2, ground - height);
+ insideBin.lineTo(72 - 46 / 2, ground - 1);
+ insideBin.lineTo(72 + 46 / 2, ground - 1);
+ insideBin.lineTo(72 + 56 / 2, ground - height);
+ insideBin.closePath;
+ ctx.fillStyle = ctx.createPattern(images.binpattern, "repeat");
+ ctx.fill(insideBin);
+
+ ctx.drawImage(images.bintop, 72 - 58 / 2, ground - height);
+ // ctx.fillRect(48, ground - height, 1, height);
+ // ctx.fillRect(95, ground - height, 1, height);
+}
+
+function drawBg(ctx) {
+ ctx.drawImage(images.bg, 0, 0);
+}
+
+function drawFg(ctx) {
+ ctx.drawImage(images.fg, 0, 0);
+}
+
+function drawJumpText(ctx) {
+ const startsAfter = 5;
+ const endsAfter = 60;
+ const fadeoutTime = 5;
+ if (gameState == STATE_WIN) {
+ ctx.drawImage(images.nice, 78, 10);
+ } else if (gameState == STATE_LOOSE) {
+ ctx.drawImage(images.toobad, 42, 10);
+ } else if (gameFrame >= startsAfter && gameFrame < endsAfter) {
+ const jumpTextNum = Math.min(
+ 5,
+ Math.floor((gameFrame - startsAfter) / 2) + 1,
+ );
+
+ if (gameFrame > endsAfter - fadeoutTime) {
+ ctx.globalAlpha =
+ 1 - (gameFrame - (endsAfter - fadeoutTime)) / fadeoutTime;
+ }
+ ctx.drawImage(images["jump" + jumpTextNum], 68, 10);
+ ctx.globalAlpha = 1;
+ }
+}
+
+// angle can be 0 and 90
+function drawArrow(ctx, angle) {
+ const arrowSize = 24;
+ const bunnyCenterOffset = 35;
+ const angleRadiant = (angle * Math.PI) / 180;
+ const bunnyCenterOffsetX = Math.round(
+ Math.cos(angleRadiant) * bunnyCenterOffset,
+ );
+ const bunnyCenterOffsetY = Math.round(
+ Math.sin(angleRadiant) * bunnyCenterOffset,
+ );
+
+ const carrot_img_nb = Math.min(Math.round((9 * angle) / 90) + 1, 9);
+ ctx.drawImage(
+ images["carrot" + carrot_img_nb],
+ bunnyPositionX - bunnyCenterOffsetX - arrowSize / 2,
+ bunnyPositionY - 12 - bunnySize / 2 - bunnyCenterOffsetY - arrowSize / 2,
+ );
+}
+
+function rotateAimingArrow() {
+ arrowAngle += arrowSpeed;
+ if (arrowAngle >= 90) {
+ arrowAngle = 90;
+ arrowSpeed *= -1;
+ } else if (arrowAngle <= 0) {
+ arrowAngle = 0;
+ arrowSpeed *= -1;
+ }
+}
+
+function moveBunny() {
+ bunnyPositionX -= Math.round(bunnyVelocityX);
+ bunnyPositionY -= Math.round(bunnyVelocityY);
+ bunnyVelocityY -= gravity;
+ if (bunnyPositionY >= ground) {
+ bunnyPositionY = ground;
+ bunnyVelocityX /= 2;
+ bunnyVelocityY = 0;
+ }
+ if (
+ bunnyPositionX > 48 - bunnySize / 2 &&
+ bunnyPositionX < 96 + bunnySize / 2
+ ) {
+ if (bunnyPositionY < ground - binHeight) {
+ isOverBin = true;
+ } else if (bunnyPositionY > ground - binHeight) {
+ if (!isOverBin) {
+ bunnyVelocityX *= -0.5;
+ bunnyPositionX = Math.ceil(97 + bunnySize / 2);
+ } else if (
+ bunnyPositionX < 48 + bunnySize / 2 ||
+ bunnyPositionX > 96 - bunnySize / 2
+ ) {
+ binBorderHeight =
+ ground - (Math.abs(bunnyPositionX - 72) / 42) * binHeight;
+ if (bunnyPositionY >= binBorderHeight) {
+ bunnyVelocityY = 0;
+ bunnyPositionY = binBorderHeight;
+ bunnyVelocityX =
+ bunnyVelocityX * 0.3 + Math.sign(bunnyPositionX - 72) * 1.5;
+ }
+ } else {
+ isIn = true;
+ if (bunnyPositionY == ground) {
+ bunnyVelocityX = 0;
+ gameState = STATE_WIN;
+ }
+ }
+ }
+ } else {
+ isOverBin = false;
+ }
+
+ if (
+ bunnyPositionY == ground &&
+ bunnyVelocityY == 0 &&
+ bunnyVelocityX < 0.1 &&
+ gameState == STATE_JUMPING
+ ) {
+ losecount += 1;
+ if (losecount > 10) {
+ gameState = STATE_LOOSE;
+ bunnyVelocityX = 0;
+ }
+ }
+}
+
+function drawFrame(ctx) {
+ // Logic
+ if (gameState == STATE_AIMING) {
+ rotateAimingArrow();
+ bunnyJumpFramesCount = 0;
+ }
+ if (gameState == STATE_JUMPING) {
+ moveBunny();
+ bunnyJumpFramesCount += 1;
+ }
+ if (gameState == STATE_WIN || gameState == STATE_LOOSE) {
+ endFrames -= 1;
+ if (endFrames == 0) {
+ window.parent.postMessage({ op: "done", win: gameState == STATE_WIN });
+ document.removeEventListener("click", mouseClick);
+ }
+ }
+
+ // Drawing
+ drawBg(ctx);
+ drawJumpText(ctx);
+ drawBnuy(ctx);
+ drawBin(ctx, binHeight);
+ drawFg(ctx);
+ if (gameState == STATE_AIMING) {
+ drawArrow(ctx, arrowAngle);
+ }
+ gameFrame += 1;
+}
+
+function mouseClick() {
+ if (gameState == STATE_AIMING) {
+ gameState = STATE_JUMPING;
+
+ const angleRadiant = (arrowAngle * Math.PI) / 180;
+ bunnyVelocityX = Math.round(Math.cos(angleRadiant) * jumpingSpeed);
+ bunnyVelocityY = Math.round(Math.sin(angleRadiant) * jumpingSpeed);
+ }
+}
+
+// init(0);
+loadSprites(() => {
+ window.parent.postMessage({ op: "ready" });
+ setInterval(() => drawFrame(globalCtx), 1000 / 30);
+ window.addEventListener("message", (ev) => {
+ if (ev.data.op == "start") {
+ init(ev.data.difficulty || 0);
+ }
+ });
+});