Phaserのゲームを改良してみた

https://www.catch.jp:443/wiki/index.php?phaser%2Ftutorial_02

Programing > Phaser > チュートリアル2

jumping_dude.png

概要

前回のチュートリアルは、Phaserによる基本的なゲームの作り方を翻訳したものだった。

今回、これを独自に改良して、もう少しゲームぽくしてみる。

あのチュートリアルでは不足していた情報が、いくつか補完できていると思う。

まあ、ソースコードを見てもらえば分かる部分もあると思うけど、いちおう簡単に解説してみます。

ここでは、順番にソースコードを組み立てていくのではなく、完成版の全体像を見てもらって、特徴的なところをピンポイントで取り上げています。

レスポンシブにする方法など、詳細は末尾を参照。

利用条件

Copyright 2014 Yutaka Kachi released under MIT license.

間違いなどあるかも知れません。

もしも見つけたら、Twitter @y_catchへ連絡いただけると助かります。

目次

改良点

  • ルール(星がどんどん増えていく。制限時間制)
  • タイマーを使い、時間制限ゲームにした
  • Phaserに同梱のBasic Project Templateを使う
  • グローバル変数を使わず、ゲームのステータスが遷移していく
  • メインメニューとゲームオーバー画面の追加
  • 効果音

Project Template

前回のチュートリアルは、単一のindex.htmファイルに100行くらいのJavascriptコードを埋め込んでいた。これは、単純だしサクサク作れるんだけど、一方で、もう少し機能の多いゲームを作りたい場合とか見通しが悪いし、グローバル変数を使いすぎている。

そこで、Phaserに同梱されている、Project Templateの「Basic 」を使う。

これは、Phaserのresources/Project Templates にあるPhaserゲームの骨組みで、複数のファイルで構成されている。

詳しい使い方は、コメントとして記載されている。

まだ骨組みだけなので。ファイルを開いてもなにも表示されない。

ファイル構成

完成版のゲームのファイル構成は、こんな感じ。

JavaScriptは、複数のファイルに分かれていて、jsフォルダに置いてある。

最終的には、単一のjsファイルに統合しちゃえばいいんだけれど、開発中の見通しをよくするため分割しておく。

BasicGame
│
│  index.html
│
├─ audio(効果音)
│      idou_ochiru_normal.mp3
│      jump08.mp3
│
├─ images(グラフィック)
│      button.png
│      dude.png
│      platform320.png
│      preloadr_bar.png
│      sky-dark.png
│      star.png
│      timesup.png
│      title.png
│
└─ js(コード)
       Boot.js
       Game.js
       MainMenu.js
       phaser.min.js
       Preloader.js

index.html

ソースコード

このindex.htmlを開くと、ゲームが起動する。

まず、<head>部で必要なJavascriptを読み込む。

<head>
    <meta charset="UTF-8" />
    <title>Jumping Dude</title>
    <script src="js/phaser.min.js"></script>
    <script src="js/Boot.js"></script>
    <script src="js/Preloader.js"></script>
    <script src="js/MainMenu.js"></script>
    <script src="js/Game.js"></script>
</head>

で、ゲーム自体を表示するコンテナを用意する。

<div id="gameContainer"></div>

<script>部のJavascriptでは、window.onloadで呼び出して、ゲームのステータスを登録する。それからBootステータスを起動する。

<script type="text/javascript">

	window.onload = function() {

	// Create your Phaser game and inject it into the gameContainer div.
	// We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, - whatever floats your boat)
	var game = new Phaser.Game(640, 480, Phaser.AUTO, 'gameContainer');

	// Add the States your game has.
	// You don't have to do this in the html, it could be done in your Boot state too, but for simplicity I'll keep it here.
	game.state.add('Boot', BasicGame.Boot);
	game.state.add('Preloader', BasicGame.Preloader);
	game.state.add('MainMenu', BasicGame.MainMenu);
	game.state.add('Game', BasicGame.Game);

	//	Now start the Boot state.
	game.state.start('Boot');
};
</script>

Boot.js

ソースコード

枠組みとしては、BasicGame.Bootを定義して、prototypeで機能を追加していく。

ここでは、init、preload、createに関数を割り当てている。

ゲームプログラムが起動したら、まずinitで必要最小限の設定をして、preloadでリソース(読み込み中を示すバー)を読み込む。

読み込んだら、createでPreloadステータスに移動する。

Preloader.js

ソースコード

preload関数で、グラフィックとサウンドファイルを読み込んで、createでMainMenuステータスに遷移する。

読み込み中

読み込み中(プログレスバー)は、こんな感じで表示する。

// These are the assets we loaded in Boot.js
// A nice sparkly background and a loading progress bar
// 背景色
this.stage.backgroundColor = 'navy';
//作業中バーの位置
this.preloadBar = this.add.sprite((BasicGame.GAME_WIDTH-311)/2, (BasicGame.GAME_HEIGHT-27)/2, 'preloaderBar');

// This sets the preloadBar sprite as a loader sprite.
// What that does is automatically crop the sprite from 0 to full-width
// as the files below are loaded in.
// 作業開始
this.load.setPreloadSprite(this.preloadBar);

で作業が完了して、次のステータスに遷移するときは、createのところで作業中バーを停止する

this.preloadBar.cropEnabled = false;

サウンドファイルの読み込み

読み込み中は、作業中のバーを表示する。 画像やスプライトと同じように、こんなふうにして読みこむ。

this.load.audio('getSound', ['audio/jump08.mp3']);
this.load.audio('jumpSound', ['audio/idou_ochiru_normal.mp3']);

MainMenu.js

ソースコード

スタート画面とスタートボタンを表示するだけ。

スタートボタン

スタートボタンは、こんな感じ。ボタンは、スプライトになっている。これを画面中央に配置。

ボタンがクリックされると、startGame関数が呼び出される。

this.add.button(BasicGame.GAME_WIDTH/2-43, BasicGame.GAME_HEIGHT-100,'start-button', this.startGame, this, 1, 0, 2);

startGame関数は、次のGameステータスに遷移する。

Game.js

ソースコード

ゲーム自体は、前のチュートリアルと同じく、走ってジャンプして星を集める。

サウンド

いちおう、効果音を付けてみた。ジャンプしたときと星を取ったときに効果音がなる。

まず、createのところで、このステータスで使う効果音を登録する

this.getSound = this.add.audio('getSound');
this.jumpSound = this.add.audio('jumpSound');

それから、実際のアクションに合わせて、効果音を再生する

this.jumpSound.play();  //ジャンプ
this.getSound.play();   //星ゲット

時間制限

時間制限制のゲームにしてみた。

そのために、まずcreateのところで、タイマーとタイマー表示を初期化する

this._timeCounter = 0;  //タイマー
this._leftTime = 30;   //残り時間
this._leftTimeText = this.add.text(300, 16, 'Time: 0', { fontSize: '28px', fill: '#FFF' }); //時間表示

で、updateのところで、タイマーを更新する

// update timer every frame
this._timeCounter += this.time.elapsed;
// if spawn timer reach one second (1000 miliseconds)
if(this._timeCounter > 1000) {
    // reset it
    this._timeCounter = 0;
    this._leftTime --;
    this._leftTimeText.text = 'Time: ' + this._leftTime;
}

残り時間が、ゼロになったら、ゲームオーバーでquitGameを呼び出す。

if(this._leftTime <= 0) {
    this.quitGame();
}

ゲームオーバー

quitGameは、こんな感じ。まず、効果音を止めて、Time'sUp(時間切れ)を表示する

quitGame: function (pointer) {
    // Here you should destroy anything you no longer need.
    // Stop music, delete sprites, purge caches, free resources, all that good stuff.
    // Then let's go back to the main menu.
    this.getSound.stop();
    this._timesup_title = this.add.sprite((this.world.width - 400) / 2, (this.world.height - 100) / 2, 'timesup');

それから、ゲーム全体を一時停止して、クリックしたらメインメニューへ戻るようにする。

    this.game.paused = true;
    var pausedText = this.add.text(160, 360, "Tap anywhere to Menu.", { fontSize: '28px', fill: '#FFF' });
    this.input.onDown.add(function(){
    pausedText.destroy();
    this.game.paused = false;
    this.state.start('MainMenu');
    }, this);
},

レスポンシブ

basicテンプレートではなく、こっちのテンプレートを使うと、わりと簡単にレスポンシブにできた。

PCやタブレットなどデバイスの画面サイズに合わせて、ゲーム画面のサイズを調整してくれる。

スマホで縦持ちのときは、横持ちにするようガイダンスも自動的に出る。

ただし、ゲームはまだタッチだけでは操作できないんだけどな。

参考

これもまた別のゲーム+チュートリアル。


  トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-09-12 (火) 23:32:31 (2407d)