#1. ゲーム作成用のフォルダを作りましょう
名前も場所も自由です。
今回は「studyPhina」という名前でフォルダを作りました。
#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
<!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」へ切り替えましょう。
#3. 終わったらさきほどのフォルダに保存
これで下準備完了です。
基本的に、いま作ったHTMLファイルは、今後さわる必要はありません。
みなさんが作るプログラミングは、次に作るJavascriptファイルの中にだけ書いていきます。
#4. 空っぽのJavascriptファイルをつくりましょう。
#5. main.jsを作っていきましょう。
まずは、もっとも最小の、もっとも基本的なJavascriptコードを書きます。
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で必要なオブジェクトを置く、というイメージです。
#7. 上記をふまえてMainSceneに文字オブジェクトを追加してみる
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フォルダを作って、そのなかに置いておくとよいです。
#9. main.js にコードを追記します。
phina.globalize(); // phina.jsがこれで使えるようになります。
// こんな感じで画像や音のファイルを指定します
let ASSETS = {
image:{
white:"img/planeship/white.png",
black:"img/planeship/black.png"
}
};
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って何だろ?」
以下をご覧ください。実は画面がこのように分割されています。
phina.main(function() {
var app = GameApp({
startLabel: 'main', // 色んな画面を増やしたいときはここに追加していきます。
assets: ASSETS, // 一番上で指定した画像とかを読み込み
});
app.run();
});
全部できたら、保存して、main.htmlをブラウザで開いてみると、こんな感じに表示されるはず。
#10. 白い飛行機を動かしてみましょう
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でも両方で使えるような共通の変数を作って、そこを経由すればいいんです。
つまり、こういうことです。
// 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を入れた
// 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の値を更新するようにしましょう。