[合いの手] PICO-8を学び中。
を学んで、
効果音も作ってみた。
[合いの手]ところでプレイ動画はどうやって撮影するんだっけ?
[話者]無料版については、 https://www.lexaloffle.com/bbs/?tid=47278に書いてある。
- [Ctrl]+[8] で撮影開始。
- [Ctrl]+[9] で撮影完了して、
- 画面右上にアニメGIFが表示されるので、右クリック>保存。
[合いの手]撮影できた。
これがプレイ動画。mp4じゃなくて、gifだから、音は出ないんだね。
ソースコード、前回との違いは少ない。
x=64 y=64 sprite=1 dir=1 itvl_frame=8-- interval =1/30sec anim_frame=2 t=0 item_x=32 item_y=32 item_sprite=5function input() local pressed=falseif btn(0) then x-=1 dir=4 pressed=trueendif btn(1) then x+=1 dir=3 pressed=trueendif btn(2) then y-=1 dir=2 pressed=trueendif btn(3) then y+=1 dir=1 pressed=trueendif pressed then sprite=dir+flr((t%(anim_frame*itvl_frame))/itvl_frame+1)*16else sprite=dir endendfunction distance(x1,y1,x2,y2) return sqrt((x1-x2)^2+(y1-y2)^2) endfunction collide(x1,y1,x2,y2) if distance(x1,y1,x2,y2) < 4thenreturntrueendreturnfalseendfunction warp_item() item_x=rnd(128) item_y=rnd(128) endfunction _update() t+=1 input() if collide(x,y,item_x,item_y) then warp_item() sfx(0) endendfunction _draw() rectfill(0,0,127,127,13) spr(item_sprite,item_x-4,item_y-4) spr(sprite,x-4,y-4) end
[話者] distance関数(距離を計算する)と、collide関数(衝突しているか判定する)を使っているくらいだな。
[合いの手]ソースコード入りPNG画像ファイルに、スクショを埋め込むにはどうするの?
[話者]ゲームをプレイ中に Ctrl+7 を押してから、SAVE 20240327-1.p8.png
みたいにPNG画像を保存すればいい。
次は
プレイ内容
x=64 y=64 sprite=1 dir=1 itvl_frame=8-- interval per frame 1/30sec anim_frame=2 speed=2 items={} time=0 t=0 item_sprite=5function update_timer() if #items>0then time+=1endendfunction draw_timer() local centi=flr(time*10/3)%100; if centi<10then centi="0"..centi endlocal sec=flr(time/30) local min=flr(sec/60) sec=sec%60if sec<10then sec="0"..sec endlocal col=7if #items==0then col=rnd(16) endprint(min..":"..sec.."."..centi, 2, 120, col) endfunction input() local pressed=falseif btn(0) then x-=speed dir=4 pressed=trueendif btn(1) then x+=speed dir=3 pressed=trueendif btn(2) then y-=speed dir=2 pressed=trueendif btn(3) then y+=speed dir=1 pressed=trueendif pressed then sprite=dir+flr((t%(anim_frame*itvl_frame))/itvl_frame+1)*16else sprite=dir endendfunction distance(x1,y1,x2,y2) return sqrt((x1-x2)^2+(y1-y2)^2) endfunction collide(x1,y1,x2,y2) if distance(x1,y1,x2,y2) < 6thenreturntrueendreturnfalseendfunction place_items() local i=1for y=0,120,8dofor x=0,120,8do items[i]={x=x+4,y=y+4} i+=1endendendfunction draw_items() for item in all(items) do spr(item_sprite, item.x-4, item.y-4) endend--function _init() place_items() endfunction _update() t+=1 input() for item in all(items) doif collide(x,y,item.x,item.y) then del(items, item) sfx(0) endend update_timer() endfunction _draw() rectfill(0,0,127,127,13) draw_items() spr(sprite,x-4,y-4) draw_timer() end
[話者]タイマー処理の部分は
タイマーの表示も組み込まれています。
1/30秒おきに1ずつ増えるカウンターを「分:秒.1/100秒」に分解する処理が行われています。
具体的には
flr()
はJavaScriptでいうMath.floor()
で、小数点以下を削除する。sec="0"..sec
というのは1
ではなく01
にする処理だな。
配列変数は、Lua言語ではtableと呼ぶ。JavaScriptのObjectと同じ感じだね。 配列の添え数は、JavaScriptなら 0 から始まるけど、 Luaは1 から始まるのが特徴的。
[合いの手]time
変数と t
変数の違いはなんだろ?
[話者]どちらも1/30秒ごとに +1 されるけど、time
変数は、青リンゴをすべて取得してしまうと、+1 されなくなるんだ。t
変数は青リンゴと関係なく +1 される。
この t
変数、本当はもっとケアすべきなんだよね。
- PICO-8の数値は32767.99までしか扱えません。
毎フレームカウンターに1を足すと、18分後にはオーバーフローを起こします!
と書いてあるように、32700 くらいを超えて、+1 すると、マイナス値の -32700 くらいになるので、
長時間プレイするゲームなら、t = (t + 1) % 32700
とかの処理を入れて、適度に 0 に戻すほうがいいんだけどね。
このソースコードでは、やってない。
[合いの手]これは短時間しかプレイしないゲームなので、そこまでケアしてないってことか。
ゲームの画面をどう作って更新するのか、気になってたけど、PICO-8は、
1/30秒ごとに全部消して、
毎回1から描き直す、
重ね順で下のほうを先に描いて、後から描いたのは重ね順の上になる
という更新方法なんだね。
なんか毎回書き直すのは無駄な気もするけど、単純だし、これでも いいな。
ソースコードは以下。