From de99c5f7636a952025ea13de02bafd25bcb6bdec Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Mon, 17 Aug 2026 20:14:16 -0400 Subject: Fix broken --- 2026/games_submissions/astatinchan/index.js | 362 ++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 2026/games_submissions/astatinchan/index.js (limited to '2026/games_submissions/astatinchan/index.js') 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); + } + }); +}); -- cgit v1.3.1