ゲームの結果と画面遷移

この記事はPICO-8を使ってゲームを作りに挑戦する初心者向けの記事です。連載になっているので初回から見たい方はこちらからどうぞ。

▷ レトロ風ゲームエンジンPICO-8でゲーム作ってみよう

 

今回でゲームを完成させます。

まず、プレイヤーキャラクターの操作を少し変更してもう少しゲームっぽくします。

加速と減速を作る

前回までの内容ではキャラクターが画面内を自由に動けましたがそれではいまいちなのでボタンをアクセルとブレーキのような感じに使うように変更します。つまり画面がスクロールするようなイメージになります。なので障害物はそのスピードに合わせて迫ってくるようになります。

if btn(4) then 
  speed -= 0.1
  if speed < 0.3 then
    speed = 0.3
  end
end
if btn(5) then 
  speed += 0.02
  if speed > 3 then
    speed = 3
  end
end

こんな感じになります(少し色変えました)。加速しているんが分かりますか?

スピードアップ

プログラムの解説

まずspeedという変数を_init()に作ります。初期値は0.3にしておきます。

で、playerクラス内の操作をしている所の4番と5番の所でspeed変数の加算減算をしています。

あとはenemyクラスのupdate()内にあるy座標を加算している数字をspeedに変更します。

簡単ですね。

あとは効果音を入れるともっとそれっぽくなりますよ(自分でやってね)。

それと速くなるのに合わせてプレイヤーの画像も速く切り替わるとより雰囲気がでますね。

スコア的なものを表示する

これだけではゲームとしてやっぱり物足りないので移動した距離と時間を表示してみましょう。

-- _init()
distance = 0
start_time = time()
elapsed_time = 0

-- update()
if not player.isdead then
  distance += speed
  elapsed_time = time() - start_time
end

-- _draw()
rectfill(0, 0, 128, 8, 9)
print("distance: "..flr(distance)/10, 2, 2, 8)
print("time: "..elapsed_time, 70, 2, 8)

上記をそれぞれの関数に追加します。

distanceは移動距離を入れる変数です。

time()はPICO-8を起動してからの時間を取得できる関数です。とりあえずゲーム開始時に一度その時間を取って(start_time)、後は毎回現在との差(elapsed_time)を出して経過時間として表示します。

死んだときは更新する必要が無いのでif文で条件を付けています。

flr()は小数点以下を切り落とす関数です。10で割っているのは10ドットで1メートルということにするためです(単位表示してないけど)。

画面遷移を作る

死んだらゲームオーバー画面が欲しいですよね。そしてできればタイトル画面も欲しいですよね。なので作りましょう。

-- game 
function game_init()
  particles = {}
  speed = 0.3
  fcount = 0
  goal = 200
  distance = 0
  start_time = time()
  elapsed_time = 0
  player.init()
  for enm in all(enemies) do
    enm.init()
  end
  music(0)
end
function game_update()
  if player.isdead then
    if time() - dead_time > 2 then
      mode = 2
    end
  else
    distance += speed
    elapsed_time = time() - start_time
  end
  
  player.update()
  for enm in all(enemies) do
    enm.update()
  end
  if #particles then
    for prt in all(particles) do
      prt.update()
    end
  end
end
function game_draw()
  rectfill(0, 0, 128, 128, 1)
  player.draw()
  for enm in all(enemies) do
    enm.draw()
  end
  if #particles then
    for prt in all(particles) do
      prt.draw()
    end
  end
  rectfill(0, 0, 128, 8, 9)
  print("distance: "..flr(distance)/10, 2, 2, 8)
  print("time: "..elapsed_time, 70, 2, 8)
end
-- title
function title_init()
  fcount = 0
end
function title_update()
  if btn(4) then
    mode = 1
    _init()
  end
end
function title_draw()
  cls()
  if fcount % 20 > 9 then
    print("press z to start", 30, 60, 4)
  end
end
-- result
function result_update()
  if btn(4) then
    mode = 1
    _init()
  end
end
function result_draw()
  rectfill(25, 55, 103, 80, 0)
  print("game over", 47, 60, 8)
  if fcount % 20 > 9 then
    print("press z to start", 33, 70, 4)
  end
end

-- main
mode = 0
function _init()
  if mode == 0 then
    title_init()
  elseif mode == 1 then
    game_init()
  elseif mode == 2 then
  end
end
function _update()
  fcount += 1
  if fcount > 32767 then 
    fcount = 0 
  end
  if mode == 0 then
    title_update()
  elseif mode == 1 then
    game_update()
  elseif mode == 2 then
    result_update()
  end
end
function _draw()
  if mode == 0 then
    title_draw()
  elseif mode == 1 then
    game_draw()
  elseif mode == 2 then
    result_draw()
  end
end

ゲームオーバー画面

かなり長いプログラムになっていますが簡単に説明します。

まず、_init()・_update()・_draw()・の中身を切り取ってgame_init()・game_update()・game_draw()に移します。

で元の関数にはif文を追加します。このif文はmode変数で切り替わるようになっています。このmode変数はゲームが何の画面かを入れておく変数です。このmode変数の数字を変えると画面が切り替わります。

あとはtitle_○○()とresult_○○()関数を作って_init()・_update()・_draw()の各モードの場所に記述します。

ちょっとプログラムが見づらいですが頑張ってください。

_update()内にあるfcountはどの画面でも使われるのであそこで処理するようにしています。

game_update()内にあるプレイヤーの生死の条件の所に少し変更があります。

if player.isdead then
  if time() - dead_time > 2 then
    mode = 2
  end
else
  distance += speed
  elapsed_time = time() - start_time
end

プレイヤーが死んですぐにゲームオーバー画面が出てしまうとパーティクルの演出が見れないのでちょっと時間をおいて切り替えるようにしています(dead_timeは死んだときに時間を入れておく)。

またparticlesはゲーム開始のたびに空にしたいのでgame_init()内に移動しています。

ゴールを作る

進むだけだといまいちな感じなのでゴールを作って記録を取るようにします。

-- game_init()
player.init()
goal = player.y - 1000

-- game_update()
goal += speed
if goal > player.y + 4 then
  music(-1)
  mode = 2
  sfx(7)
  if elapsed_time < record then
    record = elapsed_time
  end
end

ゴールの座標を入れるgoal変数を作ってgame_init()内のplayer.init()の後にplayer.yからゴールまでの距離(ここでは1000)を引いた位置を入れます。

あとはgame_update()内でspeedを足していってplayer.yより大きくなればゴールです。

ゴールはline()でgoalの位置に表示するように作ってください。

ゴールの際に新記録ならrecordに記録(elapsed_time)を保存します。recordはgame_init()で初期化すると記録が消えてしまうのでゲーム開始時に初期値を入れておいてください。

お疲れさまでした

これで一応ゲームは完成しました。

初めてゲームを作った方にはたぶんかなり難しかったんじゃないでしょうか(^^;)

まぁわからない部分は改造しまくってるとそのうち何となくわかってくると思うのでとりあえずあちこち改造して遊んでください(‘ω’)ノ

 

ブラウザゲーム館で遊べます

今回作ったゲームは私のゲームサイト「ブラウザゲーム館」で公開しています。

出来上がりがどんなものになるのか気になる方はぜひ遊んでみてください(‘ω’)ノ

 

BOOTHでサンプルプログラム無料ダウンロードできます

BOOTHでこのPICO-8入門講座で紹介したサンプルプログラムをダウンロードできます。

今回の記事の最後のプログラムが「sample7.p8」という名前で入っています。

同カテゴリー記事

記事の感想・コメント

※コメントはまだありません※

コメントを残す

メールアドレスが公開されることはありません。