-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: modernize snake example * move: main logic * cleanup * reorganize: put into main * update: internalize color definition * simplify: make program more readable * simplify: reduce game logic * fix: ffi * update: makefile
- Loading branch information
1 parent
1eedee5
commit ab871cc
Showing
14 changed files
with
320 additions
and
334 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
target/ | ||
.mooncakes/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"backend": "wasm-gc" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
run: | ||
moon build | ||
sudo python3 -m http.server 8080 | ||
moon install | ||
moon build --target wasm-gc | ||
python3 -m http.server 8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"import": [ | ||
"peter-jerry-ye/memory" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
type JS_String | ||
|
||
fn string_load_ffi(offset : Int, length : Int) -> JS_String = "string" "load" | ||
|
||
fn string_store_ffi(string : JS_String, offset : Int) = "string" "store" | ||
|
||
pub fn length(self : JS_String) -> Int = "string" "length" | ||
|
||
pub fn log(self : JS_String) = "string" "log" | ||
|
||
pub fn JS_String::empty() -> JS_String = "string" "empty" | ||
|
||
pub fn JS_String::from_string(str : String) -> Option[JS_String] { | ||
if str.length() == 0 { | ||
return Some(JS_String::empty()) | ||
} | ||
let memory = @memory.allocate(str.length() * 2)? | ||
memory.store_bytes(str.to_bytes()) | ||
let str = string_load_ffi(memory.offset, str.length()) | ||
memory.free()? | ||
Some(str) | ||
} | ||
|
||
pub fn JS_String::to_string(str : JS_String) -> Option[String] { | ||
if str.length() == 0 { | ||
return Some("") | ||
} | ||
let memory = @memory.allocate(str.length() * 2)? | ||
string_store_ffi(str, memory.offset) | ||
let str = memory.load_bytes().to_string() | ||
memory.free()? | ||
Some(str) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,125 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<link rel="stylesheet" href="./style.css" /> | ||
</head> | ||
<body> | ||
<canvas id="canvas"></canvas> | ||
<div class="information"> | ||
<div> | ||
<p><kbd>up</kbd>: go up</p> | ||
<p><kbd>left</kbd>: go left</p> | ||
<p><kbd>right</kbd>: go right</p> | ||
<p><kbd>down</kbd>: go down</p> | ||
</div> | ||
</div> | ||
</body> | ||
<script> | ||
|
||
const canvas = document.getElementById("canvas") | ||
const context = canvas.getContext("2d") | ||
const WIDTH = 480 | ||
const HEIGHT = WIDTH | ||
|
||
canvas.width = WIDTH | ||
canvas.height = HEIGHT | ||
|
||
context.scale(24, 24) | ||
const GRID_COL = WIDTH/24 | ||
const GRID_ROW = HEIGHT/24 | ||
|
||
const colors = [ | ||
"#dcdcdc", | ||
"#00263f", | ||
"#ffb900", | ||
"#2753f1", | ||
"#f7ff00", | ||
"#ff6728", | ||
"#11c5bf", | ||
"#ae81ff", | ||
"#e94659", | ||
] | ||
|
||
let requestAnimationFrameId = null | ||
let lastTime = 0 | ||
let dropCounter = 0 | ||
let dropInterval = 500 | ||
window.addEventListener("keydown", (e) => { | ||
if (!requestAnimationFrameId) return | ||
switch (e.key) { | ||
case "ArrowLeft": { | ||
snake_step(snake, 3) | ||
snake_draw(context, snake) | ||
break | ||
} | ||
case "ArrowRight": { | ||
|
||
snake_step(snake, 4) | ||
snake_draw(context, snake) | ||
break | ||
} | ||
case "ArrowDown": { | ||
|
||
snake_step(snake, 2) | ||
snake_draw(context, snake) | ||
break | ||
} | ||
case "ArrowUp": { | ||
|
||
snake_step(snake, 1) | ||
snake_draw(context, snake) | ||
break | ||
} | ||
|
||
} | ||
}) | ||
let snake_draw = null; | ||
let snake_new = null; | ||
let snake_step = null; | ||
let snake = null; | ||
|
||
const importObject = { | ||
canvas: { | ||
stroke_rect: (ctx, x, y, width, height) => ctx.strokeRect(x, y, width, height), | ||
set_line_width: (ctx, width) => ctx.lineWidth = width, | ||
fill_rect: (ctx, x, y, width, height) => ctx.fillRect(x, y, width, height), | ||
set_stroke_color: (ctx, color) => ctx.strokeStyle = colors[color], | ||
set_fill_style: (ctx, color) => ctx.fillStyle = colors[color], | ||
|
||
}, | ||
spectest: { | ||
print_i32: (x) => console.log(String(x)), | ||
print_f64: (x) => console.log(String(x)), | ||
print_char: (x) => console.log(String.fromCharCode(x)), | ||
}, | ||
Math:{ | ||
random: Math.random, | ||
floor: Math.floor, | ||
} | ||
}; | ||
|
||
function update(time = 0) { | ||
const deltaTime = time - lastTime | ||
dropCounter += deltaTime | ||
if (dropCounter > dropInterval) { | ||
snake_step(snake, 5); | ||
dropCounter = 0 | ||
} | ||
lastTime = time | ||
snake_draw(context, snake) | ||
requestAnimationFrameId = requestAnimationFrame(update) | ||
} | ||
|
||
<head> | ||
<link rel="stylesheet" href="./style.css" /> | ||
</head> | ||
|
||
<body> | ||
<canvas id="canvas"></canvas> | ||
<div class="information"> | ||
<div> | ||
<p><kbd>up</kbd>: go up</p> | ||
<p><kbd>left</kbd>: go left</p> | ||
<p><kbd>right</kbd>: go right</p> | ||
<p><kbd>down</kbd>: go down</p> | ||
</div> | ||
</div> | ||
</body> | ||
<script src="./main.mjs" type="module"></script> | ||
|
||
WebAssembly.instantiateStreaming(fetch("target/wasm/release/build/main/main.wasm"), importObject).then( | ||
(obj) => { | ||
obj.instance.exports._start(); | ||
snake_draw = obj.instance.exports["snake/main::draw"]; | ||
snake_new = obj.instance.exports["snake/main::new"]; | ||
snake_step = obj.instance.exports["snake/main::step"]; | ||
snake = snake_new(); | ||
requestAnimationFrameId = requestAnimationFrame(update); | ||
} | ||
) | ||
</script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,59 @@ | ||
// fn newCanvas(w: Int, h: Int) -> Int= "canvas""newCanvas" | ||
pub type Canvas_ctx | ||
|
||
// fn updateCanvas(id: Int, ) | ||
fn set_stroke_color_ffi(self : Canvas_ctx, color : @extern.JS_String) = "canvas" "set_stroke_color" | ||
|
||
type Canvas_ctx | ||
|
||
fn set_stroke_color(self : Canvas_ctx, color : Int) = "canvas" "set_stroke_color" | ||
fn set_stroke_color(self : Canvas_ctx, color : String) -> Unit { | ||
self.set_stroke_color_ffi(@extern.JS_String::from_string(color).unwrap()) | ||
} | ||
|
||
fn set_line_width(self : Canvas_ctx, width : Double) = "canvas" "set_line_width" | ||
|
||
fn stroke_rect(self : Canvas_ctx, x : Int, y : Int, width : Int, height : Int) = "canvas" "stroke_rect" | ||
|
||
fn fill_rect(self : Canvas_ctx, x : Int, y : Int, width : Int, height : Int) = "canvas" "fill_rect" | ||
|
||
fn set_fill_style(self : Canvas_ctx, color : Int) = "canvas" "set_fill_style" | ||
fn set_fill_style_ffi(self : Canvas_ctx, color : @extern.JS_String) = "canvas" "set_fill_style" | ||
|
||
fn set_fill_style(self : Canvas_ctx, color : String) -> Unit { | ||
self.set_fill_style_ffi(@extern.JS_String::from_string(color).unwrap()) | ||
} | ||
|
||
fn body_color(grid : GridType) -> String { | ||
match grid { | ||
Body => "#ffb900" | ||
Food => "#2753f1" | ||
Default => "#dcdcdc" | ||
} | ||
} | ||
|
||
pub fn draw(canvas : Canvas_ctx, snake : GameState) { | ||
let mut c = 0 | ||
let border_color = "#00263f" | ||
|
||
pub fn draw(canvas : Canvas_ctx, snake : GameState) -> Unit { | ||
// draw backgroud | ||
while c < grid_col_count { | ||
canvas.set_fill_style(0) | ||
for c = 0; c < grid_col_count; c = c + 1 { | ||
canvas.set_fill_style(body_color(Default)) | ||
canvas.fill_rect(c, 0, 1, grid_row_count) | ||
c = c + 1 | ||
} | ||
|
||
draw_piece(canvas, snake.grid, (0, 0)) | ||
} | ||
|
||
pub fn draw_piece(canvas : Canvas_ctx, matrix : Array[Int], | ||
offset : (Int, Int)) { | ||
|
||
fn draw_piece( | ||
canvas : Canvas_ctx, | ||
matrix : Array[GridType], | ||
offset : (Int, Int) | ||
) -> Unit { | ||
let mut r = 0 | ||
let mut c = 0 | ||
let mut c0 = 0 | ||
while c < matrix.length() { | ||
if matrix[c] == 0 { | ||
c = c + 1 | ||
continue | ||
for c = 0; c < matrix.length(); c = c + 1 { | ||
if matrix[c] == Default { | ||
continue c + 1 | ||
} | ||
c0 = c % grid_col_count | ||
r = c / grid_col_count | ||
canvas.set_fill_style(matrix[c] + 1) | ||
canvas.fill_rect( offset.0 + c0, r, 1, 1) | ||
canvas.set_stroke_color(1) | ||
canvas.set_fill_style(body_color(matrix[c])) | ||
canvas.fill_rect(offset.0 + c0, r, 1, 1) | ||
canvas.set_stroke_color(border_color) | ||
canvas.set_line_width(0.1) | ||
canvas.stroke_rect( c0, r, 1, 1) | ||
c = c + 1 | ||
canvas.stroke_rect(c0, r, 1, 1) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
{ } | ||
{ | ||
"import": [ | ||
"snake/extern" | ||
] | ||
} |
Oops, something went wrong.