<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>仮ぶろぐ</title>
	<atom:link href="http://plusb.jp/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://plusb.jp/blog</link>
	<description>今更なことをそれでもつらづらと書くブログ</description>
	<lastBuildDate>Tue, 07 May 2013 09:06:48 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>BINGO 補足</title>
		<link>http://plusb.jp/blog/?p=810</link>
		<comments>http://plusb.jp/blog/?p=810#comments</comments>
		<pubDate>Mon, 23 Apr 2012 03:35:55 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=810</guid>
		<description><![CDATA[BINGOを公開しましたが、補足です。 ジングルは音楽素材/魔王魂さんを利用させていただいています。 CSS3を多用しているのでFirefox,chrome推奨。ie9は△です。 ソースは好きにしてください。ライツはソー &#8230; <a href="http://plusb.jp/blog/?p=810">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="/dqfw/bingo/bingo.html">BINGO</a>を公開しましたが、補足です。</p>
<ol>
<li>ジングルは<a href="http://maoudamashii.jokersounds.com/">音楽素材/魔王魂</a>さんを利用させていただいています。</li>
<li>CSS3を多用しているのでFirefox,chrome推奨。ie9は△です。</li>
<li>ソースは好きにしてください。ライツはソースに記載されています。</li>
<li>直接余興に使用してもらってもＯＫです。</li>
<li>裏機能があるので、ソースが冗長です。</li>
<li><a href="http://mickeyavenue.com/fonts/waltograph/">ディズニーフォント</a>を使用しています。クライアント側にインストールする必要がありますが、いかにもでいい感じです。</li>
</ol>
<p>実際に使用したところ、会場のプロジェクターの彩度が低くて選択済みの数字がわかりにくいと不評でしたorz<br />
そのあたりは、スタイルシートで調整してください。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=810</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptで非復元抽出アルゴリズム</title>
		<link>http://plusb.jp/blog/?p=803</link>
		<comments>http://plusb.jp/blog/?p=803#comments</comments>
		<pubDate>Mon, 23 Apr 2012 03:25:29 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=803</guid>
		<description><![CDATA[非復元抽出アルゴリズム for JavaScript 結婚式の二次会の余興でBINGOゲームを作る事になりました(一番最後に新郎がビンゴを引き当てるという仕掛け付きなので自作する事にしました）。 で、BINGOゲームは1 &#8230; <a href="http://plusb.jp/blog/?p=803">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>非復元抽出アルゴリズム for JavaScript</p>
<p>結婚式の二次会の余興でBINGOゲームを作る事になりました(一番最後に新郎がビンゴを引き当てるという仕掛け付きなので自作する事にしました）。<br />
で、BINGOゲームは1～75の数字をどんどん抽選していく、いわゆる非復元抽出です。</p>
<p>JavaScriptで実装しようと考えていたときにアルゴリズムがふと思い浮かんだので備忘録として記録しておきます。</p>
<p>昔は「乱数で適当に抽選して重複したら抽選しなおす」方法を良く使っていました。<br />
実用的には問題ないですが、抽選のやり直しが発生したり抽選結果を保持する必要があったりでかっこよくはありません。</p>
<p>JavaScriptで実装する前提で考えた結果、抽選結果を単純に消していけば良いことに気づきました。<br />
C言語だとこれ自体がめんどくさい処理でしたが…</p>
<pre>
//種
var sheed=[1,2,3,4,5,6,7,8,9,10...75];

function choose() {
  //番号選択
  if (sheed.length == 0) {
      <span style="color:red">//エラー処理</span>
  }
  var num = sheed[Math.floor(Math.random() * sheed.length)];
  var value = sheed[num];

  //選んだ番号は取り出してしまう。
  sheed.splice(num,1);

  return value;
}
</pre>
<p><a href="http://plusb.jp/blog/?p=806">使用例</a></p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=803</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptでBINGO -ざっくり設計</title>
		<link>http://plusb.jp/blog/?p=806</link>
		<comments>http://plusb.jp/blog/?p=806#comments</comments>
		<pubDate>Mon, 23 Apr 2012 03:24:24 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ゲーム作成]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=806</guid>
		<description><![CDATA[ビンゴをJavaScriptで作ってみました。 1.概要 ビンゴゲームWebアプリケーションを作成する。 ただし、作成するのは抽選機能のみ。Webブラウザー上で、グラフィカルに抽選する機能を提供する。 （ビンゴカードをオ &#8230; <a href="http://plusb.jp/blog/?p=806">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>ビンゴをJavaScriptで作ってみました。<br />
<a href="http://plusb.jp/blog/wp-content/uploads/2012/04/bingo.png"><img src="http://plusb.jp/blog/wp-content/uploads/2012/04/bingo-300x224.png" alt="BINGO 画面" title="bingo" width="300" height="224" class="alignnone size-medium wp-image-816" /></a></p>
<p><span id="more-806"></span></p>
<h2>1.概要</h2>
<p>ビンゴゲームWebアプリケーションを作成する。<br />
ただし、作成するのは抽選機能のみ。Webブラウザー上で、グラフィカルに抽選する機能を提供する。<br />
（ビンゴカードをオンラインから取得してもおもしろいかも、全員がスマートフォン時代ならいけるかも）</p>
<h2>2.用件</h2>
<h3>2.1 機能用件</h3>
<p>数字は1～75<br />
抽選中のアイコンは大きく表示する<br />
全ての数字のアイコンを画面上に表示しておく<br />
抽選済みの数字は強調表示される<br />
抽選中の演出を用意する。<br />
抽選の乱数は、基底値を固定すると同じ値が選択される<br />
レイアウトは独立して変更可能とする</p>
<h3>2.2 非機能用件</h3>
<p>言語は、JavaScript+CSS3(for HTML5)</p>
<h2>3.設計</h2>
<h3>3.1概念抽出</h3>
<ul>
<li>　数字アイコン
</li>
<li>　点灯する、消灯する
</li>
<li>　カレントのアイコン
</li>
<li>　レイアウト
</li>
<li>　抽選する
</li>
<li>　クリアする（初期化する）
</li>
</ul>
<h2>3.2 シナリオ</h2>
<h3>　3.2.1 クリア<br />
<h3>
　　数字アイコン1～75を消灯状態で表示する<br />
　　カレントアイコンを消灯状態で表示する<br />
　　乱数、抽選情報を初期化する</p>
<h3>　3.2.2 抽選する</h3>
<dl>
　　
<dt>抽選用演出を開始する</dt>
<dd>演出は、ランダムに未抽選の数字の選択（選択されると数字アイコンを点灯し、次の数字が選ばれたら消灯する）を繰り返す。
</dd>
<p>　　
<dt>演出を終了する</dt>
<dd>最終的な抽選を実施して、選択された数字アイコンを点灯させる。<br />
最終的に選ばれた数字アイコンは数回点滅下のちに点灯する。<br />
さらにカレントのアイコンに数字を表示する。
</dd>
</dl>
<p>考えがまとまったので後はとっとと実装しまして、<br />
<a href="/dqfw/bingo/bingo.html">出来上がり</a>。<br />
ソース:<a href="/dqfw/bingo/js/bingo.js">bingo.js</a>,<a href="/dqfw/bingo/js/bingo_ctl.js">bingo_ctl.js</a><br />
<a href="/blog/?p=810">補足</a>も確認して下さい。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=806</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dq 0.6 リリース</title>
		<link>http://plusb.jp/blog/?p=795</link>
		<comments>http://plusb.jp/blog/?p=795#comments</comments>
		<pubDate>Thu, 25 Aug 2011 15:30:38 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[dq]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=795</guid>
		<description><![CDATA[まだ実装すべき機能は残っていますが、ライブラリを0.6.0として区切りました。 そろそろ、Firefoxでもっさりしている原因を突き止めないと・・・ ライブラリー RPG 習作 戦闘テスト 戦闘の表示効果や効果音を改善し &#8230; <a href="http://plusb.jp/blog/?p=795">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>まだ実装すべき機能は残っていますが、ライブラリを0.6.0として区切りました。<br />
そろそろ、Firefoxでもっさりしている原因を突き止めないと・・・<br />
<span id="more-795"></span><br />
<a href="http://plusb.jp/dq/">ライブラリー</a><br />
<a href="http://plusb.jp/dq/samples/rpg_learning.html">RPG 習作</a><br />
<a href="http://plusb.jp/dq/samples/bt_test.html">戦闘テスト</a></p>
<ul>
<li>戦闘の表示効果や効果音を改善しました。</li>
<li>NPCのAIと移動機能を実装</li>
<li>お店機能を改善</li>
<li>装備による追加効果に対応</li>
<li>マップエディターを改訂（マップの追加やUIを改善)</li>
<li>UIの見栄えを少し変更(CSS3を一部使用）</li>
<li>UIにスピンボックスを追加</li>
<li>スマートフォンを想定したRTG用のライブラリを作成</li>
<li>不具合をそこそこ修正</li>
</ul>
<p><a href="http://plusb.jp/blog/wp-content/uploads/2011/08/nantara.png"><img src="http://plusb.jp/blog/wp-content/uploads/2011/08/nantara.png" alt="" title="ローラ救出" width="245" height="215" class="alignnone size-full wp-image-776" /></a><br />
<a href="http://plusb.jp/blog/wp-content/uploads/2011/08/map_editor.png"><img src="http://plusb.jp/blog/wp-content/uploads/2011/08/map_editor-300x208.png" alt="マップエディター" title="マップエディター" width="300" height="208" class="alignnone size-medium wp-image-746" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=795</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dq(rpg) 2011-08-22</title>
		<link>http://plusb.jp/blog/?p=789</link>
		<comments>http://plusb.jp/blog/?p=789#comments</comments>
		<pubDate>Mon, 22 Aug 2011 16:21:54 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[dq]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=789</guid>
		<description><![CDATA[ナイトリービルドを更新。 主にお店関連の不具合対応 既知の不具合を修正したら、0.6のリリースしようかと。 消費アイテムのみ複数保持するように変更 装備を買ったら、その場で装備する選択肢を追加 アイテムを交換できない不具 &#8230; <a href="http://plusb.jp/blog/?p=789">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>ナイトリービルドを更新。<br />
主にお店関連の不具合対応<br />
既知の不具合を修正したら、0.6のリリースしようかと。<br />
<span id="more-789"></span></p>
<ol>
<li>消費アイテムのみ複数保持するように変更</li>
<li>装備を買ったら、その場で装備する選択肢を追加</li>
<li>アイテムを交換できない不具合修正</li>
<li>アイテムを売った際にお金が増えない不具合を修正</li>
<li>メッセージにスクリプト指定の不具合を修正</li>
<li>宿屋のジングルのタイミングを修正</li>
</ol>
<p><a href="http://plusb.jp/dqfw/">ナイトリービルド</a>を更新。<br />
<a href="http://plusb.jp/dqfw/samples/rpg_learning.html">習作</a></p>
<p>補足ですが、キャッシュが効いている場合に<code>CTRL+R</code>などでページを再読み込みする必要があります。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=789</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VS2010で嵌まった(error LNK2022)</title>
		<link>http://plusb.jp/blog/?p=782</link>
		<comments>http://plusb.jp/blog/?p=782#comments</comments>
		<pubDate>Sat, 20 Aug 2011 15:03:12 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[プログラミング]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=782</guid>
		<description><![CDATA[Visual Studio 2008からVisual studio 2010　への移行で嵌まったので備忘録。 VS2010でコンパイルすると以下のエラーがでてリンクが出来ない。 error LNK2022: メタデータの &#8230; <a href="http://plusb.jp/blog/?p=782">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Visual Studio 2008からVisual studio 2010　への移行で嵌まったので備忘録。<br />
VS2010でコンパイルすると以下のエラーがでてリンクが出来ない。<br />
<code>error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません:</code><br />
<span id="more-782"></span><br />
素性としてネイティブとマネージの混合プロジェクトで、元々はVS2003で構築した物です。<br />
結局、原因としては、<code>_WIN32_WINNT</code>をコンパイルスイッチで指定していたことです。<br />
さらに一部のコードでは別のバージョンが内部的に指定されていました。これがどうも良くなかったみたいですね。</p>
<p>余談ですが、VS2003当時は、デフォルトの<code>WINVER</code>の値が低くNTタイマーを使用するために明示的に<code>_WIN32_WINNT</code>バージョンを指定していましたが、<a href="http://msdn.microsoft.com/ja-jp/library/6sehtctf.aspx">ここ</a>にあるようにWindows 98などの古いOSが非サポートになったおかげで、バージョンを明示しなくてもNTタイマーが使用できるようになっていました。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=782</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dq(rpg) 2011-08-20</title>
		<link>http://plusb.jp/blog/?p=775</link>
		<comments>http://plusb.jp/blog/?p=775#comments</comments>
		<pubDate>Sat, 20 Aug 2011 14:38:57 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[dq]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[rpg]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=775</guid>
		<description><![CDATA[ナイトリービルドを更新。 NPCのイベント処理を追加して、ローラ姫を救出出来るようにしました。 既知の不具合を修正したら、0.6のリリースしようかと。 NPCと自動戦闘可能にしました。 NPCの表示・非表示をフラグで指定 &#8230; <a href="http://plusb.jp/blog/?p=775">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>ナイトリービルドを更新。<br />
NPCのイベント処理を追加して、ローラ姫を救出出来るようにしました。<br />
既知の不具合を修正したら、0.6のリリースしようかと。<br />
<span id="more-775"></span></p>
<ol>
<li>NPCと自動戦闘可能にしました。</li>
<li>NPCの表示・非表示をフラグで指定可能にしました。</li>
<li>NPCの移動APIを追加</li>
<li>戦闘時のメッセージ表示を改善</li>
<li>メッセージにスクリプト指定に対応</li>
<li>ジングルの再生遅延を改善</li>
</ol>
<p><a href="http://plusb.jp/blog/wp-content/uploads/2011/08/nantara.png"><img src="http://plusb.jp/blog/wp-content/uploads/2011/08/nantara.png" alt="" title="ローラ救出" width="245" height="215" class="alignnone size-full wp-image-776" /></a><br />
<a href="http://plusb.jp/dqfw/">ナイトリービルド</a>を更新。<br />
<a href="http://plusb.jp/dqfw/samples/rpg_learning.html">習作</a></p>
<p>補足ですが、キャッシュが効いている場合に<code>CTRL+R</code>などでページを再読み込みする必要があります。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=775</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptでバトルシティー</title>
		<link>http://plusb.jp/blog/?p=772</link>
		<comments>http://plusb.jp/blog/?p=772#comments</comments>
		<pubDate>Sun, 14 Aug 2011 02:12:27 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ゲーム作成]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[battlecity]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=772</guid>
		<description><![CDATA[例によってライブラリを作り込むための参考にバトルシティー的なものを作ってみました。 今回はゲームとして成立するところまでは作るつもりはないのですが、敵のアルゴリズムをどうしたら良いのかがわかりませんorz しかもiPho &#8230; <a href="http://plusb.jp/blog/?p=772">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>例によってライブラリを作り込むための参考にバトルシティー的なものを作ってみました。<br />
今回はゲームとして成立するところまでは作るつもりはないのですが、敵のアルゴリズムをどうしたら良いのかがわかりませんorz<br />
しかもiPhoneでは処理が重すぎるようで、本末転倒。<br />
<span id="more-772"></span><br />
ライブラリ:<a href="dq-canvas.js">dq-canvas.js</a><br />
<a href="http://plusb.jp/dqfw/samples/battlecity.html">battlecity.html</a><br />
フレーム内を一度クリックするとキーが効くようになります。十字キーに対応しています。<br />
Aボタンは&#8217;V'キー<br />
Bボタンは&#8217;C'キー<br />
です。<br />
<iframe src="http://plusb.jp/dqfw/samples/battlecity.html" width="320" height="426" style="overflow: hidden;"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=772</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>テトリスをJavascriptで作る 実装編(3)</title>
		<link>http://plusb.jp/blog/?p=760</link>
		<comments>http://plusb.jp/blog/?p=760#comments</comments>
		<pubDate>Mon, 08 Aug 2011 08:26:52 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ゲーム作成]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Tetris]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=760</guid>
		<description><![CDATA[実装編　その３です。 ステージやラインについて解説します。 その１ その２ ソース:tetris.js ライブラリー:dq-rtg.js,dq-cancas.js(実際に動かすにはライブラリのコアコンポーネントとjQue &#8230; <a href="http://plusb.jp/blog/?p=760">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>実装編　その３です。<br />
ステージやラインについて解説します。<br />
<a href="http://plusb.jp/blog/?p=699">その１</a><br />
<a href="http://plusb.jp/blog/?p=709">その２</a><br />
ソース:<a href="http://plusb.jp/dq/samples/js/tetris.js">tetris.js</a><br />
ライブラリー:<a href="http://plusb.jp/dq/js/rtg/dq-rtg.js">dq-rtg.js</a>,<a href="http://plusb.jp/dq/js/dq-canvas.js">dq-cancas.js</a>(実際に動かすにはライブラリのコアコンポーネントとjQueryも必要です）。<br />
<a href="http://plusb.jp/blog/?p=694">できあがり</a><br />
<span id="more-760"></span></p>
<h3>TETRIS.Stageクラス</h3>
<p>ステージは22本(*1)のラインがあり、ラインは10個の粒（ブロック）で構成されています。<br />
簡単に言えば縦22x横10個の粒で構成されていることになります。<br />
*1 ゲームとして有効なのは20ラインですが、テトリミノが落下する位置として2ライン分追加しています。</p>
<p>ステージの役割は粒の管理で、ラインの削除判定や削除中のラインの状態を管理します。</p>
<h4>初期化</h4>
<p>ラインを作成します。</p>
<pre>
DQ.TETRIS.Stage = function (engine) {
    this._engine = engine;
    this.lines = [];
    for (var i = 0; i &lt; 22; i++) {
        this.lines.push(new DQ.TETRIS.Line(i));
    }
}
</pre>
<p>ゲーム開始時にライン上のチップを削除することで初期化します。</p>
<pre>
DQ.TETRIS.Stage.prototype = {
    left: DQ.TETRIS.STAGE_LEFT,
    top: -14,
    lines: [],
    clear: function () {
        for (var ln = 0; ln < this.lines.length; ln++) {
            for (var i = 0; i &lt; 10; i++) {
                if (this.lines[ln].chips[i]) {
                    this.lines[ln].chips[i].remove();
                    this.lines[ln].chips[i] = null;
                }
            }
        }
    }
}
</pre>
<h4>当たり判定</h4>
<p>Stageクラスが落下中のテトリミノがステージの壁やステージ上の粒にぶつかるかどうかの当たり判定を担当します。</p>
<pre>
    hitTest: function (mino, dx, dy) {
        ///&lt;summary&gt;
        ///指定のテトリミノの当たり判定をします。
        ///&lt;/summary&gt;
        ///&lt;param name="mino" type="Tetrimino"&gt;
        ///対象となるテトリミノを指定
        ///&lt;/param&gt;
        ///&lt;param name="dx", type="number"&gt;
        ///x方向の移動予定幅を指定
        ///&lt;/param&gt;
        ///&lt;param name="dy", type="number"&gt;
        ///y方向の移動予定幅を指定
        ///&lt;/param&gt;

        for (var i = 0; i &lt; 4; i++) {
            var chip = mino.chip(i);
            var cx = Math.floor((chip.x + dx - this.left) / DQ.TETRIS.CHIP_SIZE);
            var cy = Math.floor((chip.y + dy - this.top) / DQ.TETRIS.CHIP_SIZE);
            //wall
            if (cx < 0
                || 10 &lt;= cx
                || 22 &lt;= cy) {
                return true;
            }
            //chip
            if (this.lines[cy].chips[cx]) {
                return true;
            }
        }

        return false;
    }
}
</pre>
<p>落下中のテトリミノを構成する４つの粒に対して壁とステージ上の粒との当たり判定を実施します。<br />
ステージ上の粒の有無は、対象となる座標に粒のインスタンスがあるかどうかで判定しています。<br />
横移動の場合、<code>hitTest()</code>で<code>false</code>が返ると移動できません。<br />
落下処理の場合は、「遊び」状態へ遷移します。「遊び」状態が放置されると落下中のテトリミノはただの粒へと変化します。</p>
<h4>粒への移行</h4>
<p>落下が完了したテトリミノをラインへ粒として登録します。</p>
<pre>
{
    transChip: function (mino) {
        ///&lt;summary&gt;
        ///落下中だったテトリミノをチップへ変換します。
        ///&lt;/summary&gt;
        ///&lt;param name="mino" type="Tetrimino"&gt;
        ///変換するテトリミノを指定
        ///&lt;/param&gt;

        for (var i = 0; i &lt; 4; i++) {
            var chip = mino.chip(i);
            var cx = Math.floor((chip.x - this.left) / DQ.TETRIS.CHIP_SIZE);
            var ln = Math.floor((chip.y - this.top) / DQ.TETRIS.CHIP_SIZE);
            this.lines[ln].chips[cx] = new DQ.Screen.Canvas.Sprite({
                image: chipImg.client[0],
                x: cx * DQ.TETRIS.CHIP_SIZE + this.left,
                y: ln * DQ.TETRIS.CHIP_SIZE + this.top,
                width: DQ.TETRIS.CHIP_SIZE,
                height: DQ.TETRIS.CHIP_SIZE,
                dir: mino.type,
                animation: false,
                numberOfPause: 0
            });
            this._engine._canvas.push(this.lines[ln].chips[cx]);
        }
    }
}
</pre>
<p>テトリミノを構成する４つの粒を該当する座標の粒として登録します。<br />
粒のインスタンスは描画用の<code>Sprite</code>です。スプライトを作成する際には、座標系を粒から画面のpixel単位へ変換しています。<br />
作成したSpriteは、キャンバスへ登録します（これによって、粒の描画はキャンバス(*2)が適宜実行してくれます)。<br />
*2 念のためですが、このキャンバスは拙作のライブラリのキャンバスクラスの事です。</p>
<h4>削除判定</h4>
<p>ライン上に新しい粒が登録された後は、ラインの削除判定を実施します。</p>
<pre>
{
    eraseLine: function () {
        this._lineFlash = [];
        for (var i = 21; 2 <= i; i--) {
            if (this.lines[i].canErase()) {
                //削除可能なラインがあったのでフラッシュ状態へ移行
                this.mode = DQ.TETRIS.StageMode.Flash;
                this._elapse = 0;
                var line = new DQ.Screen.Canvas.Sprite({
                    y: i * DQ.TETRIS.CHIP_SIZE + this.top,
                    x: this.left,
                    width: DQ.TETRIS.CHIP_SIZE * 10,
                    height: DQ.TETRIS.CHIP_SIZE,
                    animation: false,
                    numberOfPause: 0,
                    image: flashImg.client[0]
                });
                this._lineFlash.push(line);
                engine._canvas.push(line);
            }
        }
        return this._lineFlash.length;
    },
</pre>
<p>全てのラインについて削除判定を行います。判定自体はラインクラスに任せていますが、ようはライン内の全ての領域に粒があれば削除可能です。<br />
削除可能なら画面効果用のスプライトを登録しています。<br />
この時点で、ゲーム全体の状態はゲーム中(Play)状態から削除中(Erase)状態へ遷移します。<br />
また、画面効果として削除可能なラインがフラッシュして、しばらくしてからラインが消え、またしばらくしてから全体が落下するようになっています。<br />
ちなみに、メソッドの名前が微妙だったりしますが、そこは目をつぶります。</p>
<h4>状態管理</h4>
<p>Stageクラスではラインが削除中の場合だけ状態を管理します。状態はUpdate()の呼び出しによる一定の時間経過後に遷移します。</p>
<pre>
{
    update: function () {
        if (this.mode == DQ.TETRIS.StageMode.None) {
            return;
        }
        this._elapse += 60 / TETRIS.fps;
        if (this.wait <= this._elapse) {
            //時間経過を超えた
            switch (this.mode) {
                case DQ.TETRIS.StageMode.Flash:
                    //フラッシュ中から削除中へ移行
                    this.mode = DQ.TETRIS.StageMode.Erase;
                    this._elapse = 0;
                    for (var i = 21; 2 <= i; i--) {
                        if (this.lines[i].canErase()) {
                            this.lines[i].clear();
                        }
                    }
                    for (var i = 0; i &lt; this._lineFlash.length; i++) {
                        this._lineFlash[i].remove();
                    }
                    this._lineFlash = [];
                    break;
                case DQ.TETRIS.StageMode.Erase:
                    //削除中から通常へ移行
                    this.mode = DQ.TETRIS.StageMode.None;
                    this._elapse = 0;
                    var count = 0;
                    for (var i = 21; 2 <= i; i--) {
                        if (this.lines[i].canDown()) {
                            this.lines.splice(i, 1);
                            count++;
                        }
                    }
                    //削除した分だけラインを追加
                    for (i = 0; i &lt; count; i++) {
                        this.lines.unshift(new DQ.TETRIS.Line(0));
                    }
                    //ライン番号を振り直す
                    for (i = 0; i &lt; 22; i++) {
                        this.lines[i].line(i);
                    }
                    break;
            }
        }
    }
}
</pre>
<p>ステージの状態は<code>None</code>→<code>Flash</code>→<code>Erase</code>→<code>None</code>へと遷移します。<br />
状態遷移後に経過時間を示す<code>_elapse</code>がクリアされ、一定時間経過後にイベント処理が実施されます。<br />
まず、Flash状態にある場合は削除可能なラインをクリアします。それからフラッシュ効果用のスプライトを削除(remove)します。<br />
（スプライトをremove()するとキャンバスクラスからも削除され、描画の対象から外れます。）<br />
次に削除状態にある場合は、ラインを落下させます。<br />
落下処理については、削除可能なラインを配列から削除して、削除した分のラインを配列の先頭に追加することで落下したように見せています。<br />
余談ですが、ぷよぷよなど粒自体が落ちていく場合にはこの手法は使えないですね。</p>
<h4>全体の状態遷移</h4>
<p><a href="http://plusb.jp/blog/?p=709">その２</a>では、割愛していた全体の状態遷移の管理です。<br />
updateメソッド中で、状態毎のチェックを実施しています。</p>
<pre>
    update: function () {
        var mode = DQ.TETRIS.Mode;
        switch (this.game) {
            case mode.Start:
            case mode.GameOver:
                return;
            case mode.Erase:
                //ラインの削除演出中
                this.stage.update();
                if (this.stage.mode == DQ.TETRIS.StageMode.None) {
                    //演出完了
                    this.game = DQ.TETRIS.Mode.Play;
                    //落下したラインに合わせてゴーストを移動
                    this.moveGhost();
                }
                break;
            case mode.Delay:
                //「遊び」中
                this._elapse += 60 / this.fps;
                if (this.wait <= this._elapse) {
                    this.game = DQ.TETRIS.Mode.Play;
                    this.stage.transChip(this.current);
                    this.current.remove();
                    this.shiftCurrent();
                    soundBox.play(1);

                    var n_line = this.stage.eraseLine();
                    if (n_line > 0) {
                        this.score.score += DQ.TETRIS.Game.ScoreTable[n_line];
                        this.score.line += n_line;
                        var pre = this.score.level;
                        this.score.level = Math.floor(this.score.line / 10) + 1;
                        if (pre != this.score.level) {
                            this.levelUp();
                        }
                        this.updateScore();

                        this.game = DQ.TETRIS.Mode.Erase;
                        return;
                    }
                }
                break;
            case mode.Play:
                //「落下中」
                if (this.isAccelerate()) {
                    if (this.current.y - this._startPos > DQ.TETRIS.CHIP_SIZE) {
                        this.score.score++;
                        this.updateScore();
                        this._startPos += DQ.TETRIS.CHIP_SIZE;
                    }
                }
                var dy = this.gdy;
                if (this.hitTest(0, dy + DQ.TETRIS.CHIP_SIZE)) {
                    //「遊び」に移行
                    this.game = DQ.TETRIS.Mode.Delay;
                    this._elapse = 0;
                    this.stopAccelerate();
                    this.current.move(0, dy);
                    this.current.fit();
                } else {
                    this.current.move(0, dy);

                }
                break;
        }

    }
}
</pre>
<p>ゲーム全体の状態はゲーム開始直後(StartGame)、ゲームオーバー(GameOver)、ゲーム中(Play)、遊び中(Delay)および削除中(Erase)です。<br />
ゲーム開始直後およびゲームオーバー状態はキー操作があるまでやることも状態遷移もありません。<br />
次に基本となるゲーム状態ですが、ここについては前回説明しているので割愛します。<br />
遊び状態は一定時間が経過するとステージへ定着(transChip)します。それからラインの削除判定を実施し、削除可能なラインがなければゲーム中状態へ遷移し、削除可能なラインがあれば削除中へ遷移します。<br />
また、削除可能なラインがあった場合はスコアーの計算やレベルアップの判定も実施していますが、説明は割愛します。<br />
削除中状態ではステージに状態管理を委譲しています。これは、削除中の演出の管理をStageクラスへ局所化する意図があります。</p>
<p>次回は、ゴーストやハードドロップについてです。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=760</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptの遅延ロード</title>
		<link>http://plusb.jp/blog/?p=758</link>
		<comments>http://plusb.jp/blog/?p=758#comments</comments>
		<pubDate>Fri, 05 Aug 2011 06:21:40 +0000</pubDate>
		<dc:creator>M. K.</dc:creator>
				<category><![CDATA[dq]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[遅延ロード]]></category>

		<guid isPermaLink="false">http://plusb.jp/blog/?p=758</guid>
		<description><![CDATA[久しぶりに今更なネタですが、JavaScriptの遅延ロードについてです。 単純にJavaScriptのコードで動的にスクリプトを読み込みたいだけならオンデマンドにScriptタグをDOMに追加するだけですみます。 とこ &#8230; <a href="http://plusb.jp/blog/?p=758">続きを読む <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>久しぶりに今更なネタですが、JavaScriptの遅延ロードについてです。<br />
単純にJavaScriptのコードで動的にスクリプトを読み込みたいだけならオンデマンドに<code>Script</code>タグをDOMに追加するだけですみます。<br />
ところが、遅延ロードありきでライブラリやらを構築し出すと、読み込み完了している必要があるだとか依存関係だとかの問題が発生するわけです。<br />
<span id="more-758"></span><br />
これから説明するコードは拙作のライブラリ(<a href="http://plusb.js/dqfw/js/dq.js">dq.js</a>)から抜粋しています。</p>
<h3>とりあえず遅延ロード</h3>
<p>スクリプト内から動的にスクリプトをロードする<code>include()</code>関数の例です。</p>
<pre>
    include = function (file) {
        var s = document.createElement('script');
        s.src = file;
        s.type = 'text/javascript';
        s.defer = 'defer';
        document.head.appendChild(s);
    }
</pre>
<p>このコード自体はなんでも無いですね。<code>script</code>タグをheadタグに追加しているだけです。</p>
<h3>ロード完了を待つ</h3>
<p>そして読み込み完了を待って、任意のコードを実行する<code>lazyLoad()</code>を実装します。</p>
<pre>
    lazyLoad = function(url, ctl, fn) {
        function _check(ctl) { <span style="color:Red;">//オブジェクトの有無でロード完了を判定</span>
            return !!(eval(ctl));
        }
        if (_check(ctl)) {
            fn &#038;&#038; fn(); <span style="color:Red;">//ロード済みなら指定の関数をすぐ実行</span>
        } else {
            include(url);
            setTimeout(function () {
                if (!_check(ctl)) {
                    setTimeout(arguments.callee, 15.625);
                } else {
                    fn &#038;&#038; fn();<span style="color:Red;">//読み込みが終わったら関数を実行</span>
                }
            }, 15.625);
        }
    }
</pre>
<p>今でもそうだと思うのですが、scriptタグの読み込み完了イベントは拾えないので代わりに遅延ロードしたスクリプトを実行した結果として作成されるオブジェクトの有無を判定に利用します。<br />
後は既に読み込み済みなら遅延ロードを実行しないようにチェックを挟んでおきます。</p>
<h3>複数箇所からの呼び出し</h3>
<p>先のコードではとりあえず読み込み済みのチェックは実施していますが、遅延ロードが完了する前に複数回同じスクリプトが呼び出されると無駄があったり面倒くさいことが発生するかもしれません。<br />
そこで同じスクリプトに対しては一度しかinclude()が呼び出されないようにします。</p>
<pre>
    _urls = [];
    lazyLoad = function (url, ctl, fn) {
        function _check(ctl) {
            return !!(eval(ctl));
        }
        if (_check(ctl)) {
            fn &#038;&#038; fn();
            _remove$lazyLoad();
        } else {<span style="color: Red;">
            if (_urls[url]) { <span style="color: Red;">//リクエスト済みならfnのみ登録して終了。</span>
                _urls[url].push(fn);
                return;
            }
            _urls[url] = [];</span>
            include(url);<span style="color: Red;">
            _urls[url].push(fn);</span>
            setTimeout(function () {
                if (!_check(ctl)) {
                    setTimeout(arguments.callee, 15.625);
                } else {<span style="color: Red;">
                    for (var i = 0; i < DQ._urls[url].length; i++) {
                        _urls[url][i] &#038;&#038; DQ._urls[url][i].call();
                    }
                    delete _urls[url];</span>
                }
            }, 15.625);
        }
    }
</pre>
<p>読み込み中のスクリプトと読み込み完了時に実行される関数を<code>_urls</code>に追加しています。<br />
`</p>
<h3>複数のスクリプトを遅延ロードする</h3>
<p>複数のスクリプトを遅延ロードしてから自身のコードを実行したい場合どうなるのでしょうか。</p>
<pre>
lazyLoad("first.js", "Window.FIRST", function() {
  layzLoad("second.js", "Window.SECOND", function() {
      ... //自分のコード
  });
});
</pre>
<p>もしくは</p>
<pre>
lazyLoad("first.js", "Window.FIRST");
layzLoad("second.js", "Window.SECOND", function() {
    ... //自分のコード
});
</pre>
<p>まあ、どちらもいまいちですね。<br />
そこで、全ての遅延ロードが完了したら呼び出される、<code>afterLoad()</code>という関数を用意します。</p>
<pre>
    lazyLoad = function (url, ctl, fn) {
        function _check(ctl) {
            return !!(eval(ctl));
        }
        if (_check(ctl)) {
            fn &#038;&#038; fn();
            <span style="color:red;">__remove$lazyLoad();</span>
        } else {
            if (_urls[url]) {
                _urls[url].push(fn);
                return;
            }
            _urls[url] = [];
            include(url);
            _urls[url].push(fn);

            setTimeout(function () {
                if (!_check(ctl)) {
                    setTimeout(arguments.callee, 15.625);
                } else {
                    for (var i = 0; i < _urls[url].length; i++) {
                        _urls[url][i] &#038;&#038; _urls[url][i].call();
                    }
                    delete _urls[url];
                    <span style="color:red;">_remove$lazyLoad();</span>
                }

            }, 15.625);
        }
<span style="color:red;">_
        function _remove$lazyLoad() {
            var cnt = 0;
            for (var nm in DQ._urls) {
                cnt += _urls.hasOwnProperty(nm) ? 1 : 0;
            }
            if (cnt == 0) {
                __trigger &#038;&#038; setTimeout(DQ.__trigger, 0);
            }
        }
    }

__trigger = function () {
    for (var i = 0; i < _onLoad.length; i++) {
        _onLoad[i].call();
    }
    _onLoad.length = 0;
    delete __trigger;
}
_onLoad = [];
afterLoad = function (callback) {
    _onLoad.push(callback);
}</span>
</pre>
<p>使い方は以下の通りです。</p>
<pre>
lazyLoad("first.js", "Window.FIRST");
layzLoad("second.js", "Window.SECOND");
afterLoad(function() {
    ... //自分のコード
});
</pre>
<p>より複雑なケースでは問題が出る可能性もありますが、そこは宿題ということで。</p>
]]></content:encoded>
			<wfw:commentRss>http://plusb.jp/blog/?feed=rss2&#038;p=758</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
