itemblock チュートリアル |
はじめに
まずは「脱衣ブロック崩し」を作ってみる
アニメーションをつけてみる
アイテムを追加してみる
服の消滅とアイテムの動きに女の子を反応させてみる
手足と胸を動かしてみる
各種色の調整
その他の機能
画像ファイル作成の際の注意事項
うまく動かない時には
最後に
「アイテムブロック」JavaScriptをダウンロードして頂き、ありがとうございます。
すでにsample.htmlで遊ばれた方の中には、「こんなヘタクソなイラストではなく、自分の描いたもっとまともなイラストでオリジナルのブロック崩しを作りたい」と思われた方も多くいらっしゃると思います。
2005年頃、インターネットでは、女の子の服をボールではぎ取る「脱衣ブロック崩し」が急増しているようでした。
一方、「アイテムブロック」アプレットを使うと、女の子の服をボールではぎ取るだけでなく、服をはぎ取られた女の子をイタズラするアイテムの禁断の封印をボールで解く「脱衣+???ブロック崩し」を作る事ができます。
しかし、その作り方は「脱衣ブロック崩し」ほど簡単ではありません。
本チュートリアルは、「脱衣+くすぐりハンド悶絶ブロック崩し」の一例であるsample.htmlの作成工程を実際に体験する事により、オリジナルの「脱衣+???ブロック崩し」を作るための知識を身につけて頂こうとするものであります。
いきなり「脱衣+くすぐりハンド悶絶ブロック崩し」などを作ろうとすると、ゲームの中の女の子よりも先に自分の方が悶絶してしまいます。
そこで、まずは単純な「脱衣ブロック崩し」から始めてみましょう。
最初に以下のHTML記述をコピペし、test.htmlという名前で保存して下さい。
保存場所は、itemblock.classファイルと同じディレクトリで、文字コードはUTF-8です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta charset="UTF-8">
<title>サンプル</title>
<script type="text/javascript">
function setParam(){
ballColor="magenta";
barColor="white";
itemBarColor="white";
itemBlockColor="blue";
blockBorderColor="magenta";
messageColor="white";
backgroundColor="black";
nakedImg="smlbk.png";
clothImg="smlcl.png";
life=(-1);
clothBlockW=32;
clothBlockH=32;
itemBlockW=16;
itemBlockH=16;
frameInterval=20;
clothBlockHelpNum=10;
ballW=8;
ballH=8;
barW=64;
barH=8;
ballVX=4;
ballVY=4;
setItemAnmNum(0);
setItemTypeNum(0);
setItemNum(0);
setTgAnmNum(0);
setTgNum(0);
setNkLvNum(1,0);
layerNum=1;
clothBlockLayer=0;
}
</script>
<script type="text/javascript" src="itemblock.js">
</script>
</head>
<body>
<canvas id="id_canvas" width="500" height="560">
本ページの閲覧はHTML5ブラウザで行って下さい。
</canvas>
</body>
</html>
保存したら、さっそくブラウザで開いてみましょう。
いかがでしょう。無事に動きましたでしょうか。
それでは、上のHTML記述をよく見てみる事にしましょう。
canvasタグに指定するwithとheightは、ブロック崩しの画面の大きさです。
その上の、setParam関数の中で、各種パラメータを設定しています。
多くの設定が書かれているように見えますが、ほとんどは自動で生成する事ができ、そこから追加・変更する必要のある項目は、4つだけです。
setParam()関数の自動生成の為には、同梱しているconvert.html及びpr2func.jsを使用します。
convert.htmlをブラウザで開くと、「入力」と「出力」と書かれた2つのテキストボックスが現れると思います。
このツールは本来、JavaApplet版用のパラメータ指定をJavaScript版用のsetParam関数に変換する為のもので、「入力」の所にはJavaApplet版用のパラメータ指定を書くのですが、とりあえず何もない状態で「Convert」ボタンを押しても、「出力」のテキストボックスにsetParam関数が作られます。
そのままでは画像の指定がないので、画像の指定を追加します。
nakedImgは、服を脱いだ状態の女の子を含む背景画像、clothImgは服画像です。
また、服ブロックの数を調整する為、服ブロックの幅と高さであるclothBlockWとclothBlockHの値を変更しています。
どうですか? これだけなら、まだ簡単ですよね。
それではいよいよ本アプレット独自の機能を使ってみましょう。
といっても、「脱衣+くすぐりハンド悶絶ブロック崩し」を作るのにはまだ早すぎます。
まずは、女の子に「口パク」をさせてみましょう。
そのためには、どのようなパラメータ指定を追加する必要があるでしょうか。
何はともあれ、まずは、「口パク」のアニメーションを設計しなくてはなりませんね。
ここでは口を閉じている状態を1秒程度、口を開いている状態を同じく1秒程度表示する事によって、「口パク」を表現する事にしましょう。
口を閉じている状態は背景画像に描かれており、口を開いた状態はsmlmth1.pngを背景画像上の(209,170)の位置に上書きする事によって実現できます。
それでは、以上の事を踏まえ、必要なパラメータを追加していきましょう。
まずはアニメーションの数です。今回の場合は「口パク」ただ1つですので、
setTgAnmNum(0);
と書かれている所を
setTgAnmNum(1);
に変更します。
Tgは、「ターゲット」の略です。
すなわち、上の記述の意味は、「ターゲットアニメーションが1つ存在する」という事です。
アニメーションには「ターゲットアニメーション」と「アイテムアニメーション」の2種類があるのです。
「アイテムアニメーション」とはアイテムの表示に使うアニメーションなのですが、まだアイテム自体が存在しないので、「口パク」はアイテムアニメーションであろうはずはなく、ターゲットアニメーションという事になるのです。
次に、その1つだけ存在するターゲットアニメーションの内容について記述しなければなりません。
「口パク」のアニメーションは、口を開いているシーンと、口を閉じているシーンの2つを描画するので、以下のように記述します。
setTgAnmScnNum(0,2);
これは、アニメーション0が2つのシーンを持つという指定です。
次に、口を閉じているシーンの継続フレーム数とを求めます。
frameInterval=20となっている事から、1フレーム20msですので、1秒は50フレームという計算になります。
従って、
setTgAnmScnImgNumFrm(0,0,0,50);
となります。これは、アニメーション0のシーン0は、使用画像枚数が0枚で、継続フレーム数が50であるという指定です。
次に、口を開いているシーンについては、背景に上書きする画像が1枚あります。継続フレーム数は、0番シーンと同じ50ですので、
setTgAnmScnImgNumFrm(0,1,1,50); となりす。これは、アニメーション0のシーン1は、使用画像枚数が1枚で、継続フレーム数が50であるという指定です。 使用する1枚の画像に関しては、ファイル名と表示座標を
setTgAnmScnImgPr(0,1,0,"smlmth1.png",209,170);
と指定します。これは、アニメーション0のシーン1の画像0のファイル名は"smlmth1.png"で、表示する座標は(209,170)である事を示しています。
以上で「口パク」アニメーション自体に関する記述は完了なのですが、これだけではアニメーションは表示されません。
ターゲットアニメーションというからには、何らかの「ターゲット」に依存しており、そのターゲットに関する記述と、そのターゲットが「口パク」アニメーションを表示させる条件に関する記述が必要なのです。
まず、今回の場合、ターゲットは1つだけで十分なので、
setTgNum(1);
とします。
次に、唯一存在するターゲット0の持つ「参照ベクトル」に関する記述です。
ここで「参照ベクトルとは何ぞや」と説明しても、多分よく分からないと思いますので、それについては後で詳しく説明する事として、ここでは何も考えずに
setTgRVecNumENum(0,1,1);
setTgRVecAnm(0,0,"0.0",0);
とします。
これにより、ターゲット0がターゲットアニメーション0を表示する条件を記述した事になり、無事「口パク」のアニメーションが表示されるのです。
いかがでしょう。ちゃんと動きましたでしょうか。
「アイテムブロック」というからには、アイテムがなければお話になりません。
というわけで、いよいよアイテムの追加です。
ここではアイテムとして、「くすぐりハンド」を追加してみます。
まず、上でも説明しましたように、アイテムにはアイテムアニメーションというものがありますので、まずはその記述からはじめましょう。
くすぐりハンドのアニメーションは、手を開いている画像と、半開きにした画像の二つを10フレームずつ交互に表示するものとします。
setItemAnmNum(1);
setItemAnmImgNum(0,2);
setItemImgPr(0,0,"t02hand1.png",10);
setItemImgPr(0,1,"t02hand2.png",10);
setItemAnmNum(1);でアイテムアニメーションの数が1である事を、setItemAnmImgNum(0,2);でアイテムアニメーション0に使用する画像の数が2である事を、 setItemImgPr(0,0,"t02hand1.png",10);でアイテムアニメーション0の画像0のファイル名と継続フレーム数、ItemAnm0Img1Prはアイテムアニメーション0の画像1のファイル名と継続フレーム数です。
ターゲットアニメーションと異なり、アイテムアニメーションは1シーン1画像です。
次に、くすぐりハンドのアイテムタイプというものを定義します。
setItemTypeNum(1);
setItemType(0,0,0,16,20);
今回ゲームに登場するアイテムはくすぐりハンドのみですので、setItemTypeNum(1)でアイテムタイプの数が1である事を示します。
そして、0番のアイテムタイプがくすぐりハンドという事になります。
setItemType(0,0,0,16,20);は、アイテムタイプ0の「状態0」におけるアイテムアニメーション番号が0であり、「状態1」におけるアイテムアニメーション番号も0である事、接続座標が(16,20)であるを示します。
ここで、「状態0」とか「状態1」というものについて説明しなければなりませんね。
アイテムは、最初はアイテムブロックによって封印されており、アイテムブロックが全て消える事により該当のアイテムが起動されます。起動されると支点から伸びる棒につながれたまま目的の位置(後で説明するMXY0)に向かいます。目的の位置に到着したアイテムは、もう一つの目的地(後で説明するMXY1)との間を往復します。
「状態0」とは起動されてから目的地に着くまでの間の状態、「状態1」とは、目的地に着いた後の状態です。
接続座標は、アイテムタイプ0の、アイテムアニメーション画像の左上隅を原点とした場合の、棒との接続点の座標です。
次に、ようやくアイテムそのものについての記述です。
まず、アイテムは6つあるので、
setItemNum(6);
とします。
ここで、6つのアイテムの番号は、女の子から見て右が上から0〜2番、左が上から3〜5番としておきましょう。
次に、それぞれのアイテムに関する記述です。アイテム0に関する記述は、次のようになります。
setItemPr(0,0,56,229,3,3,-1,-1,164,267,105,168,100,100,"smlbl.png",0,0,0);
setItemPr関数に渡す18個の引数のうち、第1〜第6引数は、アイテム0のアイテムタイプ番号が0、封印するアイテムブロック群の左上の座標が(56,229)、ブロックの横の列数が3、縦の列数が3である事を示しています。
第7〜第8引数が-1であるのは、このアイテムを支える棒の座標がブロック群の中心である事を示しています。
第9〜第12引数は、このアイテムが起動された時に、まず(164,267)に向かい、その座標に到着すると、今度はその座標と(105,168)との間を往復する事を示しています。
第13引数は、往復にかかるフレーム数が100である事を、第14引数は、このアイテムが起動されてから(164,267)に着くまでのフレーム数が100である事を示しています。
第15引は、ブロック群の表示に使用する画像ファイル名です。""を指定した場合は、itemBlockColorで指定した色のベタ塗りの長方形となります。
第16〜18引数は、アイテム、アイテムブロック、アイテムブロックエリア(ブロックになる前の状態)を描画するレイヤー番号で、通常は0にします。
同様に、以下に示すパラメータも追加してみて下さい。
setItemPr(1,0,56,320,3,3,-1,-1,194,368,194,474,100,100,"smlbl.png",0,0,0);
setItemPr(2,0,56,408,3,3,-1,-1,197,509,187,540,100,100,"smlbl.png",0,0,0);
setItemPr(3,0,395,230,3,3,-1,-1,307,272,386,173,100,100,"smlbl.png",0,0,0);
setItemPr(4,0,395,321,3,3,-1,-1,274,368,274,474,100,100,"smlbl.png",0,0,0);
setItemPr(5,0,395,408,3,3,-1,-1,280,509,308,540,100,100,"smlbl.png",0,0,0);
動作させる前に、
test_mode=true;
という行をどこかに入れておきましょう。ボールがマウスクリックで移動できるようになり、動作確認がしやすくなります。
いかがでしょう。服が消えた後で、6個のくすぐりハンドは表示されましたでしょうか。
女の子の服がボールによって破られても、くすぐりハンドが動いても、女の子がずっとすまし顔で「口パク」を続けているというのでは、あまり面白くないですよね。
そこで、次は女の子の顔のアニメーションが、状況に応じて変わるようにしてみましょう。
まずは、ターゲットアニメーションのバリエーションを増やさなければなりません。
その為、
setTgAnmNum(1);
としていた所を
setTgAnmNum(13);
に変更し、以下のパラメータ指定を追加して下さい。
setTgAnmScnNum(1,8);
setTgAnmScnImgNumFrm(1,0,3,50);
setTgAnmScnImgPr(1,0,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(1,0,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(1,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(1,1,3,50);
setTgAnmScnImgPr(1,1,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(1,1,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(1,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(1,2,2,50);
setTgAnmScnImgPr(1,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(1,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(1,3,3,50);
setTgAnmScnImgPr(1,3,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(1,3,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(1,3,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(1,4,1,50);
setTgAnmScnImgPr(1,4,0,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(1,5,1,50);
setTgAnmScnImgPr(1,5,0,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(1,6,0,50);
setTgAnmScnImgNumFrm(1,7,1,50);
setTgAnmScnImgPr(1,7,0,"smlmth1.png",209,170);
setTgAnmScnNum(2,4);
setTgAnmScnImgNumFrm(2,0,3,50);
setTgAnmScnImgPr(2,0,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(2,0,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(2,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(2,1,3,50);
setTgAnmScnImgPr(2,1,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(2,1,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(2,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(2,2,2,50);
setTgAnmScnImgPr(2,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(2,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(2,3,3,50);
setTgAnmScnImgPr(2,3,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(2,3,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(2,3,2,"smlmth1.png",209,170);
setTgAnmScnNum(3,4);
setTgAnmScnImgNumFrm(3,0,3,25);
setTgAnmScnImgPr(3,0,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(3,0,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(3,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(3,1,3,25);
setTgAnmScnImgPr(3,1,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(3,1,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(3,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(3,2,2,25);
setTgAnmScnImgPr(3,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(3,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(3,3,3,25);
setTgAnmScnImgPr(3,3,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(3,3,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(3,3,2,"smlmth1.png",209,170);
setTgAnmScnNum(4,8);
setTgAnmScnImgNumFrm(4,0,3,25);
setTgAnmScnImgPr(4,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(4,0,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(4,1,3,25);
setTgAnmScnImgPr(4,1,0,"smleye00.png",171,106);
setTgAnmScnImgPr(4,1,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(4,2,2,25);
setTgAnmScnImgPr(4,2,0,"smleye00.png",171,106);
setTgAnmScnImgPr(4,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(4,3,3,25);
setTgAnmScnImgPr(4,3,0,"smleye00.png",171,106);
setTgAnmScnImgPr(4,3,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,3,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(4,4,3,25);
setTgAnmScnImgPr(4,4,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(4,4,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,4,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(4,5,3,25);
setTgAnmScnImgPr(4,5,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(4,5,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,5,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(4,6,2,25);
setTgAnmScnImgPr(4,6,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(4,6,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(4,7,3,25);
setTgAnmScnImgPr(4,7,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(4,7,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(4,7,2,"smlmth1.png",209,170);
setTgAnmScnNum(5,7);
setTgAnmScnImgNumFrm(5,0,2,25);
setTgAnmScnImgPr(5,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(5,0,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(5,1,2,25);
setTgAnmScnImgPr(5,1,0,"smleye01.png",171,106);
setTgAnmScnImgPr(5,1,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(5,2,2,25);
setTgAnmScnImgPr(5,2,0,"smleye00.png",171,106);
setTgAnmScnImgPr(5,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(5,3,2,25);
setTgAnmScnImgPr(5,3,0,"smleye01.png",171,106);
setTgAnmScnImgPr(5,3,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(5,4,3,25);
setTgAnmScnImgPr(5,4,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(5,4,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(5,4,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(5,5,2,25);
setTgAnmScnImgPr(5,5,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(5,5,1,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(5,6,3,25);
setTgAnmScnImgPr(5,6,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(5,6,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(5,6,2,"smlmth1.png",209,170);
setTgAnmScnNum(6,4);
setTgAnmScnImgNumFrm(6,0,3,25);
setTgAnmScnImgPr(6,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(6,0,1,"smleye10.png",223,109);
setTgAnmScnImgPr(6,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(6,1,3,25);
setTgAnmScnImgPr(6,1,0,"smleye01.png",171,106);
setTgAnmScnImgPr(6,1,1,"smleye11.png",223,109);
setTgAnmScnImgPr(6,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(6,2,2,25);
setTgAnmScnImgPr(6,2,0,"smleye00.png",171,106);
setTgAnmScnImgPr(6,2,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(6,3,3,25);
setTgAnmScnImgPr(6,3,0,"smleye01.png",171,106);
setTgAnmScnImgPr(6,3,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(6,3,2,"smlmth1.png",209,170);
setTgAnmScnNum(7,8);
setTgAnmScnImgNumFrm(7,0,3,25);
setTgAnmScnImgPr(7,0,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,0,1,"smleye10.png",223,109);
setTgAnmScnImgPr(7,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(7,1,3,25);
setTgAnmScnImgPr(7,1,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,1,1,"smleye10.png",223,109);
setTgAnmScnImgPr(7,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(7,2,2,25);
setTgAnmScnImgPr(7,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,2,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(7,3,3,25);
setTgAnmScnImgPr(7,3,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,3,1,"smleye10.png",223,109);
setTgAnmScnImgPr(7,3,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(7,4,3,25);
setTgAnmScnImgPr(7,4,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,4,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(7,4,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(7,5,3,25);
setTgAnmScnImgPr(7,5,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,5,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(7,5,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(7,6,2,25);
setTgAnmScnImgPr(7,6,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,6,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(7,7,3,25);
setTgAnmScnImgPr(7,7,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(7,7,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(7,7,2,"smlmth1.png",209,170);
setTgAnmScnNum(8,7);
setTgAnmScnImgNumFrm(8,0,2,25);
setTgAnmScnImgPr(8,0,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,0,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(8,1,2,25);
setTgAnmScnImgPr(8,1,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,1,1,"smleye11.png",223,109);
setTgAnmScnImgNumFrm(8,2,2,25);
setTgAnmScnImgPr(8,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,2,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(8,3,2,25);
setTgAnmScnImgPr(8,3,0,"smleye11.png",223,109);
setTgAnmScnImgPr(8,3,1,"smlbr0.png",171,106);
setTgAnmScnImgNumFrm(8,4,3,25);
setTgAnmScnImgPr(8,4,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,4,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(8,4,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(8,5,3,25);
setTgAnmScnImgPr(8,5,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,5,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(8,5,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(8,6,3,25);
setTgAnmScnImgPr(8,6,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(8,6,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(8,6,2,"smlmth1.png",209,170);
setTgAnmScnNum(9,4);
setTgAnmScnImgNumFrm(9,0,3,25);
setTgAnmScnImgPr(9,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(9,0,1,"smleye10.png",223,109);
setTgAnmScnImgPr(9,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(9,1,3,25);
setTgAnmScnImgPr(9,1,0,"smleye01.png",171,106);
setTgAnmScnImgPr(9,1,1,"smleye11.png",223,109);
setTgAnmScnImgPr(9,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(9,2,2,25);
setTgAnmScnImgPr(9,2,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(9,2,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(9,3,3,25);
setTgAnmScnImgPr(9,3,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(9,3,1,"smleye11.png",223,109);
setTgAnmScnImgPr(9,3,2,"smlmth1.png",209,170);
setTgAnmScnNum(10,8);
setTgAnmScnImgNumFrm(10,0,3,25);
setTgAnmScnImgPr(10,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(10,0,1,"smleye10.png",223,109);
setTgAnmScnImgPr(10,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(10,1,3,25);
setTgAnmScnImgPr(10,1,0,"smleye00.png",171,106);
setTgAnmScnImgPr(10,1,1,"smleye10.png",223,109);
setTgAnmScnImgPr(10,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(10,2,2,25);
setTgAnmScnImgPr(10,2,0,"smleye00.png",171,106);
setTgAnmScnImgPr(10,2,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(10,3,3,25);
setTgAnmScnImgPr(10,3,0,"smleye00.png",171,106);
setTgAnmScnImgPr(10,3,1,"smleye10.png",223,109);
setTgAnmScnImgPr(10,3,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(10,4,3,25);
setTgAnmScnImgPr(10,4,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(10,4,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(10,4,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(10,5,3,25);
setTgAnmScnImgPr(10,5,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(10,5,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(10,5,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(10,6,2,25);
setTgAnmScnImgPr(10,6,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(10,6,1,"smlbr1.png",223,109);
setTgAnmScnImgNumFrm(10,7,3,25);
setTgAnmScnImgPr(10,7,0,"smlbr0.png",171,106);
setTgAnmScnImgPr(10,7,1,"smlbr1.png",223,109);
setTgAnmScnImgPr(10,7,2,"smlmth1.png",209,170);
setTgAnmScnNum(11,4);
setTgAnmScnImgNumFrm(11,0,3,25);
setTgAnmScnImgPr(11,0,0,"smleye00.png",171,106);
setTgAnmScnImgPr(11,0,1,"smleye10.png",223,109);
setTgAnmScnImgPr(11,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(11,1,3,25);
setTgAnmScnImgPr(11,1,0,"smleye01.png",171,106);
setTgAnmScnImgPr(11,1,1,"smleye11.png",223,109);
setTgAnmScnImgPr(11,1,2,"smlmth1.png",209,170);
setTgAnmScnImgNumFrm(11,2,2,25);
setTgAnmScnImgPr(11,2,0,"smleye00.png",171,106);
setTgAnmScnImgPr(11,2,1,"smleye10.png",223,109);
setTgAnmScnImgNumFrm(11,3,3,25);
setTgAnmScnImgPr(11,3,0,"smleye01.png",171,106);
setTgAnmScnImgPr(11,3,1,"smleye11.png",223,109);
setTgAnmScnImgPr(11,3,2,"smlmth1.png",209,170);
setTgAnmScnNum(12,2);
setTgAnmScnImgNumFrm(12,0,3,25);
setTgAnmScnImgPr(12,0,0,"smleye02.png",171,106);
setTgAnmScnImgPr(12,0,1,"smleye12.png",223,109);
setTgAnmScnImgPr(12,0,2,"smlmth2.png",209,170);
setTgAnmScnImgNumFrm(12,1,3,25);
setTgAnmScnImgPr(12,1,0,"smleye03.png",171,106);
setTgAnmScnImgPr(12,1,1,"smleye13.png",223,109);
setTgAnmScnImgPr(12,1,2,"smlmth1.png",209,170);
ここで、それぞれのターゲットアニメーションの内容は、最初に作った「口パク」も含め、表1のようになっています。
実際に自分でアニメーションを作る時には、作業に先立ってこのような表を作り、さらにそれをもとに絵コンテを作っておくとよいでしょう。
番号 | 内容 | 備考 |
0 | 口パク | 女の子は何もされてない |
1 | 眉を内側に寄せたり戻したりしながら、 大きく口パク |
服が少し剥がれた |
2 | 眉を内側に寄せ、大きく口パク | 服がだいぶ剥がれた |
3 | 眉を内側に寄せ、大きく激しく口パク | 服がほとんど剥がれた (又は全部剥がれた) |
4 | 眉を内側に寄せ、右目をパチパチしながら 大きく激しく口パク |
右半身が少しくすぐったい |
5 | 眉を内側に寄せ、右目を閉じて震わせたり、 開きながら大きく激しく口パク |
右半身がかなりくすぐったい |
6 | 眉を内側に寄せ、右目を閉じて震わせ、 大きく激しく口パクしながら時々左目を開く |
右半身がすごくくすぐったい |
7 | 眉を内側に寄せ、左目をパチパチしながら 大きく激しく口パク |
左半身が少しくすぐったい |
8 | 眉を内側に寄せ、左目を閉じて震わせたり、 開きながら大きく激しく口パク |
左半身がかなりくすぐったい |
9 | 眉を内側に寄せ、左目を閉じて震わせ、 大きく激しく口パクしながら時々右目を開く |
左半身がすごくくすぐったい |
10 | 眉を内側に寄せ、両目をパチパチしながら、 大きく激しく口パク |
左右半身共少しくすぐったい |
11 | 眉を内側に寄せ、両目を閉じて震わせながら、 大きく激しく口パク |
左右半身共かなりくすぐったい |
12 | 眉を外側に寄せ、両目を閉じて震わせながら、 大きく激しく口パク |
左右半身共すごくくすぐったい |
次に、これらのアニメーションが表示される条件を記述しなければなりません。
そのためには、ターゲットがターゲットアニメーションを選択するしくみと、上で「口パク」を実現した際に説明を避けた「参照ベクトル」に関して理解しておく必要があります。
本JavaScriptは、「服の破れ具合とアイテムの稼動状況がターゲットに影響を与え、各ターゲットはその時に受けている影響度合いによって表示するターゲットアニメーションを決定する」ようになっています。
ターゲットが受ける影響度合いはベクトルという形になっています。各ターゲットは現在自分が受けている影響度合いを合計し、その結果得られたベクトルが、パラメータ指定により関連づけられている「参照ベクトル」のうちのどれに最も近いかを調べ、選択します。そして、選択した参照ベクトルに関連づけられているアニメーションを表示するのです。
最も近い参照ベクトルが複数存在する場合は、番号の若い参照ベクトルが優先して選択されます。
ベクトルの次元数は、ターゲット毎に自由に設定できます。
ここでは、上で「口パク」を実現する時に記述したターゲット0を女の子の「顔」と考え、それの持つベクトルの次元数を3とします。
この3次元ベクトルの持つ3つの成分の意味については、第0成分が「服をはぎ取られた事に対する怒り」、第1成分が「右半身のくすぐったさ」、第2成分が「左半身のくすぐったさ」であると考えます。
次に、服をはぎ取られる事によるターゲット0への影響に関する記述です。
setNkLvNum(4,3);
addNkLvTgVec(1,0,"1.0,0.0,0.0");
addNkLvTgVec(2,0,"2.0,0.0,0.0");
addNkLvTgVec(3,0,"3.0,0.0,0.0");
setNkLvNum(4,3);は、裸レベル数が4、最大値が3である事を示しています。
裸レベルは最初は0で、服ブロックが消えるに従って増えていきます。
正確には、「(今まで消滅した服ブロック数÷もともとの服ブロック数)×裸レベル数」が現在の裸レベルとなります。但し。計算結果が第2引数で指定した最大値を上回っている場合は、最大値が現在の裸レベルとなります。
従って、この例の場合は、服ブロックが1個残っている時と全く残っていない時の裸レベルが同じ値となります。
なお、上の計算式の値が最大値に等しい時にその値が裸レベルとなるようにするには、第2引数を第1引数と同じ値にします。
その下にあるaddNkLvTgVec()は、裸レベル1〜3の状況がターゲット0に与える影響ベクトルの指定です。
裸レベル0は初期状態であり、ターゲットに影響を与えないと考えられるため、影響ベクトルの指定は不要です。
次に、各アイテムがターゲット0に与える影響の記述です。
addItemTgVec(0,0,1,"0.0,1.0,0.0");
addItemTgVec(1,0,1,"0.0,1.0,0.0");
addItemTgVec(2,0,1,"0.0,1.0,0.0");
addItemTgVec(3,0,1,"0.0,0.0,1.0");
addItemTgVec(4,0,1,"0.0,0.0,1.0");
addItemTgVec(5,0,1,"0.0,0.0,1.0");
第1引数はアイテム番号、第2引数はターゲット番号、第3引数はアイテムの状態番号、第4引数が影響ベクトルです。 この記述の場合、仮にアイテム0とアイテム3が状態1で稼動している場合、ターゲット0の受ける影響は、
(3,0,0)+(0,1,0)+(0,0,1)=(3,1,1)
となります。
左辺の最初の(3,0,0)は、露出レベル3による影響(アイテム稼動時は服が全て消えているので)、次の(0,1,0)はアイテム0からの影響、次の(0,0,1)はアイテム3からの影響です。
(今回の例では、アイテムは状態1の時にしかターゲットに影響を与えませんが、状態0についても「アイテムが迫ってくる時の女の子の恐怖感」などを演出する目的で使用する事ができます。
余裕のある人は、後で挑戦してみて下さい。)
次に、アニメーションの表示条件を記述する為に、参照ベクトルを決めます。
その為には、ターゲットの受ける影響の合計がどのような値を取りうるのかを考える必要があります。
その答えは以下のとおりです。
(0,0,0),(1,0,0),(2,0,0),
(3,0,0),(3,1,0),(3,2,0),(3,3,0),
(3,0,1),(3,1,1),(3,2,1),(3,3,1),
(3,0,2),(3,1,2),(3,2,2),(3,3,2),
(3,0,3),(3,1,3),(3,2,3),(3,3,3)
上記の中で、(0,0,0)は初期値、(1〜3,0,0)は服ブロックが消える事による影響、それ以外はアイテム稼動時の影響という事になります。
次に、ターゲットの受ける影響の合計が上記のうちのどの場合にどのアニメーションを表示すべきかを考えます。
ここでは表1の備考欄に書いた内容から、表2のようにする事とします。
影響の合計 | ターゲット アニメーション |
(0,0,0) | 0 |
(1,0,0) | 1 |
(2,0,0) | 2 |
(3,0,0) | 3 |
(3,1,0) | 4 |
(3,2,0) | 5 |
(3,3,0) | 6 |
(3,0,1) | 7 |
(3,0,2) | 8 |
(3,0,3) | 9 |
(3,1,1) | 10 |
(3,2,2) | 11 |
(3,3,3) | 12 |
そこで、とりあえず、この表の左の欄にあるベクトルを参照ベクトルとし、右の欄に書かれた番号を、その参照ベクトルに対するアイテムアニメーション番号としてしまいましょう。
おや? でも、まだこれだけではまだ足りませんね。
そうです。この表からは、(3,3,1)、(3,1,3)、(3,2,1)、(3,1,2)、(3,2,3)、(3,3,2)が抜けています。
ここでは、これらのベクトルについては、アイテムアニメーションを表3のように対応させる事とします。
影響の合計 | ターゲット アニメーション |
(3,3,1) | 6 |
(3,1,3) | 9 |
(3,2,1),(3,1,2) | 10 |
(3,2,3),(3,3,2) | 11 |
この場合、これらのベクトルについても全て参照ベクトルとみなして、対応するアニメーション番号を割り当ててしまう事も可能です。
一方、今回の場合、同じアニメーション番号のベクトルが固まった位置にあるため、表2に基づいて決めた参照ベクトルをうまく調整する事によって、表3による参照ベクトル記述を省略する事ができます。
この例では、ベクトルの数が少ない為、省略によるメリットはほとんどありませんが、ベクトルの数が多くなると、それなりにメリットがあるかもしれません。
ちなみに今回の場合、どのようにすれば表3の記述が省略できるかというと、参照ベクトルの番号を表4のようにするだけでよいのです(これ以外にも、一部の参照ベクトルを微妙にずらすといった方法が考えられます)。
参照ベクトル番号 | 参照ベクトル | アニメーション |
0 | (0,0,0) | 0 |
1 | (1,0,0) | 1 |
2 | (2,0,0) | 2 |
3 | (3,0,0) | 3 |
4 | (3,1,1) | 10 |
5 | (3,1,0) | 4 |
6 | (3,2,0) | 5 |
7 | (3,3,0) | 6 |
8 | (3,0,1) | 7 |
9 | (3,0,2) | 8 |
10 | (3,0,3) | 9 |
11 | (3,2,2) | 11 |
12 | (3,3,3) | 12 |
これで本当にうまくいくか、ちょっと検証してみましょう。
(ちなみに、紙の上に第1成分と第2成分に関する座標平面を描き、各ベクトルをプロットしてみると、分かりやすいかと思います)
まず、(3,3,1)と最も近い参照ベクトルは7番の(3,3,0)なので、ターゲットアニメーション6が選択されます。
同様に、(3,1,3)と最も近い参照ベクトルは、10番の(3,0,3)で、ターゲットアニメーション9が選択されます。
(3,2,1)と最も近い参照ベクトルは4番の(3,1,1)、6番の(3,2,0)、11番の(3,2,2)の3つがありますが、そのうち最も番号が若いのは4番であり、それに対応するターゲットアニメーション10が選択されます。
他の場合についても同様に検証する事ができます。
それでは、表4に基づき参照ベクトルに関するパラメータを追加してみましょう。
まず、参照ベクトルの数は13個、次元数は3、0番の参照ベクトルは(0,0,0)なので、上の方で「何も考えずに」記述した
setTgRVecNumENum(0,1,1); setTgRVecAnm(0,0,"0.0",0);
の部分を次のように変更します。
setTgRVecNumENum(0,13,3); setTgRVecAnm(0,0,"0.0,0.0,0.0",0);
続いて以下のパラメータ指定を追加します。
setTgRVecAnm(0,1,"1.0,0.0,0.0",1);
setTgRVecAnm(0,2,"2.0,0.0,0.0",2);
setTgRVecAnm(0,3,"3.0,0.0,0.0",3);
setTgRVecAnm(0,4,"3.0,1.0,1.0",10);
setTgRVecAnm(0,5,"3.0,1.0,0.0",4);
setTgRVecAnm(0,6,"3.0,2.0,0.0",5);
setTgRVecAnm(0,7,"3.0,3.0,0.0",6);
setTgRVecAnm(0,8,"3.0,0.0,1.0",7);
setTgRVecAnm(0,9,"3.0,0.0,2.0",8);
setTgRVecAnm(0,10,"3.0,0.0,3.0",9);
setTgRVecAnm(0,11,"3.0,2.0,2.0",11);
setTgRVecAnm(0,12,"3.0,3.0,3.0",12);
いかがでしょう。顔のアニメーションは意図したとおりに変化しましたでしょうか。
次に、手足と胸をアイテムの動きに反応させてみましょう。
ここでは、右腕、左腕、右足、左足、胸はそれぞれ、顔とは独立したターゲットとして定義する事にします。
この事を踏まえ、まずは手足と胸のターゲットアニメーションを定義する為のパラメータを追加しましょう。
setTgAnmScnNum(13,2);
setTgAnmScnImgNumFrm(13,0,0,25);
setTgAnmScnImgNumFrm(13,1,1,25);
setTgAnmScnImgPr(13,1,0,"smlarm0.png",22,0);
setTgAnmScnNum(14,2);
setTgAnmScnImgNumFrm(14,0,0,25);
setTgAnmScnImgNumFrm(14,1,1,25);
setTgAnmScnImgPr(14,1,0,"smlarm1.png",319,0);
setTgAnmScnNum(15,2);
setTgAnmScnImgNumFrm(15,0,0,25);
setTgAnmScnImgNumFrm(15,1,1,25);
setTgAnmScnImgPr(15,1,0,"smlleg0.png",129,461);
setTgAnmScnNum(16,2);
setTgAnmScnImgNumFrm(16,0,0,25);
setTgAnmScnImgNumFrm(16,1,1,25);
setTgAnmScnImgPr(16,1,0,"smlleg1.png",253,461);
setTgAnmScnNum(17,2);
setTgAnmScnImgNumFrm(17,0,0,25);
setTgAnmScnImgNumFrm(17,1,1,25);
setTgAnmScnImgPr(17,1,0,"smlbust.png",145,248);
ターゲットアニメーションの追加に伴い、setTgAnmNum(13);の指定を変更します。
setTgAnmNum(18);
ここで追加したターゲットアニメーションの内容は、表5のようになっています。
番号 | 内容 | 備考 |
13 | 右腕がジタバタ | 右腕がくすぐったい |
14 | 左腕がジタバタ | 左腕がくすぐったい | 15 | 右足がジタバタ | 右足がくすぐったい | 16 | 左足がジタバタ | 左足がくすぐったい | 17 | 胸がボヨンボヨン | 左右の腕又は腰が くすぐったい |
次に、両手両足と胸をそれぞれ新たなターゲットとし、それらの持つ参照ベクトルと対応するターゲットアニメーションの指定を追加します。
まず、ターゲットの数が1個から6個に増えるので、setTgNum(1);としていた指定を以下のように変更します。
setTgNum(6);
次に、追加するターゲットの番号をきめておきましょう。
ここでは、1〜5をそれぞれ、右腕、左腕、右足、左足、胸とします。
次に、ターゲットの持つ参照ベクトルと対応するターゲットアニメーション番号、そしてアイテムがターゲットに与える影響の記述です。
ターゲット1〜4については、それぞれアイテム0,3,2,5が状態1である時にターゲットアニメーション13,14,15,16を表示するものとします。
まずは、ターゲットの参照ベクトルとターゲットアニメーション番号です。
setTgRVecNumENum(1,2,1);
setTgRVecAnm(1,0,"0.0",-1);
setTgRVecAnm(1,1,"1.0",13);
setTgRVecNumENum(2,2,1);
setTgRVecAnm(2,0,"0.0",-1);
setTgRVecAnm(2,1,"1.0",14);
setTgRVecNumENum(3,2,1);
setTgRVecAnm(3,0,"0.0",-1);
setTgRVecAnm(3,1,"1.0",15);
setTgRVecNumENum(4,2,1);
setTgRVecAnm(4,0,"0.0",-1);
setTgRVecAnm(4,1,"1.0",16);
ターゲットアニメーション番号として-1を指定している部分がありますが、これは該当の参照ベクトルが選択された場合にターゲットアニメーションを表示しない事を示しています。
次に、アイテム0,2,3,5がターゲット1〜4に与える影響の記述です。
addItemTgVec(0,1,1,"1.0");
addItemTgVec(3,2,1,"1.0");
addItemTgVec(2,3,1,"1.0");
addItemTgVec(5,4,1,"1.0");
上記のパラメータ指定により、例えばターゲット1である右腕は、アイテム0が状態1でない時は何からも影響を受けない為、アニメーションを表示せず、アイテム0が状態1の時は受ける影響が1.0となりアニメーション13を表示します。
ターゲット2〜4の動作についても同様に説明できます。
ターゲット5(胸)については、「アイテム0又はアイテム1の少なくとも一方が状態1」かつ「アイテム3又はアイテム4の少なくとも一方が状態1」」という条件を満たした時にアニメーション17を表示するものとします。
それを実現するために、ターゲットの参照ベクトルを以下のようにします。
setTgRVecNumENum(5,3,2);
setTgRVecAnm(5,0,"1.0,0.0",-1);
setTgRVecAnm(5,1,"0.0,1.0",-1);
setTgRVecAnm(5,2,"1.0,1.0",17);
ターゲット5の参照ベクトルをこのように配置する事により、参照ベクトル2が選択される条件(すなわちターゲットアニメーション17が表示される条件)は、「受ける影響の合計の第0成分が0.5より大きくて、かつ第1成分も0.5より大きい場合」という事になります。
(紙の上に図を描いて確かめてみましょう)
この事を踏まえ、アイテム0,1,3,4がターゲット5に与える影響を以下のようにします。
addItemTgVec(0,5,1,"1.0,0.0");
addItemTgVec(1,5,1,"1.0,0.0");
addItemTgVec(3,5,1,"0.0,1.0");
addItemTgVec(4,5,1,"0.0,1.0");
ここで一旦動作確認です。
アイテムブロックを消し、アイテムを稼動させてみましょう。
いかがでしょう。手足と胸は、意図したとおりに動いたでしょうか。
最後に、ボールやバー、アイテムバー等の色を調整してみましょう。
ballColor="green";
barColor="white";
itemBarColor="magenta";
blockBorderColor="orange";
messageColor="green";
backgroundColor="black";
遊ぶ時は、動作確認の為に有効にしたtest_mode指定を削除しておきましょう。
以上でsample.htmlと同じ動きをするブロック崩しを作る事ができたと思うのですが、いかがでしょうか。
今回作成したサンプルゲームで使わなかった機能のうち、特に重要な機能(であるとミニメロンが勝手に思っているもの)として、「レイヤ機能」があります。
この機能をうまく使う事により、例えば「二つのターゲットアニメーションに挟みこまれるようにして存在するアイテム」などを表現する事ができます。
その他、パラメータに関する詳細については、パラメータリファレンスを参照して下さい。
今回のサンプルは動いたのに、自分で作ったものは動かないという場合は、パラメータの読み込みに失敗している可能性があります。
このような場合は、まずはテストモードで実行してみましょう。
動きがおかしい場合や、途中で止まってしまう場合、やはりパラメータ指定に間違いや矛盾がある可能性がありますので、よくよく見直しましょう。
どうしても原因が分からない場合、ミニメロン宛にメールを頂けると、もしかしたら解決するかもしれません。
くれぐれも、学校の数学の先生の所へなど持って行って「このおっぱいの参照ベクトルの設定はどうすればよいのでしょう」などという面白い質問をして大目玉をもらう事のないようにして下さいね。
さあ、次はあなたが、「萌え萌えな女の子があられもない姿でくすぐられて身悶える、脱衣+くすぐりハンド悶絶ブロック崩し」を作る番です。
完成したら、ご自分のホームページにばんばん置いて、おおいに盛りあげてやって下さい。
え? そんな面倒な事やってられるかって?
それはもう、飽くなき煩悩の成せる術です。
「萌え萌えな女の子を存分にくすぐって悶絶させたい」
――その熱き思いは永遠に不滅なのです……よね!