Quantcast
Channel: itouhiroはてなブログ
Viewing all articles
Browse latest Browse all 107

PICO-8でゲーム制作を学ぶ(3)

$
0
0

[合いの手] 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画像を保存すればいい。

[合いの手]こうか。
ソースコード入りPNGは以下だよ。

図: 20240327-1.p8.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説明書

  • PICO-8の数値は32767.99までしか扱えません。
    毎フレームカウンターに1を足すと、18分後にはオーバーフローを起こします!

と書いてあるように、32700 くらいを超えて、+1 すると、マイナス値の -32700 くらいになるので、
長時間プレイするゲームなら、
t = (t + 1) % 32700
とかの処理を入れて、適度に 0 に戻すほうがいいんだけどね。 このソースコードでは、やってない。

[合いの手]これは短時間しかプレイしないゲームなので、そこまでケアしてないってことか。

ゲームの画面をどう作って更新するのか、気になってたけど、PICO-8は、
1/30秒ごとに全部消して、
毎回1から描き直す、
重ね順で下のほうを先に描いて、後から描いたのは重ね順の上になる
という更新方法なんだね。

なんか毎回書き直すのは無駄な気もするけど、単純だし、これでも いいな。

ソースコードは以下。

図: 20240327-1.p8.png


Viewing all articles
Browse latest Browse all 107

Trending Articles