手軽に使えるPixiJS製のゲームエンジン!

ブラウザで画像を高速に処理できるWebGLという技術が使えるJavaScriptのライブラリ「PixiJS」で簡易ゲームエンジンを作りました。

 

かなり簡潔でさっくり扱えるように作っているので2Dのミニゲーム程度なら高機能なゲームエンジンを使うよりも圧倒的に手軽に作ることができると思います。

 

enchant.jsを真似て作ってあるので初心者でも扱いやすいと思います。

 

ゲームエンジンとして必要最低限の機能に絞っているので最初に学ぶことはすごく少なくJavaScriptさえ分かっていればすぐ作れます。

 

pixi.js(音もpixi-sound.js)でかなり簡潔に作っているので追加や改造もゴリゴリできると思います。

 

この記事の筆者のいんわんはブラウザゲームをちょこちょこ作って自分のサイトで公開しています ▷ 無料ゲーム-ウェブゲームセンターコスモ

 

※このゲームエンジンの作成ではSmith氏の「HTML5ゲーム開発の教科書」という本のプログラムを一部参考にさせていただきました。とてもいい本なので興味のある方は読んでみてください。ただし初心者向けではないのですごく難しいです。

 

ゲームエンジンのプログラム入手先

とりあえずどんな感じのものができるか気になるところだと思うので先にサンプルを触ってみてください。

 

▷▷▷  サンプルプログラムを遊ぶ

 

サンプルは画面をタッチするとマスクのキャラがジャンプ&方向転換するだけです。あと左上のポーズボタンでポーズできます。

サンプルは非常に簡素ですが必要最低限にしてるから簡素なだけですからね!!作り込めばすごいのだって作れるんだから!(ちなみに筆者はこんなのを作ってますよ ▷ pixi.jsのゲーム)

 

サンプルプログラムは入手は以下の2つの場所から入手できます。

お好きな方からどうぞ(‘ω’)ノ

 

先にソースだけ見てみたい人はこっちをどうぞ(‘ω’)ノ

▷▷▷ ソースを見る

 

※初心者向けに難しいところは端折ってとりあえずゲームの作り方を解説した記事を書きました。

▷▷▷ ブラウザゲーム作ろう!【初心者にもおすすめ】

 

ゲームエンジンのファイルの内容について

ダウンロードしたフォルダには以下のようなファイルが入っています。

ファイル内容

pixi.min.jsとpixi.min.js.mapがpixi.jsのファイルです。バージョンはv5.3.7です。

pixi-sound.jsはpixi.jsの音楽再生プログラムです。バージョンはv4.0.4です。

 

上記のファイル以外は私が作ったものです。その中で「p94e.js」(ピくしイーってゴロ合わせね(^^;))が今回私が作ったゲームエンジンです。他はサンプルゲームのためのプログラムです。

※注意事項:今回公開しているプログラムに関しては好きに使っていただいて構いませんが一緒に添付している画像・音楽は他では使わないでください。

 

ブラウザゲームを作るために必要なもの

pixi.jsは動作するためにはサーバーが必要です。index.htmlをブラウザにドラッグしても動いてくれません。

「サーバーってなんぞ?」という方も大丈夫です。

 

「visual studio code」をお使いの方は「vscode-live-server」というのをインストールすればOKです。参考記事 ▷ Qiita

 

もしくはxamppというアプリをインストールすればOKです 。参考記事 ▷ Qiita

 

プログラミング初心者の方へ

このゲームエンジンはJavaScriptというプログラミング言語で作られています。もしJavaScriptという言語がわからない場合は先にJavaScriptの基本的な文法などを学んでおく必要があります。

 

初心者向けのJavaScriptの簡単な説明記事があるので先にそっちを読んでみてください(‘ω’)ノ

 

またこのゲームエンジンには当たり判定の類は一切ありません。当たり判定はすべて自分で作る必要があります。基本的な当たり判定についてはこちらの記事を読んでみてください(‘ω’)ノ

 

index.htmlについて

サンプルでは以下のようになっています。

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <script src="pixi.min.js"></script>
  <script src="pixi-sound.js"></script>
  <script src="p94e.js"></script>
  <script src="tilemap.js"></script>
  <script src="main.js"></script>
  <title></title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    body { 
      position: relative;
      background-color: #222;
      text-align: center;
    } 
  </style>
</head>
<body>
</body>
</html>

 

ここで重要なのは<script src=”○○.js”></script>部分です。<script src=”○○.js”></script>がプログラムを読みこんでる部分です。他はとりあえず気にしないでください。

 

で大事なのはこの順番で、先に読み込む必要のあるものから書いていきます。試しにmain.jsを上にするとエラーになってゲームができません。

これは他のファイルの内容をmain.jsで使っているからで、使う前に必要なファイルが読まれていないからです。

プログラムをファイルで分ける場合は順番に気を付けて下さい。

 

p94e.jsのプログラム解説

p94e.jsはゲームを動かすための基幹となるプログラムが入っています。

ちなみにクラスやプロパティの名前などはけっこうenchant.jsと同じにしてあります。昔使ってた人は名前だけで内容が分かるかと思います。

 

Gameクラス

最初のGameクラスがいろんなものを管理しています。一番重要な部分ですがpixi.jsのおかげでだいぶコンパクトに出来ています。

Gameクラスの中身については難しいのでここでは解説しません。

 

ContainerクラスとSpriteクラス

その下に出てくるContainerクラスとSpriteクラスはpixi.jsのクラスを拡張したものです。この2つにupdateという更新機能をつけてゲームを作りやすくしています。

pixi.jsでは画面に何か表示する際は基本的にこのContainerクラスとSpriteクラスという2つのクラスを使います。

Containerクラスは画面に表示するものを入れる入れ物みたいなものであとで説明するシーンもContainerクラスから出来ています。

SpriteクラスはContainerに画像表示機能が追加されたようなものです。なのでContainerのように他のSpriteをaddChildすることもできます。

 

ContainerとSpriteのプロパティ

SpriteはContainerから拡張して作られているのでプロパティがほとんど同じです。

座標などよく使うプロパティを説明します。

  • x、y・・・表示する座標です。addChildしたContainer上の座標になります
  • width、height・・・幅、高さ
  • scale・・拡大縮小率。1が基準。scale.xが幅、scale.yが高さです。マイナスにすると反転
  • rotation・・・回転。単位はラジアン
  • alpha・・・透明度。1で見える、0で見えなくなる
  • visible・・・trueで表示、falseで非表示
  • pivot・・・位置座標の基準となる場所。座標で設定
  • anchor・・・位置座標の基準となる場所(Spriteのみ)。(0, 0)だと画像の左上、(1, 1)で右下、中心なら(0.5, 0.5)
  • interactive・・・trueでタッチイベントが使えるようになる

基本的に使うのはこのくらいだと思います。

 

座標は

player.x = 1o;
player.y = 2o;

と入力したり

player.position.set(10, 20)

というふうに一度に設定もできます。

 

scaleもscale.set(1, 1)といった感じにできます。

 

pivotとanchorはx、yの座標の基準となる場所を設定します。基本は画面と同じで左上端が設定されています。これを例えば真ん中に変更したい場合に使います。

pivotは自身の左上を原点としたときにそこからどの位置化を座標で指定します。anchorは割合で決めます。anchorはSpriteだけがもっています。この基準位置は回転や反転の基準になります。

 

interactiveはtrueにするとタッチやマウスのクリックなどの処理が使えるようになります。ただし、Containerはtrueにしても上にSpriteなどが無いと反応しません。

 

もっと詳しく知りたい方はpixi.jsの公式サイトを見てください。

▷▷▷ PIXI.Sprite

▷▷▷ PIXI.Container

 

EnchantSpriteクラス

EnchantSpriteはenchant.js風のSpriteにしています。

pixi.jsではスプライトのアニメーションにjsonファイルを使うんですがjsonファイルを作るのが面倒なのと初心者には向いていないと思うのでenchant.jsのように使えるようにしました。詳しい内容については下の記事に書いています。

 

ただ、この方法には「座標に小数点以下の数字があると画像にノイズが入る」という欠点があります。一応小数点以下を分ければノイズはでなくなりますが拡大・縮小・回転には効果が無いです。

ちなみにサンプルでは真ん中で動いてるデカいキャラがjsonを使ったやり方、ふんどし一丁のキャラがenchant.js風のスプライトになっています。

 

LoadingSceneクラス

LoadingSceneクラスはゲーム起動時に表示される画面です。

ローディング状況を%で教えてくれます。

ロードが完了するとゲームが始まります。

 

main.jsのプログラム解説

main.jsはサンプルゲームの処理が書かれているファイルです。改造するときはこのファイルを書き換えてください。

 

Config

設定用の変数を入れておくオブジェクトです。

サンプルでは画面の解像度くらいしか書いてないですが、音量とかストレージの名前とか、なんなら言語とかそういうのも入れて管理すると便利です。

 

Resource

このサンプルゲームで使う画像や音楽、マップデータなどのアドレスが入っています。

これはアドレスに名札を付けてるようなもので使うときにResource.○○○みたいな感じで使うことができます。直接アドレスを書くよりわかりやすくなります。

このResourceオブジェクトの内容を

const assets = [];
for (let key in Resource) {
  assets.push(Resource[key]);
}

でurlだけ取り出してcore.preload(assets)でデータをゲームに読み込んでいます。

 

window.onload

ブラウザが読み込みを完了するとwindow.onload()という関数を実行します。ブラウザゲームはここから起動します。

let core;
//ブラウザロード完了からスタート
window.onload = () => {
  core = new Game(Config.Screen.Width, Config.Screen.Height, Config.Screen.BackGroundColor);
  core.preload(assets);
  core.onload = () => {
    core.replaceScene(new MainScene());
  }
}こ

ここでまずcore = new Game()でゲームに必要ないろんなもの(画面とか)が作られています。

で、core.preload(assets)で画像とか音楽とかを読み込んでいます。この読み込みが終わるとcore.onloadが実行されます。

 

ゲームはシーン単位で作ります

core.replaceScene(new MainScene())で新しいシーンが作られて画面が切り替わります。

ゲームはこのシーン単位で作っていくと作りやすく管理も楽です。

タイトル画面、ゲームオーバー、ポーズ画面、コンフィグ画面などなど完全に独立して作れるものはシーンで分けて作ります。

私のこのサンプルではタイトル画面が無いのでいきなりゲーム画面になってますがタイトル画面が欲しい場合はTitleSceneを作ってnew TitleScene()てすればタイトル画面が出ます(名前はTitleSceneでなくても好きに付けていいよ)。

 

replaceScene()

このシーンを切り替えるのにはcore.replaceSceneを使います。これは現在のシーンを破棄して新しいシーンと入れ替えます。

ゲーム開始時では実はLoadingSceneというシーンになってるんですがこいつを破棄してMainSceneに切り替わっています。

replaceSceneを使うと前のシーンは自動的に破棄されます。

 

pushScene()とpopScene()

replaceScene()と違って破棄せずに今のシーンの上に新しいシーンを作って表示するのがpushScene()です。ポーズ画面とかメニュー画面とか今のシーンを破棄したら困るときに使います。

今までのシーンは一時停止状態になって新しいシーンが動きます。

また元のシーンに戻したいときはpopScene()を使います。popScene()を使うと上にあったシーンが破棄されて一時停止していた元のシーンがまた動き始めます。

 

シーンの作り方

シーンはContainerを拡張して作ります。Containerは大雑把に言うと入れ物みたいなもです。

シーンの作り方はこんな感じです。

class MainScene extends Container {
  constructor(){
    super();
    //処理を書く
  }
  update(delta){
    super.update(delta);
    //処理を書く
  }
}

constructor()はクラスが作られるときに最初に実行される部分です。サンプルではここでマップやキャラが作られたり音楽が再生されたりしています。

update(delta)は更新処理を書くところです。サンプルでは空ですがここにキャラクターの操作や敵キャラクターのことなどを書いたりできます。引数のdeltaは更新スピードの情報みたいなやつでラグとかの帳尻を合わせたりするのに使ったりするようです(私は使ってないですけど)。

constructorのsuper()とupdateのsuper.update()は拡張するContainerがもともと持っている処理を引き継いて使うことができるようにしてくれる処理です。とりあえず書いておけばOKです。

 

タイルマップ用プログラムのtilemap.jsについて

RPGやアクションゲームを作りたい人のためにタイルマップ用のクラスを作っておきました。ただみんなが使うものでもないしゲームにもよると思うので別ファイルに分けました。

今回のマップデータはTiledMapEditorというマップエディターを使って作っていますが、1次元配列であれば別のエディターで作っても使えます。

このタイルマップを動かしたい場合はちょっと問題があって、「小数点以下を切り離す&戻す」処理を行わないと画面がノイズだらけになるので注意してください。

 

音の再生方法について

ゲームに使うデータはcore.preload()で読み込まれた後はcore.resourcesというところに入っています。

core.resources[Resource.MapTile]といった感じで指定すると取り出せます。

音楽ファイルは

core.resources[Resource.Bgm].sound.play();

といった感じで、読み込んでる音データの後ろに.sound.○○をつけることで操作できるようになります。

  • play()・・・再生
  • stop()・・・停止
  • pause()・・・一時停止
  • resume・・・再開
  • loop・・・trueでループ再生
  • volume・・・再生音量

volumeはConfig.Volumeとか作っておいてvolume = Config.Volumeとかにして使うと良いと思います。

 

再生などは他に

core.sound.play(Resource.Bgm)

という書き方もできます。

 

また、ポーズ画面など一時停止時に再生中の音を全部止めてくれるcore.pausePlayingSounds()とそれを再開するcore.resumePausedSounds()という処理を作っておきました。

音の再生方法についてさらに詳しく知りたい方はpixi-sound.jsの公式サイトを見てください。

▷▷▷ PIXI.sound

 

ゲームの操作入力について

ゲームではタッチ以外の操作方法も使いたい方がいるかと思います。

もちろんそういうのは自力で実装していく必要があります。

入力についてはこちらに記事があるので参考にしてください(‘ω’)ノ

Typescriptの記事なのでちょっと書き方が違いますがjavascriptでも同じようにできると思います。ただ、残念ながらゲームパッドだけはこの方法ではできません。

 

とりあえず以上です

とりあえずざっと簡単に説明しました。

今後ちょこちょこ記事を書いていこうかと思います。

あんまり反応が薄いと記事を書くモチベーションが保てないのでみなさんぜひはてなブックマークしたりシェアしたりしてください(‘ω’)ノ

pixi.jsの基本的なことを知りたい方はこちらの記事を読んでみてください。

 

もし「いやこんな作り方おかしいだろ!」という上級者の方はどうぞご自由に改良しまくってください。

てかおかしいところがあったら教えてください(;^ω^)

◇ Posted by いんわん