code wiki / (root) / nx_wasm_adventure.nx

nx_wasm_adventure.nx source

↩ module page · 99 lines · 4931 B

1// nx_wasm_adventure.nx -- BROWSER-PLAYABLE sovereign Adventure: BASE-RELATIVE integer core, runs native (-> PNG) 2// AND in the browser (base = 0). NO float, NO JS logic, NO canvas drawing. A grid maze: move 4-directionally 3// (a step-cooldown keeps held keys at a sane pace), walls block, collect the key, then the locked door opens 4// (win). init()/tick(input)/render()/score()/ww()/hh()/fb_off() = the wasm interface; input 1=up 2=down 4=left 5// 8=right. license_tier: ORIGINAL 6import "nx_nishi_font_core.nx" 7const GW: i64 = 10 8const GH: i64 = 10 9const CELL: i64 = 16 10const W: i64 = 160 // GW*CELL 11const H: i64 = 160 12const STEP_CD: i64 = 6 13const O_FB: i64 = 0 // framebuffer W*H i64 14const O_MAP: i64 = 204800 // map[GW*GH] (W*H*8) 15const O_ST: i64 = 205600 // scalars[16]: 0=gx 1=gy 2=has_key 3=won 4=cooldown 16const O_MSK: i64 = 205728 17const O_STR: i64 = 213920 18 19func rgb(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) } 20 21func fillr(base: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 { 22 let fb: *i64 = (base + O_FB) as *i64 23 var yy: i64 = y0; if yy < 0 { yy = 0 } 24 var ye: i64 = y1; if ye > H { ye = H } 25 while yy < ye { 26 var xx: i64 = x0; if xx < 0 { xx = 0 } 27 var xe: i64 = x1; if xe > W { xe = W } 28 while xx < xe { fb[yy*W + xx] = c; xx = xx + 1 } 29 yy = yy + 1 30 } 31 return 0 32} 33func wall(base: i64, mp: *i64, x: i64, y: i64) -> i64 { mp[y*GW + x] = 1; return 0 } 34 35func init_impl(base: i64) -> i64 { 36 let mp: *i64 = (base + O_MAP) as *i64 37 let st: *i64 = (base + O_ST) as *i64 38 var i: i64 = 0; while i < GW*GH { mp[i] = 0; i = i + 1 } 39 var x: i64 = 0; while x < GW { wall(base, mp, x, 0); wall(base, mp, x, GH-1); x = x + 1 } 40 var y: i64 = 0; while y < GH { wall(base, mp, 0, y); wall(base, mp, GW-1, y); y = y + 1 } 41 // interior walls (none on row 1 or column 8 -> the key/door path stays clear) 42 wall(base, mp, 2, 3); wall(base, mp, 3, 3); wall(base, mp, 4, 3); wall(base, mp, 5, 3) 43 wall(base, mp, 4, 5); wall(base, mp, 5, 5); wall(base, mp, 6, 5); wall(base, mp, 7, 5) 44 wall(base, mp, 2, 7); wall(base, mp, 3, 7); wall(base, mp, 4, 7); wall(base, mp, 5, 7) 45 mp[1*GW + 8] = 2 // key at (8,1) 46 mp[8*GW + 8] = 3 // door at (8,8) 47 st[0] = 1; st[1] = 1; st[2] = 0; st[3] = 0; st[4] = 0 48 return 0 49} 50 51func tick_impl(base: i64, input: i64) -> i64 { 52 let mp: *i64 = (base + O_MAP) as *i64 53 let st: *i64 = (base + O_ST) as *i64 54 if st[3] == 1 { return 0 } // win: frozen (reload to replay) 55 if st[4] > 0 { st[4] = st[4] - 1; return 0 } 56 var dx: i64 = 0; var dy: i64 = 0 57 if (input & 1) != 0 { dy = 0 - 1 } else { if (input & 2) != 0 { dy = 1 } else { if (input & 4) != 0 { dx = 0 - 1 } else { if (input & 8) != 0 { dx = 1 } } } } 58 if dx == 0 { if dy == 0 { return 0 } } 59 let nx: i64 = st[0] + dx; let ny: i64 = st[1] + dy 60 if nx < 0 { return 0 } if ny < 0 { return 0 } if nx >= GW { return 0 } if ny >= GH { return 0 } 61 let cell: i64 = mp[ny*GW + nx] 62 if cell == 1 { return 0 } // wall 63 if cell == 3 { if st[2] == 0 { return 0 } st[0] = nx; st[1] = ny; st[3] = 1; st[4] = STEP_CD; return 0 } // locked door / win 64 st[0] = nx; st[1] = ny 65 if cell == 2 { st[2] = 1; mp[ny*GW + nx] = 0 } // pick up key 66 st[4] = STEP_CD 67 return 0 68} 69 70func render_impl(base: i64) -> i64 { 71 let fb: *i64 = (base + O_FB) as *i64 72 let mp: *i64 = (base + O_MAP) as *i64 73 let st: *i64 = (base + O_ST) as *i64 74 var p: i64 = 0; while p < W*H { fb[p] = rgb(18, 18, 26); p = p + 1 } 75 var y: i64 = 0 76 while y < GH { 77 var x: i64 = 0 78 while x < GW { 79 let c: i64 = mp[y*GW + x] 80 if c == 1 { fillr(base, x*CELL, y*CELL, x*CELL+CELL, y*CELL+CELL, rgb(96, 96, 112)) } 81 if c == 2 { fillr(base, x*CELL+5, y*CELL+5, x*CELL+CELL-5, y*CELL+CELL-5, rgb(245, 210, 70)) } 82 if c == 3 { fillr(base, x*CELL+2, y*CELL+1, x*CELL+CELL-2, y*CELL+CELL-1, rgb(160, 90, 50)) } 83 x = x + 1 84 } 85 y = y + 1 86 } 87 fillr(base, st[0]*CELL+3, st[1]*CELL+3, st[0]*CELL+CELL-3, st[1]*CELL+CELL-3, rgb(90, 210, 122)) // player 88 if st[2] == 1 { fillr(base, W-12, 4, W-4, 12, rgb(245, 210, 70)) } // key-held icon 89 if st[3] == 1 { fillr(base, 0,0,W,3, rgb(90,220,120)); fillr(base, 0,H-3,W,H, rgb(90,220,120)); fillr(base, 0,0,3,H, rgb(90,220,120)); fillr(base, W-3,0,W,H, rgb(90,220,120)) } 90 return 0 91} 92 93func init() -> i64 { return init_impl(0) } 94func tick(input: i64) -> i64 { return tick_impl(0, input) } 95func render() -> i64 { return render_impl(0) } 96func score() -> i64 { let st: *i64 = (0 + O_ST) as *i64; return st[2] } 97func fb_off() -> i64 { return O_FB } 98func ww() -> i64 { return W } 99func hh() -> i64 { return H }