文法の時間

ねむいものですね。はい。参考までに、程度で書いていきます。

  • この分野は市販の本とかネットとかのが詳しくて良い解説もいっぱいあるだけに、この文書にどれほどの意味があるのかと小一時間自問自答が・・・。
  • しばらくは雰囲気で感じていればいいことなのではないかと思っています。下の方の例ではググるキーワードもつけていますので、ご参考に。
  • 例)で書いているコードはcode.9leapの環境で、新規プロジェクト→一旦全部の行を削除(main.jsを空白)として、実際に打ち込んで試してみるといいかもしんないです。こんなかんじで。 画像
    • 実行するコードはほぼ全部下記のようなメッセージが左下に出ますが、気にしてはいけません。enchant.jsを使わないことによるものです。

      構文エラーが起きているようです。

      enchant.js は読み込まれていますが、main.js の中で構文エラーが起きているか、enchant(); が実行されていないようです。

あと、よく引き合いにVBAを出すのは、単にExcelを触るのにちょっと役に立てばいいな程度の意味であって、個人的に好きな言語ってわけではありません。

1. あまり意識しなくていい文法

ここの項目は気にしていると先にすすめないので、まずは「こういう事があるんだな」と頭の隅に置いておく程度でいいです

出力処理

echo とか print とかで画面に表示させる事が多いですが、javascriptで画面に表示させる場合は、…とりあえず、window.alert("xxxxx")かなぁ。ここではdocument.write("xxxx")を使っていますが。。。まあ、例のパターンを頭にいれておけば何かと使える。

例)

document.write("画面に表示する");
window.alert("ポップアップ出すよ");

コメント

  • enchant.js(というか、javascript)では、// (ダブルスラッシュ)で、それ以降〜行の終わりがコメント扱いになる.
  • /* 〜〜〜 */とした場合、〜〜〜 の部分をコメント扱いで書くことができる*は本当は半角)。
  • 「どういうことをさせようとしているか」を書いておくと、後から自分で見てもわかりやすい。
  • 開発時「ちょっと試して元に戻したい」という時に一時的にコメントアウトさせて試すのにも使ったりする。
  • コメントの書き方はプログラミング言語で違う
    • JavaやPHPは// とか/**/使う
    • #でコメント扱いするのもある
    • VBAでは'(シングルクォート)
// いまから足し算します ←ここはコメント
1 + 1 ; // ;までは実行されるプログラム. // より右はコメント
var kekka = 1 + 2;
/* ←この書き方の場合、ここ以降・・・
var a = "111";
window.alert(a);
・・・ここまでがコメント→ */ window.alert("実施"); //←ここはコメントじゃないので変な事を書くと文法エラーになる
// -----ここから----------
var test1 = 1;
var test2 = test1 + 1;
// var test2 = test1 + 2;
document.write(test2); // 「2」と出る。上の//だけ消したら「3」が出る。
// -----ここまで----------

行末判定

enchant.js(というか、javascript)の解釈では';'が基本的には行末判定になります。 言葉足らずですが、とりあえずはこの認識で十分かと。

// これはjavascriptとしては2行扱い
var hensu1 = "あああ"; var hensu2 = "いいい";
// これは1行扱い
var hensu
      = "あああああ";
// ↓実はこれでもエラーにはならない
//  これはjavascriptさんが広い心でそっと;を入れてくれている
var hensu = "だからなにって"
hensu = hensu + "言わないの";
document.write(hensu);

改行コードで行末判定される言語もあります。VBAはこのタイプ。

' vbaの場合、これは1行
Dim var1 as String
var1 = "あああああ"

' vbaの場合、こうしようとするとエラー
var1
  = "あああああ"

' なので、"改行入れるけど1行として読み取って欲しい” という記号を入れる必要がある。
' vbaなら、半角空白 + _
var1  _
  = "あああああ"

2. 文法みたいのの本番

ここから本番。意識して覚えていく必要があるものを並べてみます。

変数

  • いままでガッツリ使いながら説明しなかった基本中の基本。
  • (たぶん)どのプログラミング言語を使っていてもかならずお目にかかる、スライムにしてラスボス。
  • 値を入れる箱のこと。
  • 変数名=値 の形で、値を変数に入れることができる。
  • 変数(箱)に値を入れることを「代入する」という。
  • 言語ごとで多少法則は違うが、今回使用言語の場合、文字列を入れる場合は""(ダブルクォーテーション)または''(シングルクォーテーション)で括る。数字の場合は囲わない。
  • 型というやつを気にしないといけない言語もある。数字を入れるための変数には文字を入れられない、みたいな制約があったりする。
    • よくあるのはint型(数値を扱う型)、string型(文字を扱う型)、boolean型(True,Falseのみ扱う型)。
    • これを書いている人は、初めて習った時はこのboolean型の意義が全く理解できませんでした。今は使いまくっています。
  • これは変数ですよ、という宣言というやつをしないと変数にならない言語もある。
    • VBAは絶対ではないけど、まあ、やりましょうよ。 Dim suuji as Integer ← suujiという、数値を入れるための箱ですよ、と、宣言している。
  • 逆に、宣言という考え方が無い言語もある。
    • PHPとか。$hoge という変数を、宣言過程なしに代入することができる。 $hoge = 1111; みたいな。
    • javascriptも特に宣言が必要無い言語だったりする。
  • ほうぼうに細かい語弊があるけど気にしてはいけない。

例)

var hensu1 = "文法の時間"; // 文法の時間 という文字を代入
var suuji1 = 1; // 1 という数字を代入
suuji1 = suuji1 + suuji1; // =より右側で足し算された値「2」が新たにsuuji1に設定される
document.write(suuji1);
document.write(":");
var moji1 = "1"; // 1 という文字を代入
document.write(moji1);
document.write(":");
moji1 = moji1 + moji1; // 新たなmoji1の値は"11"となる
document.write(moji1);

文字の結合

これも言語によって違うが、"+"を使えばいいのが多い気がする(思い込み)。

  • 足し算でも"+"を使うが、これは、扱う値や変数の型によって判別がつく
    • 数値型 + 数値型 … 足し算
    • 文字列型 + 文字列型 … 文字列結合

例)

var moji1 = "たまご";
var moji2 = "わたし";
var moji3 = moji1 + "と" + moji2;
document.write(moji3);
document.write("<br>---------<br>"); // 見やすさのために改行と点線をいれておく
var suuji1 = 1010;
var suuji2 = 1020;
var suuji3 = suuji1 + suuji2;
document.write(suuji3);

ループ

くるくるするやつ。

  • 結構、ForとかWhileで始まる構文を持っていることが多い。
  • javascriptの場合は繰り返し処理をさせたい箇所の始まりと終わりを"{""}"で括るのが基本スタイル。
    • VBAだと括弧で括るやり方がなく、Forという言葉の次の行からNextという言葉の1行前までが繰り返し実行される。多分、改行に対する考え方の違いだと思う。
  • ループ変数という考え方があり、i,j,k,lあたりが使われる。人間的なお約束。
  • ForとかWhile以外にも、配列の中身を順番に操作するとかいうループもある。
    • 配列とは、という説明はスキップする強行スタイル。
  • 繰り返し実行される内側はtabや半角空白でインデントをつけるのが、人間的なお約束。

例)

// しつこく晩御飯要る?と表示して、10回表示された後キレてみる。挙動は
// ・ iという変数の初期値が0
// ・ iの値は10未満の間ループ
// ・ "{"から"}"の間を繰り返す、iの値は毎回1ずつ増える
// ・ N回目、の表示部分について。常にiの値より1大きい値を表示したいので、表示時はi+1とする
for(var i = 0 ; i < 10 ; i++){
  document.write("[iの値を確認:"+ i+"]");
  document.write("晩御飯要る?" + "(" + (i + 1) + "回目)<br>");
}
document.write("うっさいわ!!!");
  • i++の++って何!?っていう場合はグーグル先生にお問い合わせください(インクリメント演算子)

例)

// iの値を1ずつ増加ではなく、2ずつ増加させてみる。
for(var i = 0 ; i < 10 ; i=i+2){
  document.write("[iの値を確認:"+ i+"]");
  document.write("晩御飯要る?" + "(" + (i/2 + 1) + "回目)<br>");
}
document.write("それでも十分うざいです");
  • わざわざiの値を2ずつ増やして2で割ってN回目表示するという、文法確認のためのプログラムです

配列

複数の値を1個の変数でお取り扱いする場合に使う。ループや条件分岐とセットで学ぶとわかりやすいかも。

(特徴)

  • 順番をつけられる
  • キーはデフォルト数値(0始まり)。でも文字列にすることもできる(場合がある)
    • 連想配列というやつ
    • しかも、この連想配列というやつ、"配列名[xxx]の形だけでなくて、実は"配列名.xxx"でアクセスすることもできる。
  • 配列の中に配列を入れていろいろやったりする
    • 多次元配列とかいう
  • 配列の個数をカウントする機能が大体用意されていて、組み合わせてループ回したりする
    • javascriptの場合はlength, VBAの場合はLCountだったかな

十干十二支の全60パターンを見てみる。

例)その1。とにかく全パターン見られればOK。

// 十干の配列
var jikkan = new Array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
// 十二支の配列
var junishi = new Array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥");

for(var i = 0 ; i < 10 ; i++ ){ // 十干用
  for(var j = 0 ; j < 12 ; j++ ){ // 十二支用

    // 配列jikkanのi番目に入っている値を表示
    document.write( jikkan[i] );

    //配列junishiのj番目に入っている値を表示
    document.write(junishi[j]);

    // 見やすくするために改行しておく
    document.write("<br>");
  } // 十二支用ループ終わり
} // 十干用ループ終わり

表示できたなら、ちまちま変えてみるとどこでどういう動きをしているかわかってくるかも。

  • document.write( jikkan[i] ); の位置を10行目から7行目(十干用ループと十二支用ループの間)に移動してみる
    • こんなかんじで。
      for(var i = 0 ; i < 10 ; i++ ){
      document.write( jikkan[i] );
      for(var j = 0 ; j < 12 ; j++ ){
  • document.write("<br>"); の位置を16行目から18行目(十二支用ループの終わりと十干用ループの終わりの間)に移動してみる
    • こんなかんじで。
      }
      document.write("<br>");
      }
    • 表示が崩れるけど、どういう風に崩れているか見るのが大事。

例)その2。巡ってくる順に十干十二支を表示(×甲子甲丑、○子→乙丑)

// 十干の配列
var jikkan = new Array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
// 十二支の配列
var junishi = new Array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥");

for(var i = 0; i < 60 ; i++ ){
  var pattern = ""; // 空白値を代入し、初期化
  pattern = pattern + jikkan[ i % 10 ]; // 変数iの値を10で割った余り
  pattern = pattern + junishi[ i % 12 ]; // 十干 + 十二支 の文字列を作る
  document.write("十干十二支" + (i + 1) + "番目:" + pattern +"<br>");
}
  • pattern=""がなくても動くけど、今回は入れてみている
    • pattern=""の行を消した場合、つぎの行も pattern = jikkan[i % 10 ] みたいに変更しておいたほうがよい
    • これくらい動作が少ないなら、初めから↑のようにしてもいいくらい。書き方を揃えておく方が後々小さい改変をした時に間違えにくいから、という程度。
  • pattern = pattern + junishi[ i % 12 ];の pattern + の部分がないと寂しくなるので、実際に書いて動作を見てみると面白い

例)連想配列を使って各十干十二支の読み方もわかるようにする。

// 十干の配列
var jikkan = new Array({"name":"甲","kana":"きのえ"},{"name": "乙","kana":"きのと"},{"name": "丙","kana":"ひのえ"},{"name": "丁","kana":"ひのと"},{"name": "戊","kana":"つちのえ"},{"name": "己","kana":"つちのと"},{"name": "庚","kana":"かのえ"},{"name": "辛","kana":"かのと"},{"name": "壬","kana":"みずのえ"},{"name": "癸","kana":"みずのと"});
// 十二支の配列
var junishi = new Array({"name":"子","kana":"ね"},{"name": "丑","kana":"うし"},{"name": "寅","kana":"とら"},{"name": "卯","kana":"う"},{"name": "辰","kana":"たつ"},{"name": "巳","kana":"み"},{"name": "午","kana":"うま"},{"name": "未","kana":"ひつじ"},{"name": "申","kana":"さる"},{"name": "酉","kana":"とり"},{"name": "戌","kana":"いぬ"},{"name": "亥","kana":"い"});

for(var i = 0; i < 60 ; i++ ){
  // 初期化
  var etoname = ""; var etokana="";
  // まずは干支(漢字)
  etoname = etoname + jikkan[ i % 10 ]["name"];
  etoname = etoname + junishi[ i % 12 ]["name"];
  // つぎ、干支(読み方)
  etokana = etokana + jikkan[ i % 10 ].kana; // "."でも使える確認
  etokana = etokana + junishi[ i % 12 ].kana; // "."でも使える確認

  document.write("干支" + (i + 1) + "番目:" + etoname + "(" + etokana + ")" +"<br>");
}
  • {"":"","":""}のあたりが連想配列
  • 配列の中に配列(連想配列)を入れてみたあたりが多次元配列を主張

例)西暦と合わせる。今回は西暦と突合できれば十分なので、作為的だが配列の開始順を操作する

// ========= 干支関係の設定 =========
// 西暦0年(配列の0番目)を一番初めにもってくる
// 十干の配列
var jikkan = new Array("庚","辛","壬","癸","甲","乙","丙","丁","戊","己");
// 十二支の配列
var junishi = new Array("申","酉","戌","亥","子","丑","寅","卯","辰","巳","午","未");

// ========= 確認したい西暦 =========
var seireki = 672; // 計算するので数値で設定

// ========= 計算 =========
var modjikkan = seireki % 10; // 西暦を10で割った余りの値が十干の配列の位置になる
var modjunishi = seireki % 12; // 西暦を12で割った(以下略)

// ========= 表示 =========
document.write("指定された西暦:" + seireki + "年<br>");
document.write("十干十二支:" + jikkan[modjikkan] + junishi[modjunishi]);
  • seireki % 10;などの「%」は、数値を割り算した余りの値を求める時につかう(剰余演算子)
  • 壬"を"壬(みずのえ)"、"申"を"申(さる)"としてみたときの表示も確かめてみるといいかも
    • ただの文字列のつながりで持っておくか、データで持っておくかで使える事の違いを確認できる
    • 別に、"申(しん)"で設定しておいても、たとえば"壬申(みずのえさる)"と表示しようと思えばできるよ?
      • ちょっと大変だけど。で、プログラムの場合、大変=ミスしやすい=危険。

例)連想配列との連携技で西暦・十干十二支・読み方を表示してみる

// ========= 干支関係の設定 =========
// 西暦0年(配列の0番目)を一番初めにもってくる
// 十干の配列
var jikkan = new Array({"name": "庚","kunyomi":"かのえ","onyomi":"こう"},{"name": "辛","kunyomi":"かのと","onyomi":"しん"},{"name": "壬","kunyomi":"みずのえ","onyomi":"じん"},{"name": "癸","kunyomi":"みずのと","onyomi":"き"},{"name":"甲","kunyomi":"きのえ","onyomi":"こう"},{"name": "乙","kunyomi":"きのと","onyomi":"おつ"},{"name": "丙","kunyomi":"ひのえ","onyomi":"へい"},{"name": "丁","kunyomi":"ひのと","onyomi":"てい"},{"name": "戊","kunyomi":"つちのえ","onyomi":"ぼ"},{"name": "己","kunyomi":"つちのと","onyomi":"き"});
// 十二支の配列
var junishi = new Array({"name": "申","kunyomi":"さる","onyomi":"しん"},{"name": "酉","kunyomi":"とり","onyomi":"ゆう"},{"name": "戌","kunyomi":"いぬ","onyomi":"じゅつ"},{"name": "亥","kunyomi":"い","onyomi":"がい"},{"name":"子","kunyomi":"ね","onyomi":"し"},{"name": "丑","kunyomi":"うし","onyomi":"ちゅう"},{"name": "寅","kunyomi":"とら","onyomi":"いん"},{"name": "卯","kunyomi":"う","onyomi":"ぼう"},{"name": "辰","kunyomi":"たつ","onyomi":"しん"},{"name": "巳","kunyomi":"み","onyomi":"し"},{"name": "午","kunyomi":"うま","onyomi":"ご"},{"name": "未","kunyomi":"ひつじ","onyomi":"び"});

// ========= 確認したい西暦 =========
var seireki = 672; // 計算するので数値で設定

// ========= 計算 =========
var modjikkan = seireki % 10; // 西暦を10で割った余りの値が十干の配列の位置になる
var modjunishi = seireki % 12; // 西暦を12で割った(以下略)

// ========= 表示 =========
document.write("指定された西暦:" + seireki + "年");
document.write("<br>");
document.write("十干十二支:" + jikkan[modjikkan]["name"] + junishi[modjunishi]["name"]);
document.write("<br>");
document.write("(");
document.write(jikkan[modjikkan]["onyomi"] + junishi[modjunishi]["onyomi"]);
document.write(" または ");
document.write(jikkan[modjikkan]["kunyomi"] + junishi[modjunishi]["kunyomi"]);
document.write(" のとし)");

動作イメージ

  • たくましいデータになってきたので、ネット上のデータをExcelに貼り付けて関数で都合の良い形に置換したのを貼り付けて使うと楽かもしれない
    • Tabとか半角空白、改行は自由に入れていいので、読みやすいようにしておくとよいかも

条件分岐

  • 「Aの場合はどうする,Bのばあいは…」を書くやつ。
    • 自分より相手の出した値が大きいなら負け、自分の値の方が大きいなら勝ち、同じ値ならおあいこ、とか
  • 代表的なのは、if文。どの言語でもif文は見かけると思う。
    • でも、if文のつなげ方は言語によってちょっと違う。javascriptとかだと if([条件]){[挙動]}だけど、VBAだとif [条件] then[改行] [挙動] [改行]endifだったりする。
    • 多分、改行の取り扱い方が違うからだと思う(個人の偏見)
  • 他にもcase文とかはよく見る。
  • 比較演算子(AとBの値は等しい、AよりBの値の方が大きいとか)の表し方も言語で特徴がある
    • javascriptだと、a === b が「厳密に」等しい(厳密、の意味はここではカット)、a == bが寛容に等しい
    • VBAだと a = b が等しい(if文の中なら"="が比較の意味になる)
    • gt (greater thanの意味) eq (equal) とかで比較するのもある
  • なんにしてもとても便利。

例)

// 日時のデータを取得する
var nichiji = new Date();
// 時刻(H時の部分)を取り出す
var hour = nichiji.getHours();
// 時刻(分)を取り出す
var minute = nichiji.getMinutes();
// 時刻(秒)を取り出す
var second = nichiji.getSeconds();

// 12時以前だと「午前」、12時台は「真昼間」、13時以降は「午後」とする
if(hour < 12) {
  document.write("いまは午前です");
} else if( hour == 12) {
  document.write("まっ昼間");
}else{
  document.write("俄然午後です");
}
// 参考までに、時刻表示
document.write("--※いまは;" + hour + "時" + minute + "分" + second + "秒");

オブジェクト

ようこそ泥沼へ。オブジェクトとは値や動作の定義を詰め込んだ設計物みたいなもんです。

・・・。雑な説明ですみません。なかなかぱっとイメージがつく説明がないのです。

  • ところが、javascript使うならこの言葉から逃げられない!
  • 特に、enchant.jsでは逃げられない!!
    • 絶対に、だ!!
  • だって、文字列を扱うStringってやつ、これもオブジェクトだし
    • 配列もオブジェクトだし
    • さっきしれっとDate()ってやつ書いたけど、これもオブジェクトだし
    • enchant.js使う時のSprite、あれもオブジェクトだし
  • オブジェクトは、単に定義している間はクラスとか呼ばれたりもする
    • で、実際にメモリ上に呼び出し喰らったらオブジェクト呼ばわりされる
    • 設計書や図面の状態 = クラス、実際に構築されたもの = オブジェクト、みたいな感じだろうか
    • ところがjavascriptはちょっとこれとも違う
      • クラスではなくプロトタイプですな。考え方がちょっと違う。とりあえず無視すること大推奨。
  • 親クラスとか子クラスとかも実は存在する
    • 大枠だけ書いた設計書と、それに基づいてちょっと細かく書いた設計書、みたいな
    • とりあえずは「言葉を聞いたことがあるだけ」でいいかと
  • クラスで定義しておいたものをオブジェクトにするには、new というやつを使う。 大体それを変数に代入する
    • var d = new Date(); ←Dateオブジェクトを作ってdという変数に代入している
    • まあ、文字列自体は特に使うことが多いから、他と違ってnewしなくても使えたりする
  • オブジェクトの中に存在するもの
    • 値の定義はプロパティと呼ばれる
    • 動作の定義はメソッドと呼ばれる
  • オブジェクト化したらオブジェクトの中の定義を使えるようになる
    • 使い方は、間に"."を入れる
    • var d = new Date(); var h = d.getMinutes();←DateオブジェクトのなかのgetMinutes()という動作機能を使い、日付の情報から分の情報を取り出す
  • 初心者にはつらいおはなし。これもほろにがい昔の思ひ出。
  • もうわからない
  • 習うより慣れろの最たるものだと思う

例)画面をロードした時刻によって、現れる敵や逃げられるかどうかが変わる画面を作ってみる。

*ここではわざと自作クラスを用意しています。今まで説明もしていないことを加えているので、まずはこれをコピペしてみることをお勧めします

/*
 * =================
 *  クラスの定義
 * =================
 */
// バラモスクラスの定義
var Baramos = function(){
  this.monstername = "バラモス"; // モンスターの名前。これはプロパティ
  this.nigechi = 0; // 逃げ値。これはプロパティ
  this.attack = function(lv){ // 攻撃。これはメソッド
    if(lv < 20 ){ // 勇者のレベルが低ければやさしい攻撃、高ければイオナズン
      return "やさしい攻撃。ダメージ10";
    } else {
      return "イオナズン。ダメージ150";
    }
  }
}
// スライムクラスの定義
var Slime = function(){
  this.monstername = "スライム";
  this.nigechi = 100;
  this.attack = function(lv){
    return "ぽよんっ。ダメージ1";
  }
}

/*
 * =================
 *  動作開始。ここから実際の挙動になる。
 * =================
 */
var level = 40; // 勇者のレベル。ここをいろいろな値に変えてみると動作がなんとなくわかるかも
var d = new Date(); // Dateはもともと用意されているクラスなので上部で改めて定義しなくても良い
var second = d.getSeconds(); // Dateで予め定義されているgetSeconds()メソッドを利用し、現在秒を取り出す

// モンスターに出会う。
var souguuMonster; // この変数に、遭遇するモンスターのオブジェクトを入れる
if(second > 30 ){ // 現在秒が30秒以降ならスライムに遭遇、それ以外ならバラモスに遭遇
  souguuMonster = new Slime();
}else{
  souguuMonster = new Baramos();
}
// どのモンスターに出会ったかを表示する
document.write(souguuMonster.monstername + "に出会った<br>");

// 逃げてみる.
// ここではモンスターが持っているnigechiの値が50を超えていたら必ず逃げられるものとする
if(souguuMonster.nigechi > 50){
  document.write("逃げ成功<br>");
} else if( (souguuMonster.nigechi > 30) && (second % 2 == 1) ) {
  // nigechiが50以下30超えの値の場合、かつ、現在秒が奇数の場合
    document.write("なんとか逃げ成功<br>");
} else {
  document.write("逃げられなかったorz<br>");
  // 逃げられなかった場合はそのまま攻撃を食らうペナルティ
  document.write(souguuMonster.attack(level)); // モンスターによっては勇者のレベルで攻撃を変えてくる
}

// 参考データを表示
document.write("<br><br>-[参考]------------<br>");
document.write("勇者のレベル:" + level + "<br>");
document.write("現在秒:" + second + "<br>");
document.write("逃げ値:" + souguuMonster.nigechi + "<br>");

動作イメージ

無事、表示されたら以下のことを試してみるとイメージがつくかもしれません。括弧内はググり時のキーワードです。

  • 勇者のレベルを40から20にしてみる。
    • バラモスに出会った時に受ける攻撃が変わるはず
  • スライムの逃げ値を100から40にしてみる
    • 逃げられた場合のメッセージが変わるはず
    • 逃げられない可能性がでてくるため、攻撃を受けることがあるはず
  • モンスターから逃げられる条件を変えてみる
    • モンスターの逃げ値 < 勇者のレベルの場合も、"逃げ成功<br>"になるようにする(論理演算子)
    • 要は、今現在「逃げ値 > 50」となっているところを、「逃げ値 > 50 または 逃げ値 < 勇者のレベル」という構文にしてみるということ
    • 現在秒が奇数の場合→現在秒が3の倍数の場合(剰余演算子)
    • つまり、3で割った余りの値が0の場合

例)敵が現れるプログラムを改造し、enchant.jsらしく組み込んでみる。

(前処理)「Add Resource」ボタンからchara6.pngファイルを選択し、読み込めるようにしておく。

enchant(); // enchant.js呼び出し

 window.onload = function(){
    var game = new Game(320 , 320);
    game.preload('chara6.png');

    // バラモスクラスの定義
    var Baramos = function(){
        this.monstername = "バラモス";
        this.nigechi = 0;
        this.attack = function(lv){
            if(lv < 20 ){
                return "通常攻撃。ダメージ10";
            }else{
                return "イオナズン。ダメージ150";
            }
        };
        // 追加箇所。バラモスのグラフィック
        var tmpspr = new Sprite(32,32);
        tmpspr.image = game.assets['chara6.png'];
        tmpspr.scaleX=2;
        tmpspr.scaleY=2;
        tmpspr.frame=4;//前向きで目が光ってるやつ
        tmpspr.x = 320/2 - 32/2; // 画面サイズとキャラサイズから中心を割り出す
        tmpspr.y = 180 - 32*2/1.7; // 文字は180の位置下に出る。画像の周囲に空白があるので補正値が必要(これは1.7で設定)
        this.sprite = tmpspr;
    };
    // スライムクラスの定義
    var Slime = function(){
        this.monstername = 'スライム';
        this.nigechi = 30;
        this.attack = function(lv){
            return 'ぽよんっ。ダメージ1';
        };
        // 追加箇所。スライムのグラフィック
        var tmpspr = new Sprite(32,32);
        tmpspr.image = game.assets['chara6.png'];
        tmpspr.scaleX=2;
        tmpspr.scaleY=2;
        tmpspr.frame=1;//ちょっと潰れてるやつ
        tmpspr.x = 320/2 - 32/2; // 画面サイズとキャラサイズから中心を割り出す
        tmpspr.y = 180 - 32*2/1.5; // 補正値は1.5
        this.sprite = tmpspr;
    };

    // 実際の画面表示
    game.onload = function(){
      // 勇者の定義
      var level = 10; // 勇者のレベル。
      var d = new Date(); // Randomだと再現が面倒くさいので秒で動きが変わるようにする
      var second = d.getSeconds(); // 現在秒を取り出す

      // ラベル表示の定義
      var msgLabel = new Label();
      msgLabel.x = 7; // 若干右寄せのほうが収まりが良かったので...
      msgLabel.y = 180;
      msgLabel.textAlign = 'center';
      msgLabel.text = ""; // 空白にしておく

      // モンスターに出会う。
      // 出会った場合;どのモンスターに遭うか決める
      //   →遭遇を伝えるメッセージと、敵グラフィックを設定
      var enemy; // この変数に遭遇するモンスターのオブジェクトを入れる
      if(second > 30 ){
        enemy = new Slime();// 現在秒が30秒以降ならスライムに遭遇
      }else{
          enemy = new Baramos(); // それ以外ならバラモスに遭遇
      }
      // 遭遇を伝えるメッセージ
      msgLabel.text = msgLabel.text + enemy.monstername + 'に出会った<br>';
      game.rootScene.addChild(msgLabel);

      // 敵グラフィックを設定
      game.rootScene.addChild(enemy.sprite);

      // 出会った時の動作
      //  ここではとにかく逃げてみる。
      //   →成功した場合は成功メッセージを、失敗した場合はそのままペナルティへ
      if(enemy.nigechi > 50){ // 敵の逃げ値51以上は必ず逃げられる
          msgLabel.text = msgLabel.text + '逃げ成功<br>';
      } else if( (enemy.nigechi > 30) && (second % 2 == 1) ) {
        // 逃げ値が50以下30超えの値の場合、かつ、現在秒が奇数の場合
        msgLabel.text = msgLabel.text + 'なんとか逃げ成功<br>';
      } else { // 他のケース = 逃げられなかった
        msgLabel.text = msgLabel.text + '逃げられなかったorz<br>';
        // 攻撃を食らうペナルティ
        msgLabel.text = msgLabel.text + enemy.attack(level);
      }
      // メッセージを設定
      game.rootScene.addChild(msgLabel);

    };
    game.start();
 };

動作イメージ

  • enchantを使わなかった時と何が変わったかを見比べてみるとよいかもしれません
  • 重複している部分はわざとそのまま残しています。特に敵に関する情報ですが、ほとんどが同じ計算式を使っているのに別々に書いています。
    • メッセージ表示処理も、本当は一回一回msgLabel = msgLabel + "xxxxxx";みたいにするもんじゃないと思う
    • 本当は"ダメージxxx"なんかは、”ダメージ”を出すラベル処理とダメージの値を出す処理を分けておかないと、多分、意味がない
    • ぶっちゃけ、この書き方はダサイ。
    • でも、どうまとめるのがいいかは、人それぞれ。今回は文法例から始めたのも、正直ちょっと苦しいところ
  • 良い例は世の中にたくさんあるので、そちらを参考に自分にとって書きやすいやり方を身につければいいかと。