なでしこを明後日の方向に

日本語プログラム言語なでしこを応援しています

なでしこでゲーム作る話  #2 キャラにイメージを使わない

ゲームに絵は付き物なので、イメージ部品を使っていきます。
ここではキャラクター1つにイメージ1つを割り当てることはしません
大きなイメージに画像コピーで描画していきます。

キャラごとにイメージを用意しない理由

・前後の入れ替えの管理が面倒
奥のものが手前のもので当然隠れるのですが、イメージ部品には「最前面」「最背面」でしか前後に移動できません。
手札のカードを並び替えたつもりが手前と奥がごっちゃに…なんてことも。

・母艦の右や下のほうに置くとスクロールバーが出る
画面外にすっと移動させたつもりが、スクロールバーがでます。
レイアウトを「全体」にしたパネルに乗せれば回避できるかも。

・イメージの移動は処理が遅い
X,Yを移動させると、すっごい処理時間がかかります。
100回の移動で30ミリ秒くらい。
秒間30フレームで1フレームあたり33ミリ秒ですから、あまりイメージの移動だけに処理時間を使いたくありません。

気にしすぎない

……以上のケースにあてはまらないゲームはいくらでもあります。
比較的簡素なゲームの場合は気にせず、キャラごとにイメージを作ってください。
ただ、制作途中にゲームの描画方法を変えるとすごくたいへんです(敗北経験あり)

なでしこでゲーム作る話  #1

ゲームを作るときの基本設計として、「イベントドリブン型」と「ゲームループ型」があります。
「イベントドリブン型」はGUIのイベント、クリックした時は~やキー押した時は~で進むタイプです。
「ゲームループ型」は無限ループ+待つを基本に、「キー状態」でゲームが進行するタイプです。

イベントドリブンだと操作性に難があったり、演出(ウエイト)のしにくさがネックになります。
なので「ゲームループ型」を基本にしていきます。

ゲームループの基本形

ゲームループフラグとは変数
●ゲームループ開始
 ゲームループフラグ=1
 (ゲームループフラグ==1)ループ
   操作取得()    # 1
   現在シーン更新 # 2
   現在シーン描画 # 3
   描画更新()    # 4
   0.05秒待つ    # 5

●ゲームループ停止
 ゲームループフラグ=0

・操作取得()    # 1
キー状態やマウスの情報を取得して変数に入れておきます。

・現在シーン→更新 # 2
キャラの移動など。
座標データやフラグなどを更新。
キーの状態で条件分岐するときは#1で取得した情報を参照します。

・現在シーン→描画 # 3
座標データをもとに描画。 レイヤー(可視はオフ)に描画します。

・描画更新()    # 4
レイヤーを統合して可視がオンのイメージに画像コピーします。

・0.05秒待つ    # 5
仮に0.05秒と書いてありますが、システム時間をみて微調整するといい感じになります。

GUI部品の用意を忘れてた

イメージ部品をいくつか用意しますが、キャラをイメージ部品で表示することはしません。
可視がオンの表イメージが1枚。 これが目に見える画像になります。
そのほかに、可視がオフのレイヤーを数枚、可視がオフの裏イメージを1枚、可視がオフのキャッシュを1枚。
画像コピーや画像合成で重ねていきます。

なんでキャラごとにイメージ作らないのか?とかを次回に書こうと思います。

●ナデシコシンタックスハイライト(txtを) //その3 完成

!変数宣言必要
!配色番号 = 1 //1…背景が白、文字が黒  2…背景が黒、文字が白
結果とは変数

STYLEとはハッシュ
//<span style="{STYLE@type}"> </span>
#type	配色番号=1	配色番号=2
「
文字列	color:blue;	color:#FFFF00;
コメント	color:green;	color:#999999;
助詞	color:#A0522D;	color:#00ff00;
関数	color:#ff00ff;	color:#ff00ff;
記号	color:#00BFFF;	color:#00ffff;
宣言	color:blue;	color:#ffafc9;
予約語	color:blue;	color:#00ffff;
定数	color:red;	color:red;
」TSV取得して反復
  もし対象==「」ならば続ける
  STYLE(対象[0]) = 対象[配色番号]

//タグで囲うとか、引用符をつけるとか
●仕上げ(htmlを)
 preタグとは変数
 配色番号条件分岐
   1ならば、preタグ = 『<pre style="background-color:#eeeeee; color:#000000">』
   2ならば、preタグ = 『<pre style="background-color:#333333; color:#ffffff">』
   違えば、preタグ = 「pre>」
 html = 「{preタグ}<code>{html}</code></pre>」
 html戻す

/* カンニング用
 background-color:#ffffff; 
 color:red;
 color:#ffffff;
*/

#----------------------
変換テーブルとは変数
//endあり:「{first}*{end}」でワイルドカードマッチ
//endなし:firstでワイルドカードマッチ  にあてはまるようにする
#タイプ	開始	終了	をタブ区切りでいれる(改行は\n)
#type	first	end	の変数に入る
変換テーブル=「
文字列	{カッコ}	{カッコ閉じ}
文字列	『	』
文字列	"	"
コメント	/\*	\*/
コメント	[=//|'|#|#|※]	\n
関数	[=●|*|■]	\n
関数	・[*!\(~ \n]
記号	[+\+\-\*\/\=\%\^\<\>\(\)\!\[\]\\\&\@\|]
記号	[++-×÷=%^<>()![]¥&@|≦≧→←~]
宣言	[=とは変数|とはハッシュ|とは配列|とはボタン|とはラベル|とはエディタ|とはメモ|とはフォーム|とはパネル|とはスプリッタ]
助詞	[=とは|は|について|ならば|なら|でなければ|から|ここまで|まで|までを|までの|で|を|の|が|に|へ|と|して|だけ|くらい|なのか|として|より|ほど|など|って|では|て]
予約語	[=もし|違えば|それ|対象|その|ループ|繰り返す|条件分岐|反復|戻す|戻る|続ける]
予約語	[=母艦|かつ|または]
定数	[=はい|いいえ|改行|必要|不要]
定数	[+1234567890]
」TSV取得
//「宣言」はプログラム部分に例外処理をしてあります
//保留  { } 、。*(掛け算)::,.▲/

#----------------------#----------------------
●ナデシコシンタックスハイライト(txtを)
 oldtxtとは変数  //無限ループ検知
 firstとは変数
 endとは変数
 パターンとは変数
 typeとは変数  //html修飾タイプ
 hitとは変数
 posとは変数
 minposとは変数
 minhitとは変数
 mintypeとは変数
 結果=「」
 (txt<>「」)ループ
   oldtxt=txt
   minpos=-1 //初期化 未発見
   変換テーブル反復
     もし対象[0]==「」ならば続ける
     type = 対象[0]
     first = 対象[1]
     end = 対象[2]
     もしend==「」でなければ
       パターン = 「{first}*{end}」
     違えば
       パターン = first
     hit = txtパターンワイルドカードマッチ
     もしhit==「」ならば続ける
     
     pos = txthit文字検索
     もしpos<=0ならばエラー発生 //マッチしたのに検索に失敗?
     
     //いちばん左にヒットしたパターンを記録
     もしminpos==-1またはpos<minposならば
       //例外処理:空白に装飾は要らないのでトリムしてみる
       hit=hitトリム
       minpos=pos
       minhit=hit
       mintype=type
   //反復ここまで
   
   //もうヒットするものがない
   もしminpos==-1ならば
     txtテキスト出力
     txt=「」
     抜ける
   違えば
     txtminhitまで切り取る//txtから消す
     それテキスト出力
     minhitmintypeマークアップ出力
   もしoldtxt=txtならば
     「無限ループの可能性があります」言う
     デバッグ
 結果戻す

●テキスト出力(txtを)
 txt=txtHTML変換
 結果txt追加
●マークアップ出力(txtをtypeで)
 txt=txtHTML変換
 もしtype==「宣言」ならば//宣言だけ例外処理
   マークアップ出力(「とは」「助詞」)
   txtから「とは」まで切り取る//切り取って捨てる
 styleとは変数
 style=STYLEtype
 txt=「<span style="{style}">{txt}</span>」
 結果txt追加

●HTML変換(txtを)
 txt=txt「&」「&amp;」置換
 txt=txt「<」「&lt;」置換
 txt=txt「>」「&gt;」置換
 txt=txtタブ「&#09;」置換
 txt戻す
#----------------------#----------------------
//実行部分
クリップボード取得
それナデシコシンタックスハイライト
それ仕上げ
コピー
おわり

完成!(予定)です。
なでしこプログラムをクリップボードにコピーした状態で実行すると、シンタックスハイライト(HTML修飾)をつけてクリップボードに返します。
完成品のサンプルは上記そのものです。

色はセンスある人が提示してくれたら変えていきたいです。
HTMLとスタイルシートの知識が付け焼き刃なので、そこも指摘があればなおしましょう。
処理の高速化は……いらないかな?

!配色番号 = 1 の部分を2にすると黒背景モードになります。
↓実行結果はこんな感じ

コピーボタンとはボタン
そのクリックした時ボタンイベント
●ボタンイベント
 クリップボード取得してコピー

●ナデシコシンタックスハイライト(txtを) //その2


!変数宣言必要
結果とは変数

#----------------------
変換テーブルとは変数
//endあり:「{first}*{end}」でワイルドカードマッチ
//endなし:firstでワイルドカードマッチ  にあてはまるようにする
#タイプ	開始	終了	をタブ区切りでいれる(改行は\n)
#type	first	end	の変数に入る
変換テーブル=「
文字列	{カッコ}	{カッコ閉じ}
文字列	『	』
文字列	"	"
コメント	/\*	\*/
コメント	[=//|'|#|#|※]	\n
関数	[=●|*|■]	\n
関数	・[*!\(~ \n]
記号	[+\+\-\*\/\=\%\^\<\>\(\)\!\[\]\\\&\@\|]
記号	[++-×÷=%^<>()![]¥&@|≦≧→←~]
宣言	[=とは変数|とはハッシュ|とは配列|とはボタン|とはラベル|とはエディタ|とはメモ|とはフォーム|とはパネル|とはスプリッタ]
助詞	[=とは|は|について|ならば|なら|でなければ|から|ここまで|まで|までを|までの|で|を|の|が|に|へ|と|して|だけ|くらい|なのか|として|より|ほど|など|って|では|て]
予約語	[=もし|違えば|それ|対象|その|ループ|繰り返す|条件分岐|反復|戻す|戻る|続ける]
予約語	[=母艦|かつ|または]
定数	[=はい|いいえ|改行|必要|不要]
定数	[+1234567890]
」TSV取得
//「宣言」はプログラム部分に例外処理をしてあります
//保留  { } 、。*(掛け算)::,.▲/

#----------------------
!配色番号 = 2 //1…背景が白、文字が黒  2…背景が黒、文字が白

STYLEとはハッシュ
//<span style="{STYLE@type}"> </span>
#type	配色番号=1	配色番号=2
「
文字列	color:blue;	color:#FFFF00;
コメント	color:green;	color:#999999;
助詞	color:#A0522D;	color:#00ff00;
関数	color:#ff00ff;	color:#ff00ff;
記号	color:#00BFFF;	color:#00ffff;
宣言	color:blue;	color:#ffafc9;
予約語	color:blue;	color:#00ffff;
定数	color:red;	color:red;
」TSV取得して反復
  もし対象==「」ならば続ける
  STYLE(対象[0]) = 対象[配色番号]

//タグで囲うとか、引用符をつけるとか
●仕上げ(htmlを)
 html = 「<pre><code>{改行}{html}{改行}</code></pre>」
 html戻す

/* カンニング用
 background-color:#ffffff; 
 color:red;
 color:#ffffff;
*/
#----------------------#----------------------
●ナデシコシンタックスハイライト(txtを)
 oldtxtとは変数  //無限ループ検知
 firstとは変数
 endとは変数
 パターンとは変数
 typeとは変数  //html修飾タイプ
 hitとは変数
 posとは変数
 minposとは変数
 minhitとは変数
 mintypeとは変数
 結果=「」
 (txt<>「」)ループ
   oldtxt=txt
   minpos=-1 //初期化 未発見
   変換テーブル反復
     もし対象[0]==「」ならば続ける
     type = 対象[0]
     first = 対象[1]
     end = 対象[2]
     もしend==「」でなければ
       パターン = 「{first}*{end}」
     違えば
       パターン = first
     hit = txtパターンワイルドカードマッチ
     もしhit==「」ならば続ける
     
     pos = txthit文字検索
     もしpos<=0ならばエラー発生 //マッチしたのに検索に失敗?
     
     //いちばん左にヒットしたパターンを記録
     もしminpos==-1またはpos<minposならば
       //例外処理:空白に装飾は要らないのでトリムしてみる
       hit=hitトリム
       minpos=pos
       minhit=hit
       mintype=type
   //反復ここまで
   
   //もうヒットするものがない
   もしminpos==-1ならば
     txtテキスト出力
     txt=「」
     抜ける
   違えば
     txtminhitまで切り取る//txtから消す
     それテキスト出力
     minhitmintypeマークアップ出力
   もしoldtxt=txtならば
     「無限ループの可能性があります」言う
     デバッグ
 結果戻す

●テキスト出力(txtを)
 txt=txtHTML変換
 結果txt追加
●マークアップ出力(txtをtypeで)
 txt=txtHTML変換
 もしtype==「宣言」ならば//宣言だけ例外処理
   マークアップ出力(「とは」「助詞」)
   txtから「とは」まで切り取る//切り取って捨てる
 styleとは変数
 style=STYLEtype
 txt=「<span style="{style}">{txt}</span>」
 結果txt追加

●HTML変換(txtを)
 txt=txt「&」「&amp;」置換
 txt=txt「<」「&lt;」置換
 txt=txt「>」「&gt;」置換
 txt=txtタブ「&#09;」置換
 txt戻す
#----------------------#----------------------
//実行部分
クリップボード取得
それナデシコシンタックスハイライト
それ仕上げ
コピー
おわり

なでしこエディタの「配色に黒を用いる」にならって色付けしてみました。
前回よりは見やすいかと思います。

気になるのは処理速度がやや遅いことで、1.2秒くらいかかります。
アルゴリズムは以下の感じ。
1. 全パターンでワイルドカードマッチをやって、検索でどこにあるのかを探す
2. ヒットしたもので一番左のものを記録
3. ヒット部分の前はテキストそのまま、ヒット部分は切り取ってタグをつける
4. 1に戻る
前回のヒット個所を記録しておいて、3で切り取った文字数を引いて、マイナスになっている場合のみワイルドカードマッチすれば多少は早くなるでしょうか。
そんなに頻繁に起動するプログラムでもないし、1秒ちょいなら許容範囲なのでこれでいいことにします。

あとは色のセンスがいい人が現れて調整してくれるとうれしい。

●ナデシコシンタックスハイライト(txtを)


!変数宣言必要
結果とは変数

#----------------------
変換テーブルとは変数
//endあり:「{first}*{end}」でワイルドカードマッチ
//endなし:firstでワイルドカードマッチ  にあてはまるようにする
#タイプ	開始	終了	をタブ区切りでいれる(改行は\n)
#type	first	end	の変数に入る
変換テーブル=「
文字列	{カッコ}	{カッコ閉じ}
文字列	『	』
文字列	"	"
コメント	/\*	\*/
コメント	[=//|'|#|#|※]	\n
関数	[=●|*|■]	\n
関数	・[*!\(~ \n]
記号	[+\+\-\/\*\=\(\)\!\[\]\\\&\@\|]
記号	[+@→←~=+×÷-]
宣言	[=とは変数|とはハッシュ|とは配列|とはボタン|とはラベル|とはエディタ|とはメモ|とはフォーム|とはパネル|とはスプリッタ]
助詞	[=とは|は|について|ならば|なら|でなければ|から|ここまで|まで|までを|までの|で|を|の|が|に|へ|と|して|だけ|くらい|なのか|として|より|ほど|など|って|では|て]
予約語	[=もし|違えば|それ|対象|その|ループ|繰り返す|条件分岐|反復|戻す|戻る|続ける]
予約語	[=母艦|かつ|または]
定数	[=はい|いいえ|改行|必要|不要]
定数	[+1234567890]
」TSV取得
//「宣言」はプログラム部分に例外処理をしてあります

#----------------------
STYLEとはハッシュ
//<span style="{STYLE@type}"> </span>
#type	style
「
文字列	color:blue;
コメント	color:green;
助詞	color:#A0522D;
関数	color:#ff00ff;
記号	color:#00BFFF;
宣言	color:blue;
予約語	color:blue;
定数	color:red;
」TSV取得して反復
  もし対象==「」ならば続ける
  STYLE(対象[0]) = 対象[1]

//タグで囲うとか、引用符をつけるとか
●仕上げ(htmlを)
 html = 「<pre><code>{改行}{html}{改行}</code></pre>」
 html戻す

/* カンニング用
 background-color:#ffffff; 
 color:red;
 color:#ffffff;
*/
#----------------------#----------------------
●ナデシコシンタックスハイライト(txtを)
 oldtxtとは変数  //無限ループ検知
 firstとは変数
 endとは変数
 パターンとは変数
 typeとは変数  //html修飾タイプ
 hitとは変数
 posとは変数
 minposとは変数
 minhitとは変数
 mintypeとは変数
 結果=「」
 (txt<>「」)ループ
   oldtxt=txt
   minpos=-1 //初期化 未発見
   変換テーブル反復
     もし対象[0]==「」ならば続ける
     type = 対象[0]
     first = 対象[1]
     end = 対象[2]
     もしend==「」でなければ
       パターン = 「{first}*{end}」
     違えば
       パターン = first
     hit = txtパターンワイルドカードマッチ
     もしhit==「」ならば続ける
     
     pos = txthit文字検索
     もしpos<=0ならばエラー発生 //マッチしたのに検索に失敗?
     
     //いちばん左にヒットしたパターンを記録
     もしminpos==-1またはpos<minposならば
       //例外処理:空白に装飾は要らないのでトリムしてみる
       hit=hitトリム
       minpos=pos
       minhit=hit
       mintype=type
   //反復ここまで
   
   //もうヒットするものがない
   もしminpos==-1ならば
     txtテキスト出力
     txt=「」
     抜ける
   違えば
     txtminhitまで切り取る//txtから消す
     それテキスト出力
     minhitmintypeマークアップ出力
   もしoldtxt=txtならば
     「無限ループの可能性があります」言う
     デバッグ
 結果戻す

●テキスト出力(txtを)
 txt=txtHTML変換
 結果txt追加
●マークアップ出力(txtをtypeで)
 txt=txtHTML変換
 もしtype==「宣言」ならば//宣言だけ例外処理
   マークアップ出力(「とは」「助詞」)
   txtから「とは」まで切り取る//切り取って捨てる
 styleとは変数
 style=STYLEtype
 txt=「<span style="{style}">{txt}</span>」
 結果txt追加

●HTML変換(txtを)
 txt=txt「&」「&amp;」置換
 txt=txt「<」「&lt;」置換
 txt=txt「>」「&gt;」置換
 txt=txtタブ「&#09;」置換
 txt戻す
#----------------------
//実行部分
クリップボード取得
それナデシコシンタックスハイライト
それ仕上げ
コピー
おわり

試作品ができました。
色のセンスが残念ですが、それ以外はいい感じだと思います。
背景を白色にして通常文字が黒色ならそれっぽくなると思います。
……どこをかえるといいのかわかりません。preタグかな?

マッチのパターンも全部は網羅してませんが、だいたいOKでしょう。
上のほうが設定部分、その下が関数。 130行くらいです。
下の5行が実行部分で、クリップボードの内容をいじくってその後クリップボードに戻します。 「仕上げ」という関数はpreタグで囲うとかですね。

できあがりは以下のようになります。

<pre><code>
<span style="color:#00BFFF;">!</span>変数宣言<span style="color:#A0522D;"></span><span style="color:red;">必要</span>
結果<span style="color:#A0522D;">とは</span><span style="color:blue;">変数</span>
</code></pre>

実はHTMLにろくに触れたことがないです。 慣れている人から見たら変な書き方をしているかも。

なでしこで何かする

ブログのテーマ

日本語プログラミング言語「なでしこ」に関することを書いていきたいと思います。
そのうちなでしこでゲームをつくるはず。

マークダウンに挑戦

ブログにはマークダウンという記法があるので触ってみることに。
見出し部分は####で書くらしいです。

プログラムの見栄えを見る

マークダウンでプログラムソースがきれいに出力されるそうですね
rubyならRPGツクールVXAceで触ったことがあるので貼り付けてみます

def drawMainblock
 4.times{ |num|
    x[num] = (@mainblock.x + @mainblock.block[num].x)*BLOCKSIZE
    y[num] = (@mainblock.y + @mainblock.block[num].y)*BLOCKSIZE
    y[num] += @mainblock.yy/1000*BLOCKSIZE
    @imgBa.blt(x,y, @imgMainblock[@mainblocktype], @blockrect)
}

自動でカラフルになりました

今度はなでしこプログラムでやってみましょう

コピーボタンとはボタン
そのクリックした時は~ボタンイベント
●ボタンイベント
 クリップボード取得してコピー

対応してないから無理ですね。
このままではなでしこが流行らないので、なでしこエディタを参考に着色しましょう。(手作業)

母艦最前面
コピーボタンとはボタンクリックした時ボタンイベント
●ボタンイベント
 クリップボード取得してコピー

はい、色がつきました。
ちなみにコレはクリップボードにあるテキストをコピーしてクリップボードにいれるプログラムです。
主にネットからコピーしたものをエクセルに貼り付ける前に使います。
プレーンテキストになる優れものです。

カラフルじゃないと見る側も疲れると思うので、 まずはなでしこプログラムをなHTMLにするプログラムを作ることにしましょう。