LoginSignup
5
6

More than 3 years have passed since last update.

phina.jsでゲーム作り入門編①

Posted at

1. ゲーム作成用のフォルダを作りましょう

名前も場所も自由です。
今回は「studyPhina」という名前でフォルダを作りました。
image.png

2. 次にHTMLページをつくります。

phina.jsはブラウザ上で動くゲームです。ブラウザで動くということはHTMLがないと動きません。
以下のソースコードをコピペすればOKです。一応1つ1つ何をしているのか読んでみましょうね。

「HTMLって何??( ゚д゚)ポカーン」
「HTMLでJavascriptを読み込む??( ゚д゚)ポカーン」

って人は、CODEPREPの「WEBの基礎を学ぶ」コースをまずクリアしておきましょう。
https://codeprep.jp/tracks/%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%20Web%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%82%92%E5%AD%A6%E3%81%B6

main.html
<!doctype html>

<html>
  <head>
    <meta charset='utf-8' />
    <!-- 画面の横幅にあわせた窓をつくる。ユーザがズームできないように設定している-->
    <meta name="viewport" content="width=device-width, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />

    <!-- ブラウザのタブのところに表示される文字です -->
    <title> ゲームつくるぞー | phina.js</title>
    <!-- phina.js をダウンロードして読み込む -->
    <script src='http://cdn.rawgit.com/phi-jp/phina.js/v0.2.0/build/phina.js'></script>

    <!-- ここで自分で作ったJavascriptファイルを読み込んでいる-->
    <script src='main.js'></script>
  </head>
  <body>
    <!-- 肝心のHTMLの中身は実はからっぽなんです・・・! -->
    <!-- Javascript作るだけでゲームはうごきます -->
  </body>
</html>

「色がつかないんだけど・・・?」

ってときには、VSCodeの右下にある「プレーンテキスト」ってところをクリックして、「HTML」へ切り替えましょう。

image.png

3. 終わったらさきほどのフォルダに保存

image.png

これで下準備完了です。
基本的に、いま作ったHTMLファイルは、今後さわる必要はありません。
みなさんが作るプログラミングは、次に作るJavascriptファイルの中にだけ書いていきます。

4. 空っぽのJavascriptファイルをつくりましょう。

image.png

5. main.jsを作っていきましょう。

まずは、もっとも最小の、もっとも基本的なJavascriptコードを書きます。

main.js
phina.globalize(); // phina.jsがこれで使えるようになります。

// phinaではこうやってClassを定義します
// Classよくわからんって人は、「ここで画面(Scene)を作ってる」とおぼえましょう
// ゲーム業界では画面のことをSceneと呼びます。スタート画面、ゲームプレイの画面、メニュー画面など
// DisplaySceneという「画面全体のボス」から、子供のMainSceneという「ゲームプレイ画面」を作りました
phina.define('MainScene', {
  superClass: 'DisplayScene',
  init: function() { // ここはコンストラクタです。一番最初に一回だけやる処理のこと。
    this.superInit(); // 親クラス(DisplayScene)のコンストラクタを呼んでます。
                      // ←←他にもやりたいことがあるときは、ここに追記していきます。
  }
});

// ここがゲームスタートの入り口です
// 今はGameSceneという画面が1つあるだけなので、ただ画面が表示されるだけです。
phina.main(function() {
  var app = GameApp({
    startLabel: 'main'  // 色んな画面を増やしたいときはここに追加していきます。そのうちやりましょう。
  });
  app.run();
});

※functionの定義の仕方について

ふつうは、
function init() {}
のように定義しますが、オブジェクトの中で定義する場合に限っては、
init : function() {}
のようになります。

6. Sceneとオブジェクトの関係について

ゲームをつくる上で、まずSceneが必要です。
各Sceneの中に、そのSceneで必要なオブジェクトを置く、というイメージです。

image.png

7. 上記をふまえてMainSceneに文字オブジェクトを追加してみる

main.js
phina.define('MainScene', {
  superClass: 'DisplayScene',
  init: function() { // ここはコンストラクタです。要は一番最初に一回だけやる処理のこと。
    this.superInit(); // 親クラス(DisplayScene)のコンストラクタを呼んでます。

   // 以下追記です
    // newをする必要はありません
    // 直接、必要なオブジェクトの種類を書くと、そのオブジェクトが作成されます。
    // 文字:Label()、キャラ:Sprite()、円形:CircleShape()とかとか
    // 最後の.addChildTo(this)は、作成されたLabelオブジェクトをMainSceneの子供にするよってことです。
    // まず画面があって、そこに必要なオブジェクトを置く、という流れです。
    var label = Label('オッス、, おらphina.js!').addChildTo(this)
    // これ以降でlabelに対して様々な操作をする
    // 「.(ドット)」でつなげていくことで、オブジェクトに対し色々できます。
    // .addChildToで画面に置いたり、setPositionで置く座標を決めたり
    // Javascriptは最後に「;(セミコロン)」を置くことで、行の終わりの意味になります。
    // つまり上の「var label =」から始まって、下の「gridY.center());」までが1行なんです。
      .setPosition(this.gridX.center(), this.gridY.center()); // 位置を指定
  }
});

8. 次は2つの飛行機を出してみましょう。

画像は適当にネットから拾ってきて、studyPhinaフォルダに置きましょう。
フォルダの中がごちゃごちゃしないようにimgフォルダを作って、そのなかに置いておくとよいです。
image.png

9. main.js にコードを追記します。

main.js
phina.globalize(); // phina.jsがこれで使えるようになります。

// こんな感じで画像や音のファイルを指定します
let ASSETS = {
    image:{
        white:"img/planeship/white.png",
        black:"img/planeship/black.png"
    }
};
main.js
phina.define('MainScene', {
  superClass: 'DisplayScene',
  init: function() { // ここはコンストラクタです。要は一番最初に一回だけやる処理のこと。
    this.superInit(); // 親クラス(DisplayScene)のコンストラクタを呼んでます。

    // こんな感じで、飛行機オブジェクトを作って、画面に配置します。
    // WHITE
    let white = Sprite("white", 48, 48).addChildTo(this);
    white.x = this.gridX.center();
    white.y = this.gridY.center();

    // BLACK
    let black = Sprite("black", 146, 96).addChildTo(this);
    black.x = this.gridX.center();
    black.y = this.gridY.span(4);
    black.scaleY *= -1; // Y方向の"大きさ"を逆にすると見た目が逆になります。
  }
});

「gridXとかgridYって何だろ?」
以下をご覧ください。実は画面がこのように分割されています。
image.png

main.js
phina.main(function() {
  var app = GameApp({
    startLabel: 'main',  // 色んな画面を増やしたいときはここに追加していきます。
    assets: ASSETS,       // 一番上で指定した画像とかを読み込み
  });
  app.run();
});

全部できたら、保存して、main.htmlをブラウザで開いてみると、こんな感じに表示されるはず。
image.png

10. 白い飛行機を動かしてみましょう

main.js
    black.scaleY *= -1; // Y方向の"大きさ"を逆にすると見た目が逆になります。
  },  // ここのカンマ忘れずに。MainSceneの中のinitとupdateです。
  // Scratchでいうと、「ずっと」です
  update:function(app) {
      const key = app.keyboard; // キーボードの状況が入った箱を持ってきます
      if (key.getKey("right")) { // rightボタンが押されたらTrueになります
        white.x += 1;
      }
      if (key.getKey("left")) { // leftボタンが押されたらTrueになります
        white.x += -1;
      }
  }

これでいけそうな気がしますが、実はだめなのです。
「変数のスコープ」 というやつを思い出しましょう。

『functionの中で定義した変数は、そのfunctionの外では使えない』

つまり、whiteという変数は上のほうのinit : function()の中で定義されたものなので、
下のupdate : function()の中では使えません。

ではどうすればいいのかというと、initでもupdateでも両方で使えるような共通の変数を作って、そこを経由すればいいんです。

つまり、こういうことです。

main.js
    // WHITE
    let white = Sprite("white", 48, 48).addChildTo(this);
    white.x = this.gridX.center();
    white.y = this.gridY.center();
    this.white = white;  // MainSceneが持つwhiteという変数に、initが持つwhiteを入れた
main.js
  // Scratchでいうと、「ずっと」です
  update:function(app) {
      let white = this.white; // updateが持つwhiteに、MainSceneが持つwhiteを入れた
      const key = app.keyboard; // キーボードの状況が入った箱を持ってきます
      if (key.getKey("right")) { // rightボタンが押されたらTrueになります
        white.x += 1;
      }
      if (key.getKey("left")) { // leftボタンが押されたらTrueになります
        white.x += -1;
      }
  }

修正がおわったら、保存して、白い飛行機が動くことを確認しましょう。

11. チャレンジ課題

黒い飛行機を、左右に自動で動くようにしてみましょう

【ヒント①】:phinaの座標は、左上が0, 0で、右に行くほどXは大きくなり、下にいくほどYは大きくなります。Scratchとは違うので気をつけましょう。
【ヒント②】:blackのX座標を変えればいいだけなので、black.xの値を更新するようにしましょう。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6