完善 w4-life 例子

This commit is contained in:
chai2010
2024-09-10 06:37:51 +08:00
parent 57e3b48592
commit 1134c618d5
11 changed files with 202 additions and 5 deletions

View File

@@ -1,9 +1,9 @@
# 版权 @2024 P5-hello 作者。保留所有权利。
dev:
go run ../../../main.go build -target=wasm4 .
run:
go run ../../../main.go run -target=wasm4 .
go run ../../../main.go run .
dev:
go run ../../../main.go build .
clean:

1
waroot/examples/w4-life/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/output

View File

@@ -0,0 +1,9 @@
# 版权 @2024 P5-hello 作者。保留所有权利。
run:
go run ../../../main.go run
build:
go run ../../../main.go build
clean:

View File

@@ -0,0 +1,4 @@
# WASM4 例子
https://wasm4.org/docs/

View File

@@ -0,0 +1,17 @@
// 版权 @2024 凹语言 作者。保留所有权利。
func setBit(n: uint, pos: uint) => uint {
n |= 1 << pos
return n
}
func clearBit(n: uint, pos: uint) => uint {
mask := ^(1 << pos)
n &= uint(mask)
return n
}
func hasBit(n: uint, pos: uint) => bool {
val := n & (1 << pos)
return (val != 0)
}

View File

@@ -0,0 +1,30 @@
// 版权 @2024 凹语言 作者。保留所有权利。
// 2色图像, 长宽是8的倍数
type BitImage :struct {
Width: int
Height: int
Pix: []byte
}
func NewBitImage(w, h: int) => *BitImage {
return &BitImage{
Width: w,
Height: h,
Pix: make([]byte, w*h/8),
}
}
func BitImage.At(x, y: int) => bool {
idx := (y*this.Width + x) / 8
return hasBit(uint(this.Pix[idx]), uint(x%8))
}
func BitImage.Set(x, y: int, c: bool) {
idx := (y*this.Width + x) / 8
if c {
this.Pix[idx] = byte(setBit(uint(this.Pix[idx]), uint(x%8)))
} else {
this.Pix[idx] = byte(clearBit(uint(this.Pix[idx]), uint(x%8)))
}
}

View File

@@ -0,0 +1,23 @@
// 版权 @2024 凹语言 作者。保留所有权利。
import "syscall/wasm4"
// https://wasm4.org/docs/guides/basic-drawing#direct-framebuffer-access
// 帧缓存, 1个字节2个像素
type Framebuffer :struct {
Pix: []byte
}
func FramebufferInstance => *Framebuffer {
return &Framebuffer{
Pix: wasm4.GetFramebuffer(),
}
}
func Framebuffer.Set(x, y: int, v: byte) {
idx := (y*wasm4.SCREEN_SIZE + x)/4
shift := byte((x % 4) * 2)
mask := byte(0b11 << shift)
this.Pix[idx] = (v << shift) | (this.Pix[idx] & ^mask)
}

View File

@@ -0,0 +1,96 @@
// 版权 @2023 life 作者。保留所有权利。
import (
"math/rand"
"syscall/wasm4"
)
const (
width = wasm4.SCREEN_SIZE
height = wasm4.SCREEN_SIZE
)
global (
cells0 = NewBitImage(width, height)
cells1 = NewBitImage(width, height)
cellFrame = FramebufferInstance()
pausing = false
)
func LifePausing {
println("pausing:", pausing)
pausing = !pausing
}
func LifeInit {
for x := 0; x < cells0.Width; x++ {
for y := 0; y < cells0.Height; y++ {
if (rand.Int() % 2) != 0 {
cells0.Set(x, y, true)
} else {
cells0.Set(x, y, false)
}
}
}
}
type DIR :struct {
x: int
y: int
}
global dirs = [...]DIR{
{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1},
}
// 生命进化
func lifeEvolve {
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
live_count := 0
for i := 0; i < 8; i++ {
nx := (x + dirs[i].x + width) % width
ny := (y + dirs[i].y + height) % height
if cells0.At(nx, ny) {
live_count++
}
}
if cells0.At(x, y) {
switch live_count {
case 2, 3:
cells1.Set(x, y, true)
default:
cells1.Set(x, y, false)
}
} else {
switch live_count {
case 3:
cells1.Set(x, y, true)
default:
cells1.Set(x, y, false)
}
}
}
}
// 交换 cells0 和 cells1
cells0, cells1 = cells1, cells0
}
func LifeStep {
if !pausing {
lifeEvolve()
}
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
if cells0.At(x, y) {
cellFrame.Set(x, y, 4)
} else {
cellFrame.Set(x, y, 2)
}
}
}
}

View File

@@ -0,0 +1,12 @@
// 版权 @2024 W4-life 作者。保留所有权利。
#wa:export start
func Start {
println("life start")
LifeInit()
}
#wa:export update
func Update {
LifeStep()
}

View File

@@ -0,0 +1,5 @@
# @2024 w4-hello
name = "w4life"
pkgpath = "w4life"
target = "wasm4"

View File

@@ -1,4 +1,4 @@
// 版权 @2024 W4-hello 作者。保留所有权利。
// 版权 @2024 W4-pong 作者。保留所有权利。
import (
"math/rand"