Giter VIP home page Giter VIP logo

spade's Introduction

NOTE - This repo has been deprecated. Please refer to https://github.com/hackclub/sprig for the latest version of the Spade firmware.

Spade - an implementation of Sprig engine

This repo is a C implementation of the Sprig engine you can find in the "engine" folder of the repo hackclub/sprig.

We reimplemented the engine in C to run on the Raspberry Pi Pico powering the Sprig hardware.

However, on-device debugging is hard, so the engine can also be compiled to run on your computer and render to a minifb window.

Building

Using Docker

Prerequisites:

  • Working Linux/MacOS system with Docker environment
  • Dependencies commands:
    • docker
    • chcon (Linux only)

Building

  • Clone the repository
  • Change into the spade directory and change code as desired
  • Run build-with-docker.sh

this will produce the ./spade.uf2 file which you can flash to your sprig.

Manual

Prerequisites:

  • A working Python 3 environment.
  • The ability to run Bash scripts.
  • A C build environment, preferably Clang. On Windows, GCC won't work and you must use Clang. Make sure CMake and Make are both working.
  • Entr and uglifyjs installed to use jsdev.sh.

Set up your build environment. All folders need to be in your home directory (for now), although they can be symlinked if you prefer.

Clone Spade:

cd ~
git clone https://github.com/hackclub/spade.git
cd spade

Install JerryScript:

mkdir ~/jerryscript_build
cd ~/jerryscript_build
git clone https://github.com/jerryscript-project/jerryscript.git
cd jerryscript
git checkout 8ba0d1b6ee5a065a42f3b306771ad8e3c0d819bc # version 2.4.0

cd ~/spade
./src/pc/jerry/refresh.sh

Download the Pico SDK:

mkdir ~/raspberrypi
cd ~/raspberrypi
git clone -b 1.3.1 https://github.com/raspberrypi/pico-sdk.git
git clone https://github.com/raspberrypi/pico-extras.git
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init

Engine CStrings

For compiling on both PC and Pico you'll need to convert engine.js to a .cstring file (a custom format that lets us easily embed strings in our code). Make sure to create a game.js file as well (touch game.js), even though it is only used for the desktop build.

Run ./tools/jsdev.sh to minify and update the engine. Keep it running to auto-update.

Pico Build

cmake --preset=rpi
# then...
cmake --build --preset=rpi

A UF2 file will be outputted to rpi_build/src/spade.uf2. On macOS, with a Pico plugged in and in BOOTSEL mode, you can transfer from the CLI with cp ./rpi_build/src/spade.uf2 /Volumes/RPI-RP2.

PC Build

cmake --preset=pc
# then...
cmake --build --preset=pc
./pc_build/src/spade ./game.min.js

The audio emulator is written for CoreAudio and audio will be muted on non-macOS systems.

If you get an error about a missing Pico SDK, run the following and try again:

export PICO_SDK_PATH=~/raspberrypi/pico-sdk
export PICO_EXTRAS_PATH=~/raspberrypi/pico-extras

Project Structure

Spade uses CMake to build its binaries across platforms, although it's only tested to work on macOS.

Shared code, including rendering, JavaScript execution, and Sprig engine code is available in src/shared/. The platform-specific harness code for the PC and Pico editions are in src/pc/ and src/rpi/, respectively.

Files in these folders are mixed header and C files. The header files (should) provide definitions for functions and globals, while the C files actually define the functions. All of the required C files are included in src/pc/main.c and src/rpi/main.c so that all the required function definitions are built, and then all other code can reference them with headers (jumbo builds).

The shared code is generally split into four parts with associated folders:

  • Audio: code for parsing tune text and synthesizing sound.
  • JS Runtime: our wrapper around JerryScript, including event handling.
  • Sprig Engine: the native implementation of the Sprig engine functions.
  • UI: some shared helpers, like Sprig's 8-bit font and errorbuf (a shared global buffer for rendering error information and diagnostic text).

The code in this repo can be uncommented or chaotic in some locations. Make a GitHub Issue or ask on the Hack Club Slack if you have any questions about anything!

spade's People

Contributors

agentblack6000 avatar cedric-h avatar grymmy avatar josiasaurel avatar kcoderhtml avatar kognise avatar leomcelroy avatar shanecelis avatar sheepy3 avatar snoglobe avatar whatwareweb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spade's Issues

PC Build crashes when run

After compiling a PC build on both Linux (Fedora 38) spade crashes immediately after creating the window with the following error:

bouta run some code
engine.js:afterInputs
Fatal glibc error: malloc.c:2593 (sysmalloc): assertion failed: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)
Aborted (core dumped)

On MacOS, it also hangs after creating the window (@grymmy), but no logs after bouta run some code

Simplify spade firmware build process via containerization

There are too many eccentricities to the spade build instructions that make them difficult to complete successfully. We should set up a simple dockerfile that contains all prerequisites built-in for the build process such that they can be run easily on any platform. A simple script could be created to "run the build within docker".

make it easier to get spade firmware builds

Create a workflow for automatically building spade firmware.

Thoroughly tested firmware builds will be published to github releases for easy access.

We also need to update links in sprig UPLOAD.md to point to the latest github release of hackclub/spade.

bug: high game size and low battery voltages cause freeze

When I have non-full batteries and run a large game on my sprig via battery power, it consistently freezes. However, if I plug the sprig in via USB, it works flawlessly.

The game that is currently crashing my sprig is attached below:

let entries=[{name:"4_Colour_Drawing",by:"Unknown",code:'const L="u",t="b",e="d",i="l",r="w";setLegend([L,bitmap`\n.....000000.....\n.....000000.....\n.....000000.....\n.....000000.....\n.....000000.....\n.....000000.....\n22222......LLLLL\n22222......LLLLL\n22222......LLLLL\n22222......LLLLL\n22222......LLLLL\n.....111111.....\n.....111111.....\n.....111111.....\n.....111111.....\n.....111111.....`],[t,bitmap`\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000`],[e,bitmap`\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL`],[i,bitmap`\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111`],[r,bitmap`\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222\n2222222222222222`]),setSolids([]);let s=0;const p=[map`\n....................\n....................\n....................\n....................\n....................\n....................\n....................\n....................\n..........u.........\n....................\n....................\n....................\n....................\n....................\n....................\n....................\n....................\n....................`];setBackground(t),setMap(p[s]),setPushables({[L]:[]}),onInput("w",(()=>{getFirst(L).y-=1})),onInput("s",(()=>{getFirst(L).y+=1})),onInput("a",(()=>{getFirst(L).x-=1})),onInput("d",(()=>{getFirst(L).x+=1}));let a=getFirst(L).x,d=getFirst(L).y;onInput("i",(()=>{let e=getFirst(L).x,i=getFirst(L).y;clearTile(e,i),addSprite(e,i,t),addSprite(e,i,L)})),onInput("j",(()=>{let t=getFirst(L).x,e=getFirst(L).y;clearTile(t,e),addSprite(t,e,r),addSprite(t,e,L)})),onInput("k",(()=>{let t=getFirst(L).x,i=getFirst(L).y;clearTile(t,i),addSprite(t,i,e),addSprite(t,i,L)})),onInput("l",(()=>{let t=getFirst(L).x,e=getFirst(L).y;clearTile(t,e),addSprite(t,e,i),addSprite(t,e,L)}));'},{name:"Amazing_Mazes",by:"Unknown",code:'const c="p",C="c",t="e",e="b",p=tune`\n112.78195488721805: E4-112.78195488721805 + G4-112.78195488721805,\n112.78195488721805,\n112.78195488721805: C5-112.78195488721805 + E5-112.78195488721805,\n112.78195488721805: G4-112.78195488721805 + B4-112.78195488721805,\n112.78195488721805: C5-112.78195488721805 + E5-112.78195488721805,\n112.78195488721805: E5-112.78195488721805 + G5-112.78195488721805,\n112.78195488721805,\n112.78195488721805: C5-112.78195488721805 + E5-112.78195488721805,\n112.78195488721805,\n112.78195488721805: G4-112.78195488721805 + B4-112.78195488721805,\n112.78195488721805,\n112.78195488721805: E5-112.78195488721805 + G5-112.78195488721805,\n112.78195488721805: B4-112.78195488721805 + D5-112.78195488721805,\n112.78195488721805: E5-112.78195488721805 + G5-112.78195488721805,\n112.78195488721805: G5-112.78195488721805 + B5-112.78195488721805,\n112.78195488721805,\n112.78195488721805: E5-112.78195488721805 + G5-112.78195488721805,\n112.78195488721805,\n112.78195488721805: C4-112.78195488721805 + E4-112.78195488721805,\n112.78195488721805,\n112.78195488721805: A4-112.78195488721805 + C5-112.78195488721805,\n112.78195488721805: G4-112.78195488721805 + E4-112.78195488721805,\n112.78195488721805: A4-112.78195488721805 + C5-112.78195488721805,\n112.78195488721805: C5-112.78195488721805 + E5-112.78195488721805,\n112.78195488721805: B4-112.78195488721805 + D5-112.78195488721805 + G5-112.78195488721805 + B5-112.78195488721805,\n112.78195488721805: A4-112.78195488721805 + C5-112.78195488721805 + F5-112.78195488721805 + A5-112.78195488721805,\n112.78195488721805: G5-112.78195488721805 + E5-112.78195488721805 + B4-112.78195488721805 + G4-112.78195488721805 + B5-112.78195488721805,\n112.78195488721805: F5-112.78195488721805 + D5-112.78195488721805 + A4-112.78195488721805 + F4-112.78195488721805 + A5-112.78195488721805,\n112.78195488721805: E5-112.78195488721805 + C5-112.78195488721805 + G4-112.78195488721805 + E4-112.78195488721805 + G5-112.78195488721805,\n112.78195488721805: D5-112.78195488721805 + B4-112.78195488721805 + F4-112.78195488721805 + D4-112.78195488721805 + F5-112.78195488721805,\n112.78195488721805: C5-112.78195488721805 + A4-112.78195488721805 + E4-112.78195488721805 + C4-112.78195488721805 + E5-112.78195488721805,\n112.78195488721805: D5-112.78195488721805 + B4-112.78195488721805 + G4-112.78195488721805 + D4-112.78195488721805`,n=tune`\n37.5: B4-37.5,\n37.5: D5-37.5,\n37.5: G4-37.5,\n1087.5`;setLegend([c,bitmap`\n..000000000000..\n..000000000000..\n0066666666666600\n0066006666006600\n0066006666006600\n0066006666006600\n0066006666006600\n0066666666666600\n0066666666666600\n0066666666666600\n0060666666660600\n0060066666600600\n0066000000006600\n0066666666666600\n..000000000000..\n..000000000000..`],[C,bitmap`\n3333303333303333\n3333303333303333\n0000000000000000\n3303333303333303\n3303333303333303\n0000000000000000\n3333303333303333\n3333303333303333\n0000000000000000\n3303333303333303\n3303333303333303\n0000000000000000\n3333303333303333\n3333303333303333\n0000000000000000\n3303333333303333`],[t,bitmap`\nCC000222000222..\nCC000222000222..\nCC000222000222..\nCC222000222000..\nCC222000222000..\nCC222000222000..\nCC000222000222..\nCC000222000222..\nCC000222000222..\nCC..............\nCC..............\nCC..............\nCC..............\nCC..............\nCC..............\nCC..............`],[e,bitmap`\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111\n1111111111111111`]),setSolids([c,C]);let a=0;const s=[map`\ncpcccccccc\nc....c...c\nc.cccc.c.c\nc......c.c\nc.c.cccc.c\nc.c.ccc..c\nc.c...c.cc\nc.ccc.c..c\nc...c.cc.c\nccccccccec`,map`\ncccccccpccccccc\nc.....c.......c\nc.ccc.ccccccc.c\nc.c.c.c.....c.c\nc.c.c.c.ccc.c.c\nc.c.c.c.c.....c\nc.c.ccc.ccccccc\nc.c...........c\nc.ccc.ccccccc.c\nc.....c.....c.c\nc.ccccc.c.c.c.c\nc.c.....c.c.c.c\nc.ccc.ccccc.c.c\nc...c...c.....c\nccccccceccccccc`,map`\nccccccccccpccccccccc\nc...c....c.........c\nc.c.c.cc.ccccccccc.c\nc.c.c.c.....c....c.c\nc.c.c.c.c.c.c.cccc.c\nc.c.c.c.c.c.c......c\nc.c...c.c.c.c.cccccc\nc.ccccc.c.c...c....c\nc.....c.c.ccc.cccc.c\nc.ccc.c.c...c......c\nc.c...c.ccc.cccccc.c\nc.c.c.c...c......c.c\nc.c.ccccc.cc.c.c.c.c\nc.c.c...c..c.c.c.c.c\nc.c...c.cccccc.c.c.c\nc.ccc.c.c....c.c.c.c\nc.....c.cccc.c.c.c.c\nccccccc.cccc.c.c.c.c\nc..........c.c.c...c\ncccccccccceccccccccc`,map`\ncccccccccccccccccccc\nc........c.........c\nc.cccc.cccccc.cccc.c\nc.c....c......cccc.c\nc.c.cc.ccccccccccc.c\nc.c.c...c.ccc.cccc.c\nc.c.c.c.c.....cccc.c\nc.c.c.ccccccc.cccc.c\nc.c.c.........cccc.c\nc.c.ccccccccc.cccc.c\nc.c...c.......cccc.c\nc.ccccccccccc.cccc.c\nc.c.........c.cccc.c\nc.c.ccc.c.c.c.cccc.c\nc.c...c.c.c.c......c\ne.c.c.c.c.c.cccccc.c\nc.c.c.c.c.c........c\nc.c.ccc.c.cccccccc.c\nc.c.....c..........p\ncccccccccccccccccccc`,map`\ncccccccccccccccccccc\nc...c....c.........c\nc.c.c.cc.ccccccccc.c\nc.c.c.c.....c....c.c\nc.c.c.c.c.c.c.cccc.c\nc.c.c.c.c.c.c......p\nc.c...c.c.c.c.cccccc\nc.ccccc.c.c...c....c\nc.....c.c.ccc.cccc.c\nc.ccc.c.c...c......c\nc.c...c.ccc.cccccc.c\nc.c.c.c...c......c.c\nc.c.ccccc.cc.c.c.c.c\nc.c.c...c..c.c.c.c.c\nc.c...c.cc.ccc.c.c.c\nc.ccc.c.c....c.c.c.c\nc.....c.cccc.c.c.c.c\nccccccc.cccc.c.c.c.c\nc........c...c.c...c\ncccccccccceccccccccc`];setBackground(e),setMap(s[a]),setPushables({[c]:[]}),onInput("w",(()=>{getFirst(c).y+=-1,playTune(n)})),onInput("a",(()=>{getFirst(c).x+=-1,playTune(n)})),onInput("s",(()=>{getFirst(c).y+=1,playTune(n)})),onInput("d",(()=>{getFirst(c).x+=1,playTune(n)})),afterInput((()=>{const C=tilesWith(t).length;if(tilesWith(t,c).length===C){a+=1;const c=s[a];void 0!==c?setMap(c):(addText("you win!",{y:4,color:color`2`}),playTune(p,3))}}));'},{name:"Galactic Coconuts ",by:"kcoderhtml (@kieran on slack) ",code:'const L="p",t="s",e="C",C="d",o="b",l="l",n="t",r="r",a="L",i="R",c="c",d="h",f="B",u="m";setLegend([L,bitmap`\n................\n................\n................\n................\n................\n......3333......\n.....3L00L3.....\n......3003......\n......3003......\n.....333333.....\n.....333333.....\n.....333333.....\n.....333333.....\n.....333333.....\n.....333333.....\n.....303303.....`],[t,bitmap`\n........C.......\n...00CCC00C0....\n.CC0CCC0CCC0C...\n.CC0CC00CC0CC...\n.CC0CCCC000CC.C.\nC0C0CCC0CCCC00C.\nC0C0CCC0CCCC00C.\nC0C0CCC0CCC0C0C.\n0CC00CC0CCC0CC..\n0CCC0CC0CCC0CC..\n0C0C0CC0CCC0CC..\n.C0C0CC0CCCCCC..\n.00CC0C00CCCC...\n.00CC0CC0CCCC...\n...C00CC00CC....\n....CCCC.C......`],[C,bitmap`\n......3333......\n......3D43......\n......34D3......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......\n......3333......`],[o,bitmap`\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL`],[l,bitmap`\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL`],[n,bitmap`\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................`],[r,bitmap`\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL`],[i,bitmap`\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL\n.............LLL`],[a,bitmap`\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLLLLLLLLLLLLLLL\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............\nLLL.............`],[c,bitmap`\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n.99999999999999.\n9999999999999999\nD99999999999999D\nD99999999999999D\n9999999999999999\n.99999999999999.`],[d,bitmap`\n................\n................\n................\n................\n................\n................\n................\n................\n................\n................\n..333333333333..\n.33333333333333.\n3333333333333333\n3333333333333333\n.33333333333333.\n..333333333333..`],[e,bitmap`\n................\n....66666666....\n...6669696696...\n..966666666666..\n.66696696966696.\n.66666666669666.\n.69696966666966.\n.66696666696696.\n.66966966966666.\n.66966669666696.\n.66696966669666.\n.66696666696666.\n..666969696666..\n...6666696696...\n....69666666....\n................`],[f,bitmap`\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000`],[u,bitmap`\n................\n........33333333\n....3333.....33.\n...3.........3..\n...3......33333.\n..3......3.3....\n..3.....333.....\n.3......33...33.\n.3.....333...333\n.3.....33.....3.\n.33.....3.......\n..3....3.33..3..\n...33.3...333...\n.....333........\n.....3..33333333\n....3...........`]),setSolids([L]);const h=tune`\n348.83720930232556: G4~348.83720930232556,\n348.83720930232556: F4~348.83720930232556,\n348.83720930232556: E4~348.83720930232556,\n10116.27906976744`,g=tune`\n750: G5~750 + F5^750,\n750: E5~750 + D5^750,\n750: C5~750 + B4^750,\n750: C4/750,\n750: C4/750,\n750: C4/750,\n19500`,p=tune`\n319.1489361702128: C4/319.1489361702128 + E4~319.1489361702128 + A4~319.1489361702128,\n319.1489361702128: E4/319.1489361702128 + G4-319.1489361702128,\n319.1489361702128: F4~319.1489361702128 + A4~319.1489361702128 + D4~319.1489361702128,\n319.1489361702128: G4/319.1489361702128 + B4-319.1489361702128,\n319.1489361702128: F4~319.1489361702128,\n319.1489361702128: C4/319.1489361702128 + E4-319.1489361702128 + A4~319.1489361702128,\n319.1489361702128: E4/319.1489361702128 + G4-319.1489361702128,\n319.1489361702128: F4/319.1489361702128 + A4~319.1489361702128,\n319.1489361702128: G4/319.1489361702128 + B4-319.1489361702128 + D4~319.1489361702128,\n319.1489361702128: E4~319.1489361702128 + G4-319.1489361702128,\n319.1489361702128: C4/319.1489361702128 + E4-319.1489361702128 + F4~319.1489361702128,\n319.1489361702128: E4/319.1489361702128 + G4-319.1489361702128 + B4~319.1489361702128,\n319.1489361702128: D4/319.1489361702128 + F4-319.1489361702128 + G4~319.1489361702128,\n319.1489361702128,\n319.1489361702128: A4~319.1489361702128,\n319.1489361702128: E4/319.1489361702128 + G4-319.1489361702128 + C4~319.1489361702128,\n319.1489361702128: E4/319.1489361702128 + G4-319.1489361702128,\n319.1489361702128: D4/319.1489361702128 + F4-319.1489361702128,\n319.1489361702128: C4/319.1489361702128 + E4-319.1489361702128 + A4~319.1489361702128,\n319.1489361702128: D4/319.1489361702128 + F4-319.1489361702128,\n319.1489361702128: E4~319.1489361702128 + G4-319.1489361702128,\n319.1489361702128: F4/319.1489361702128 + A4~319.1489361702128,\n319.1489361702128: G4/319.1489361702128 + B4-319.1489361702128,\n2872.340425531915`,m=tune`\n140.18691588785046,\n140.18691588785046: C4~140.18691588785046,\n4205.607476635514`,b=tune`\n116.73151750972762: G5~116.73151750972762,\n116.73151750972762: A5~116.73151750972762,\n116.73151750972762: B5~116.73151750972762,\n3385.214007782101`;let s=!1,x=!1,v=!1,T=0,y=1e3,A=0,F=0;const G=4;let E=3,D=3,I=75,S=50,B=350;const M=.95;let W=1.5,j=0;const k=[map`\nLtttttttttttttR\nlbbbbbbbbbbbbbr\n...............\n...............\n...............\n...............\n...............\n...............\n...............\n...............\n...............\n...............`];function w(L){v||playTune(L)}function R(){if(F<1){w(m),F=4;let t=getFirst(L);addSprite(t.x,t.y,C);for(let L=0;L<4;L++)addSprite(4+L,0,c)}}function O(){let L=getAll(C);for(let t=0;t<L.length;t++)L[t].y-=1}function Y(){F>0&&(clearTile(F+3,0),addSprite(F+3,0,n),F-=1)}function q(){if(E==D)for(let L=0;L<E;L++)addSprite(11+L,0,d);else clearTile(11+E,0),addSprite(11+E,0,n)}function z(){let L=getAll(t),C=getAll(e);for(let t=0;t<L.length;t++)L[t].y+=1;for(let L=0;L<C.length;L++)C[L].y+=1}function H(){let L=getAll(t),C=getAll(e);for(let t=0;t<L.length;t++)L[t].y==height()-1&&L[t].remove();for(let L=0;L<C.length;L++)C[L].y==height()-1&&C[L].remove()}function J(){for(let L=0;L<1+Math.floor(Math.random()*A/60);L++){let L=Math.floor(Math.random()*width()),C=2;Math.random()>M?addSprite(L,C,e):addSprite(L,C,t)}}function K(){let L=getAll(C),o=tilesWith(t,C),l=tilesWith(e,C);for(let L=0;L<o.length;L++)for(let t=0;t<o[L].length;t++)o[L][t].remove(),T++;for(let L=0;L<l.length;L++)for(let t=0;t<l[L].length;t++)l[L][t].remove(),T=Math.floor(1.25*T),w(b);for(let t=0;t<L.length;t++)1==L[t].y&&L[t].remove()}function N(){if(0!=tilesWith(t,L).length)return!0}function P(){if(0!=tilesWith(e,L).length)return!0}function Q(){let C=getAll(t);for(let L=0;L<C.length;L++)C[L].remove();let o=getAll(e);for(let L=0;L<o.length;L++)o[L].remove();getFirst(L).remove()}function U(L){var t=setInterval((()=>{A++,Y(),O(),K(),z(),K(),H(),J(),N()?E<1?(w(g),clearInterval(t),s=!1,x=!0,Q(),addText("Game Over!",{x:5,y:6,color:color`3`})):(E-=1,w(h),T<100?T=0:T-=100,q()):(T>y?(clearInterval(t),clearText(),addText(""+T,{x:1,y:1,color:color`9`}),Q(),addText("You won!",{x:6,y:7,color:color`9`}),w(p),s=!1):(T++,clearText(),addText(""+T,{x:1,y:1,color:color`9`})),P()&&(T=Math.floor(T*W),w(b)),A%I==0&&(clearInterval(t),W*=.9,U(B-S*A/I)))}),L)}function V(){clearText(),E=3,T=0,A=0,x=!1,addText("Falling Coconuts",{x:2,y:1,color:color`9`}),addText("a kcoderhtml game",{x:1,y:3,color:color`4`}),addText("Avoid the falling\\ncoconuts and shoot\\nboth coconuts.\\nThe golden coconuts\\ngive a x1.5 bonus",{x:1,y:5,color:color`9`}),addText("(a,d) for movement\\nj to shoot",{x:1,y:11,color:color`4`}),addText("(a,d,j) lvl sel",{x:1,y:14,color:color`3`})}function X(){clearText(),s=!0,addSprite(7,10,L),q(),U(B)}setMap(k[j]),setBackground(f),onInput("w",(()=>{s||(x?V():(B=250,y=850,I=100,X()))})),onInput("s",(()=>{s||(x?V():(B=250,y=850,I=100,X()))})),onInput("a",(()=>{s?getFirst(L).x-=1:x?V():X()})),onInput("d",(()=>{s?getFirst(L).x+=1:x?V():(B=300,y=950,I=85,X())})),onInput("i",(()=>{s?R():x?V():(B=250,y=850,I=100,X())})),onInput("j",(()=>{s?R():x?V():(B=250,y=850,I=100,X())})),onInput("k",(()=>{s||(x?V():(B=250,y=850,I=100,X()))})),onInput("l",(()=>{s?v?(v=!1,clearTile(14,11)):(v=!0,addSprite(14,11,u)):x?V():X()})),V();'}];var selectionIndex=0,booted=!1;function init(){setLegend(["b","\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000\n0000000000000000"]),setMap("b"),onInput("w",(()=>{booted||moveSelection(-1)})),onInput("s",(()=>{booted||moveSelection(1)})),onInput("i",(()=>{booted||bootSelected()})),renderEntries(0)}function renderEntries(c){clearText(),addText("Sprig Boot",{x:5,y:1,color:"2"});let L=c-2,n=c+2;L<0&&(n+=c-L,n>4&&(n=4),L=0);for(let t=L;t<n;t++)if(entries[t]){let n=entries[t];addText(`${capString(n.name,18)}\nby: ${capString(n.by,14)}`,{x:1,y:3+3*(t-L),color:c==t?"3":"2"})}}function bootSelected(){clearText(),setMap("."),booted=!0;let entry=entries[selectionIndex];eval(entry.code)}function moveSelection(c){(selectionIndex+=c)<0&&(selectionIndex=entries.length-1),selectionIndex>=entries.length&&(selectionIndex=0),renderEntries(selectionIndex)}function capString(c,L){return c.length>L-2?c.substring(0,L-2)+"..":c}init();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.