114
とことんF#よぷよ! F# + XNA ゲームプログラミング入門 10.15.2011 #CLRH63 ぜくる

とことんF#よぷよ! F# + XNA ゲームプログラミング入門

Embed Size (px)

Citation preview

Page 1: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

とことんF#よぷよ! F# + XNA ゲームプログラミング入門

10.15.2011 #CLRH63 ぜくる

Page 2: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぜくる (1978年生まれ)

Twitter : @zecl , はてな id:zecl

旭川市から来ました。

F#歴3年くらいの睡眠丌足なプログラマ。

プレイ中のゲーム : DARK SOULS(心が折れそうだ…

好きなパズルゲーム

倉庨番, ぷよぷよ, Dr.マリオ, ミスタードリラー, etc…

自己紹介

Page 3: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ブロック崩しゲーム

2Dシューティングゲーム(横/縦)

リバーシ(オセロ)

・・・

テトリス風ゲーム (F# + WindowsForm)

倉庨番風ゲーム (F# + Silverlight)

ぷよぷよ風ゲーム (F# + XNA) ← New!

つくったことのあるもの

Page 4: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

きょうお話しする内容

Page 5: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

株式会社コンパイルから発売されていた落ち物パズルゲームの人気シリーズ。

第1作目は1991年10月25日に発売されたMSX2版とファミコン ディスクシステム版。

2003年以降はセガが販売を行っている。

ぷよぷよ

Page 6: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ファミコン版のぷよぷよ

ぷよぷよ

人型のオブジェクトでプレイすることが可能。

とてもシュールです…

Page 7: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

F# + XNA

「とことんF#よぷよ!」Demo

いきなりですが

Page 8: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

わたしはゲームプログラマではありません。

XNA4.0で初めてXNAに触れました(初心者)

とことんF#よぷよ!にテストコードはございません。

とてもレガシーコードです(>_<)

モナドとか高度なお話はしません。怖くないです。

F#わからなくても大丈夫。雰囲気を感じてください。

おことわり

Page 9: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

Microsoft 社の簡単かつ本格的なゲーム開発環境(無償) マルチプラットフォーム Windows, Xbox360, WindowsPhone

XNA開発に使用できる言語 一般的には、C# で開発します。 が、 .NET 上で動作する言語であれば、基本的になんでもOK。 (F#, VB, IronPython, IronRuby ...)

XNAとは

Page 10: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

開発環境が無料である。

.NET Framework を軸とした移植性の高いコードを書ける

ゲーム開発に必要な枠組みや部品を提供してくれるので、ゲームをつくることだけに集中できる。すぐに作り始められる。

簡単なゲームであれば、難しいことを知らなくても割と大丈夫。

C#で書くことができるよ!

XNAのここが嬉しい!

Page 11: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

XNAのここが嬉しい!

開発環境が無料である。

.NET Framework を軸とした移植性の高いコードを書ける

ゲーム開発に必要な枠組みや部品を提供してくれるので、ゲームをつくることだけに集中できる。すぐに作り始められる。

簡単なゲームであれば、難しいことを知らなくても割と大丈夫。

C#もいいけど、F#で書くこともできるよ!

カンスウガタゲンガー歓喜

Page 12: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

絵が出せる。動かせる。

音が出せる。 文字が出せる。

入力を受け取れる(操作)。

ゲームデータの保存と読込み

ゲーム作りに必要なこと

19れんさ

Page 13: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ウィンドウの表示

ゲームループの仕組み(FPSの管理)

絵や音等、素材をロードする仕組み

描画の仕組み(SpriteBatch, SpriteFont)

データの圧縮, リソースの管理

入力を受け取る仕組み(キーボード、マウス、ゲームパッドなど)

ストレージを扱う仕組み

多くの補助的なクラスや関数 (Vector2, Color, Math…)

XNAのお膳立て

19れんさ

Page 14: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

開始

ゲームの流れ

Initialize LoadContent BeginRun EndRun UnloadContent

終了

Update Draw

ゲームループ

プレイヤーの入力受付

ゲーム状態の更新 ゲーム状態に応じた画面への描画

データ読込 データ開放 初期化

Page 15: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

開始

ゲームの流れ

Initialize LoadContent BeginRun EndRun UnloadContent

終了

Update Draw

ゲームループ

プレイヤーの入力受付

ゲーム状態の更新 ゲーム状態に応じた画面への描画

データ読込 データ開放 初期化

Page 16: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

開始

ゲームの流れ

Initialize LoadContent BeginRun EndRun UnloadContent

終了

Update Draw

ゲームループ

プレイヤーの入力受付

ゲーム状態の更新 ゲーム状態に応じた画面への描画

データ読込 データ開放 初期化

Page 17: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

SpriteBatch.Draw (Texture2D, Vector2, Color)

絵はどやって出すの?

なんかオーバーロードいっぱいあるけど、必要なときに必要なやつを適当に使えばいいよ!

Page 18: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

SpriteBatch.Draw (Texture2D, Vector2, Color)

絵はどやって出すの?

なんかオーバーロードいっぱいあるけど、必要なときに必要なやつを適当に使えばいいよ!

Page 19: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

SpriteBatch.DrawString (SpriteFont, String, Vector2, Color)

文字はどやって出すの?

なんかオーバーロードいっぱいあるけど、必要なときに必要なやつを適当に使えばいいよ!

Page 20: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

SpriteBatch.DrawString (SpriteFont, String, Vector2, Color)

文字はどやって出すの?

なんかオーバーロードいっぱいあるけど、必要なときに必要なやつを適当に使えばいいよ!

Page 21: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

素材はどうやって読み込むの?

Content.Load<アセットの種類>(アセット名)

例えば

・ this.Content.Load<Texture2D>(@"Content¥image¥player")

・ this.Content.Load<SoundEffect>(@"Content¥sound¥bgm")

Page 22: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

素材はどうやって読み込むの?

Content.Load<アセットの種類>(アセット名)

例えば

・ this.Content.Load<Texture2D>(@"Content¥image¥player")

・ this.Content.Load<SoundEffect>(@"Content¥sound¥bgm")

Page 23: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

音はどうやって出すの?

let bgm = this.Content.Load<SoundEffect>(@"Content¥sound¥bgm")

bgm.CreateInstance() .Play()

CreateInstanceメソッドで、サウンドの単一

再生、一時停止、または停止を制御可能なSoundEffectInstanceインスタンスが作られる。そして、あとはPlay()するだけ。

Page 24: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

音はどうやって出すの?

let bgm = this.Content.Load<SoundEffect>(@"Content¥sound¥bgm")

bgm.Play()

Page 25: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ゲームロジックはどう書けば?

type Game1 () as this =

inherit Game()

override this.Update(gameTime) = …

override this.Draw(gameTime) = …

Update : プレーヤーやゲームの状態を更新する処理を書く

Draw :プレーヤーやゲームの状態に応じた描画処理を書く

Page 26: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ゲームロジックはどう書けば?

type Game1 () as this =

inherit Game()

override this.Update(gameTime) = …

override this.Draw(gameTime) = …

Update : プレーヤーやゲームの状態を更新する処理を書く

Draw :プレーヤーやゲームの状態に応じた描画処理を書く

Page 27: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ウィンドウを出す方法は?

module Program =

[<EntryPoint>]

let main (args : string[]) =

use game = new Game1()

game.Run()

0 GameクラスのRun

メソッドを呼ぶだけ!

Page 28: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ウィンドウを出す方法は?

module Program =

[<EntryPoint>]

let main (args : string[]) =

use game = new Game1()

game.Run()

0 GameクラスのRun

メソッドを呼ぶだけ!

Page 29: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

入力を受取りたいんだけど?

Keyboard.GetState().IsKeyDown (Keys)

Keyboard.GetState().IsKeyUp(Keys)

Keyboard.GetState().GetPressedKeys()

さまざまなメソッドで、キーボードの入力状態を容易に取得できる。

マウス、ゲームパッド(Xbox360コントローラー)、タッチや加速度センサー(WindowsPhone)なども、プラットフォームや環境に応じて容易に取得できす。

Page 30: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

入力を受取りたいんだけど?

Keyboard.GetState().IsKeyDown (Keys)

Keyboard.GetState().IsKeyUp(Keys)

Keyboard.GetState().GetPressedKeys()

さまざまなメソッドで、キーボードの入力状態を容易に取得できる。

マウス、ゲームパッド(Xbox360コントローラー)、タッチや加速度センサー(WindowsPhone)なども、プラットフォームや環境に応じて容易に取得できす。

Page 31: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

Demo

ちいさなサンプル

Page 32: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

Microsoft社製のマルチパラダイム言語。

OCaml, Haskellなどの関数型言語に強い影響を受け、さま

ざまなアイディアの元に作られた最先端の言語。

.NET Framework上で動作し、.NET の最新テクノロジを利用できる関数型言語。

オープンソース

C#er, VBerが関数型をはじめるならコレできまり!

F#

Page 33: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数プログラミング

オブジェクト指向

手続型

プログラミング メタプログラミング

言語指向

プログラミング

マルチパラダイム

Page 34: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数プログラミング

オブジェクト指向 メタプログラミン

言語指向

プログラミング

手続型

プログラミング

マルチパラダイム

Page 35: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

エドワード・ガーソン(Edward Garson)

02関数プログラミングを学ぶことの重要性

Page 36: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数(機能/式)の集まりとして表現する

関数は第一級(ファーストクラスオブジェクト)として扱う

副作用がない(あるいは、少ない)

操作は入力を出力にマップ(写像)するのが基本

関数プログラミング

Page 37: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数型言語の利点

並列/並行プログラムの容易性

Page 38: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数型言語の利点

並列/並行プログラムの容易性

Page 39: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

簡単だというと嘘になりますが、

「泣きたいくらい難しい。」ということはないので、

まずは書き始めてください、F#を。

それが第一歩です。

関数型言語って難しいんでしょう?

Page 40: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

WindowsForm

WPF

Silverlight

XNA

Azure

ASP.NET

.NETのテクノロジ

Page 41: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

WindowsForm

WPF

Silverlight

XNA

Azure

ASP.NET

.NETのテクノロジ

Page 42: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

F# + XNA

Page 43: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

なぜF# + XNAなのか

Page 44: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

なぜF# + XNAなのか

Page 45: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

なぜF# + XNAなのか

Page 46: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

FRIENDLY F# with game development and XNA

著者:Giuseppe Maggiore

ジュゼッペ ・マジョーレ

販売:Smashwords.com

販売形式:EBookのみ

内容:シミュレーション(物理、AI等)ゲーム開発に焦点を当て、関数型言語F#2.0とXNA4.0を使って解説。

http://goo.gl/i9pRa

F# + XNA

Page 47: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

関数型言語でゲームが手軽に作れちゃう時代が来てた。

(意識していなかったけど、とっくに来てた!)

→ せっかくだから、俺はこのF#でゲームを書くぜ!

関数型言語で 手軽にゲームが作れる時代

Page 48: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ゲームプログラミング(ゲームループ)は状態が変化し続けることに着目したパラダイムです。

「状態をなるべく持たない。」、「破壊的代入を好まない」

関数型言語との相性はわるいのでは?

F#ってゆーか、関数型言語で ゲームプログラミングとか無理ゲーじゃね?

Page 49: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ゲームプログラミング(ゲームループ)は状態が変化し続けることに着目したパラダイムです。

「状態をなるべく持たない。」、「破壊的代入を好まない」

関数型言語との相性はわるいのでは?

F#ってゆーか、関数型言語で ゲームプログラミングとか無理ゲー?

Page 50: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

Visual Studio 2010 Shell (Integrated) 再配布可能パッケージhttp://goo.gl/6MsC2

Visual C# 2010 Express

http://www.microsoft.com/japan/msdn/vstudio/express/

F# CTP http://goo.gl/NMmCU

XNA Game Studio 4.0

APP HUB – [関連情報] – [ダウンロード]より http://create.msdn.com/ja-JP

開発準備

Page 51: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

新しいアイディア、新しいゲームデザインは難しい。

真似って大事。

どこまで真似をできるか。

もっとよくできそうな部分はないか探す。

自分のアイディアを盛り込む。

絵や音楽づくりはプログラミングとはまた違ったおしごと。

模倣で学ぶゲームプログラミング

Page 52: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよぷよのざっくりとしたルール

・2つでひと組で、ぷよの組が落下してくる。

・落下してくるぷよの組の色の組合せはランダム。

・落下中のぷよの組は、プレイヤーにより移動・回転の操作ができる。

・同じ色のぷよが4つ以上つながると消える(ぷよの消去)。

・ぷよの下に障害物がない場合、障害物に接地するまで落下する。

・ぷよの消去と落下の繰り返しにより連鎖が発生する場合がある。

・ぷよを配置できない状態になったら窒息(ゲームオーバー)。

・フィールド上のすべてのぷよを消去すると「全消し」となり得点を得る。

Page 53: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよぷよのゲームの状態

ゲームオーバーかどうか

ポーズ状態かどうか

現在の得点

消したぷよの数

落下中のぷよの組の状態

NEXTぷよの状態

フィールドの状態

...

代表的なゲームの状態

Page 54: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよぷよのゲーム状態を表すレコード型

ぷよぷよのゲームの状態

Page 55: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

フィールド上のぷよ配置状態を表現するには?

フィールドの表現

Page 56: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

横6×縦13の〼に区切る

フィールドの表現

Page 57: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

X座標とY座標で表せる

2次元配列で表現できそう

フィールドの表現

Page 58: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

フィールドの表現

色ごとに異なる値を設定することで、 フィールドのぷよの配置を表現する

Page 59: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

フィールドの表現

ぷよが配置されていない場所も埋める。

Page 60: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

色の表現

Page 61: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

色の表現

Page 62: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

enum (列挙型)で色違いのぷよを表現する。フィールドにぷよが配置されていない状態 n も定義する。

色の表現

Page 63: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

フィールドの表現

落下中のぷよは、確定していないので、 フィールド上は、配置がないものする。

Page 64: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

実は、1次元配列で表現できる

※数字は配列のindexを表す

数字が黄色のindexは壁を表す

フィールドの表現(余談)

Page 65: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

落下中のぷよの表現

3×3〼で考えて、配列の配列として表現

Page 66: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(360度回転の流れ)

落下中のぷよの回転

左回転(360度回転の流れ)

※ 赤ぷよを回転軸とした場合。

Page 67: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)

落下中のぷよの回転

3×3〼のそれぞれの位置に数字で名前を付けたとします。

回転に関係のある数字のみに注目して考えます。

※ 赤ぷよ(4の位置)を回転軸としています。

Page 68: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)

落下中のぷよの回転

1と5を入替える。

5と3を入替える。

7と5を入替える。

90度回転

Page 69: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)

落下中のぷよの回転

Page 70: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)

落下中のぷよの回転

Page 71: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

落下中のぷよの回転

図はイメージ

右回転(90度回転)

Page 72: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

落下中のぷよの回転

ぷよの回転方向に壁やぷよなど障害物が存在する場合、 そのまま回転させることが出来ないので回避する処理が必要。

右回転(90度回転)

Page 73: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)後の位置に障害物がある場合

ぷよ回転時の障害物の回避

赤ぷを回転軸とした場合、障害物があるので右回転ができない。

障害物を回避して回転させる必要がある。

Page 74: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

右回転(90度回転)後の位置に障害物がある場合

ぷよ回転時の障害物の回避

90度右回転すると障害物に衝突するので、左に移動する。

左に移動した後、90度右回転する。

Page 75: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの移動

ぷよが移動可能な方向は、左右と下。

ぷよの落下もmove関数を利用。 判別供用体(Discriminated Union、DU)

パターンマッチ match direction with | Right -> {ps.current with position = x + 1, y } | Left -> {ps.current with position = x - 1, y } | Down -> {ps.current with position = x , y + 1 } というように、書くのが一般的。

Page 76: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

そもそも回転ができない場合

※ 赤ぷよを回転軸とした場合。

回避丌可能な障害物があり、右回転も左回転もできない。

回避および回転可能かどうかを判断する必要がある。

実装例ではavoidance関数で行っている。

Page 77: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの生成とNEXTぷよ

現在落下中のぷよ

次に落ちてくるぷよ

次の次に落ちてくるぷよ

ぷよの組はNEXTぷよの表示のめにも3組生成しておく必要がある。

Page 78: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの生成とNEXTぷよ

ぷよの組はNEXTぷよの表示のめにも3組生成しておく必要がある。

ぷよの組の色の組合せはランダムとする。

レベルに応じて生成するぷよ組の色数を変える。

レベル001~レベル002 ・・・ レベル003~レベル004 ・・・ レベル005~レベル999 ・・・

Page 79: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの生成とNEXTぷよ

消したぷよの数

消去したぷよに応じたレベルを返す関数を定義

40個ぷよを消すごとに「+1」したレベルを返す。

ただし、最大レベルは999とする。

Page 80: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの生成とNEXTぷよ

雑なランダム生成

ぷよの組(puyoObj)の生成

Page 81: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの組

ぷよの組を表すレコード型

Page 82: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの接地と確定

Page 83: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの接地と確定

Page 84: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの接地と確定

床に接地(Yは12まで)するか、ぷよに接地(Y+1の位置が「0」ではない場合)するまでは落下し続ける。

GameクラスのUpdateメソッドでゲームの状態を更新するときに、落下中のぷよ組の座標Yに1を加算する。つまり、move関数にDirection.Downを指定して呼び出すことで表現できる。

床あるいはぷよに接地した場合、はじめてフィールド上に確定させる。

フィールド上の「0」は省略しています。落下中ぷよはフィールド上では「0」。

Page 85: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

重力によるぷよの落下

Page 86: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

重力によるぷよの落下

Page 87: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

重力によるぷよの落下

Page 88: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

重力によるぷよの落下

Page 89: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの落下

フィールドの座標において、Y+1の位置が「0」であるものすべてについて、ぷよをY+1へひとつずつずらす。

Page 90: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの連結と消去判定

Page 91: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの連結と消去判定

ぷよがいくつ連結しているかを調べる関数が必要。

最も簡単な連結ぷよの個数チェックと消去アルゴリズムは、フィールド上の座標ごとに同色ぷよの連結を再帰的に探索し保持しておきます、連結ぷよが4つ以上隣接していれば消すというものです。その際、1度調べた座標についてはチェック済みとして、再度チェックしないようにするという方法です。

左の絵の赤ぷよがいくつつながっているかを例に考えてみます。

Page 92: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの連結と消去判定

Page 93: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの連結と消去判定

探索部分に着目してみます。

Page 94: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよの連結と消去判定

再帰関数を表す。

Page 95: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよ連結の描画

上下左右の4方向で繋がる可能性があるので、4桁の2進数で表せる。

つまり単独の時も含めて、 16パターンの絵が必要なことがわかる。

Union型は、C#やVBで言うところの FlagsAttributeでマークした列挙型。

b はビットを表す。

Page 96: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよ連結の描画

ぷよがいくつ連結しているかを調べる関数が必要。

Page 97: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ぷよ連結の描画

Page 98: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

連鎖

ぷよの消去処理と、重力による落下処理の繰り返しで表現できます。

Page 99: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

得点計算

A = 基本得点(消したぷよの数 × 10 )

B = 連鎖ボーナス

C = 連結ボーナス

D = 複色ボーナス

得点 = Σ { A × (B + C + D ) } n

k=1 n n n n

n は連鎖数を表す(連鎖ごとに計算が行われる)

Page 100: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

連鎖ボーナス

連鎖数が多いほど得点が多く得られる。

最大連鎖の理論値は19連鎖。

連鎖ボーナス B は、連鎖数に応じたボーナス。

連鎖数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

ボーナス 0 8 16 32 64 96 128 160 192 224 256 288 320 352 384 416 448 480 512

連鎖ボーナス表

Page 101: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

連結ボーナス

同時消し数が多いほど得点が多く得られる。

11以上連結した場合のボーナスは10。

連結ボーナス Cは、同時に消したぷよの数に応じたボーナス。

連結ボーナス表

同時消しぷよ数 4 5 6 7 8 9 10 11 ボーナス 0 2 3 4 5 6 7 10

Page 102: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

複色ボーナス

同時に消した色の数が多いほど得点が多く得られる。

複色ボーナス Dは、同時に消したぷよの色数に応じたボーナス。

複色ボーナス表

消した色数 1 2 3 4 5 ボーナス 0 3 6 12 24

Page 103: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

落下ボーナスと全消しボーナス

ぷよの組が落下中にDownキーを押しっぱなしにすることで得られる得点のことで、 フィールド1マスごとに1点得ることができる。

全消しボーナスとは、ぷよを消去する処理が行われた後、フィールド上にぷよが1つも存在しない場合に得られるボーナス。

3600点 + (現在のLEVEL × 5)点

落下ボーナス

全消しボーナス

Page 104: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

全消し判定

フィールドのすべてがPuyoColors.n (「0」)であるかどうかをチェックするだけです。

全消しの場合、得点にボーナス点を加算する。

Page 105: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

LEVEL判定

計算量のことを考えると、ぷよぷよのゲーム状態としてLEVELを持たせて、都度状態を変更した方

がよさそうな気もしなくもないですが、レベルに応じて生成するぷよの色数を変えたりする都合上、このように、現在のLEVELを毎回計算するように、

ステートレスな仕組みにしておいた方がしっくりくる場合も。

計算量も少ないので今回は許容する。

40個消すごとにLEVELが1上がる

Page 106: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

スコアの保存

XNAではストレージで保存/読込する機能があらかじめ用意されていま

Windowsゲームでは、マイドキュメントのSavedGamesフォルダにデータが格納されます。

XBOX360の場合はストレージの選択処理なども絡んできます。

Page 107: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

スコアの保存

Page 108: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

スコアの読込

保存とは逆に、デシリアライズして読み込むだけです(ぇ

XNAでストレージを扱う仕組みを用意してくれているのは嬉しいのですが、どうしても記述が冗長になってしまうんですよねえ…。

nullとか書きたくないですし…。

Page 109: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ゲームの状態を描画する

とことんF#よぷよ!で

使用した画像は7枚

Gameクラスの派生クラスのUpdateメソッドで更新したPuyoState(ゲームの状態)に応じて、Drawメソッドで描画するだけ!

Page 110: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

アニメーション

C#で書く場合は、アニメーション専用のクラスを記述するのが一般的なようですが、F#ではいちいちクラスつくのメンドイよねってことで、ちょっとした副作用の表現であれば、クロージャーで書いたほうがシンプルです。

えろい人はStateMonadとか言い出すので注意しましょう。

Page 111: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

おすすめの書籍

Page 112: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

おすすめの書籍

Page 113: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

おすすめの書籍

Page 114: とことんF#よぷよ!  F# + XNA ゲームプログラミング入門

ご清聴ありがとうございました。