[合いの手] 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=5 function input() local pressed=false if btn(0) then x-=1 dir=4 pressed=true end if btn(1) then x+=1 dir=3 pressed=true end if btn(2) then y-=1 dir=2 pressed=true end if btn(3) then y+=1 dir=1 pressed=true end if pressed then sprite=dir+flr((t%(anim_frame*itvl_frame))/itvl_frame+1)*16 else sprite=dir end end function distance(x1,y1,x2,y2) return sqrt((x1-x2)^2+(y1-y2)^2) end function collide(x1,y1,x2,y2) if distance(x1,y1,x2,y2) < 4 then return true end return false end function warp_item() item_x=rnd(128) item_y=rnd(128) end function _update() t+=1 input() if collide(x,y,item_x,item_y) then warp_item() sfx(0) end end function _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=5 function update_timer() if #items>0 then time+=1 end end function draw_timer() local centi=flr(time*10/3)%100; if centi<10 then centi="0"..centi end local sec=flr(time/30) local min=flr(sec/60) sec=sec%60 if sec<10 then sec="0"..sec end local col=7 if #items==0 then col=rnd(16) end print(min..":"..sec.."."..centi, 2, 120, col) end function input() local pressed=false if btn(0) then x-=speed dir=4 pressed=true end if btn(1) then x+=speed dir=3 pressed=true end if btn(2) then y-=speed dir=2 pressed=true end if btn(3) then y+=speed dir=1 pressed=true end if pressed then sprite=dir+flr((t%(anim_frame*itvl_frame))/itvl_frame+1)*16 else sprite=dir end end function distance(x1,y1,x2,y2) return sqrt((x1-x2)^2+(y1-y2)^2) end function collide(x1,y1,x2,y2) if distance(x1,y1,x2,y2) < 6 then return true end return false end function place_items() local i=1 for y=0,120,8 do for x=0,120,8 do items[i]={x=x+4,y=y+4} i+=1 end end end function draw_items() for item in all(items) do spr(item_sprite, item.x-4, item.y-4) end end -- function _init() place_items() end function _update() t+=1 input() for item in all(items) do if collide(x,y,item.x,item.y) then del(items, item) sfx(0) end end update_timer() end function _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から描き直す、
重ね順で下のほうを先に描いて、後から描いたのは重ね順の上になる
という更新方法なんだね。
なんか毎回書き直すのは無駄な気もするけど、単純だし、これでも いいな。
ソースコードは以下。