《第9回》ギコ猫アタッカー!『リアルタイム・アクションゲームを作る』 新時代のリアルタイム・ゲームは、これ。高速CPUやブロードバンド技術が可能にし た、最新手法である。 ※後記。このスクリプトは、一画面=一リロードという、究極のネットワーク・アクシ ョンゲームなのですが、このシャレは、プログラマーの人でないと、ピンと来ないよう です……。 ※ダウンロードのコーナーから、windows用(jperl用sjis)と、Li nux用(perl用euc)をダウンロードできます。 ※windowsは、「http://localhost/cgi-bin/dea th.pl」。linuxは、「http://localhost/cgi-bin /death.cgi」です。 ※インターネットに接続されているサーバからは、ネットワーク越しにもこのゲームを 愉しめます。 ※ネットワークでこのゲームを愉しむには、最初からやるとスピードが遅いので、途中 からはじめると良いでしょう。「http://localhost/cgi-bin /death.pl?db=00+x=3+s=2000+on=1+go=2+」 リアルタイム・アクションゲーム! Perlでゲーム作りに挑戦する。オセロのような"思考型"や、ライフ・ゲームの ような"ありがち"、そして、RPG(文字ベース)など手法的に簡単なゲームではな く、ずばり「リアルタイム・アクションゲー」である。 まずは、起動画面を見ていただこう。障害物(岩?)の間に空いた、隙間の道(?)を落下していくキャラ……を操作して 、ただひたすら、命を長引かせるゲームである。クリアはない(笑)。 パソ歴の長い読者は、この画面に見覚えがあるかもしれない。MSXや、それ以前、 パソコンがまだ8ビットだった時代に、BASICで繰り返し書かれたゲームである。 ゲームを開始すると、DOS窓が開いて……。ちょっと待った! まさか、ギガ級P entium4時代にこんなクソゲーをまじめに回顧する意義はないだろう。 マシンの性能をフルに生かしたい。すなわち、通常のゲームは「1ステージごと」に CDやHDDからプログラムやデータを読み込んで進行する。本スクリプトは、「1ア クションごと」に、Webサーバに読みに行くのである(^ ^;)。 8ビット時代に、BASICインタープリタでも余裕で動いたこのゲームも、1アク ションごとのリロードは、さすがに負担が大きいらしく、PentiumV-700M Hzでも速度が速くなると、操作がほとんどきかなくなる。途方もなく非効率的なこの 手法は、まさに、新時代のプログラム手法なのだ(?)。 @ マシンリソース大食らい。 A ネット帯域大食らい。 B サーバリソース大食らい。 C そして動いたゲームが、誰がやってもつまらない、ただのクソゲー。 これこそ、贅沢中の贅沢。 スクリプト では、さっそくスクリプトを見てほしい(リスト1)。エンドロール・アニメに、行 を割いているわりには、あっさりしている。 手法的には、「<BODY onLoad=setTimeout('loc ation.href="URL"',TIME>」のタグにより、矢継ぎ早に 、次画面をリロードし続けることで、ゲームが進行する。 今回は「getメソッド」。スクリプトの「$qs = $ENV{'QUERY_ STRING'}」に注目しよう。ブラウザのURL欄に「http://local host/abc.pl?zzz」と記述してabc.plを起動すると、「$qs」 には、「zzz」が格納されるという寸法だ。この性質により、「1アクションごとの 画面推移=全変数」を、すべてURL欄に記述して、スクリプトに渡している。 《変数》 変数の扱い方そのものが、このスクリプトのミソなので、変数を紹介しておこう。 $zenx=45…定数 この定数を増やすと、横軸空間が広くなる(最大97)。デフォルトでは、横軸には 47個の障害物(=■)があるが、左端と右端は、常に障害物が存在する。この二つを 除外した、「47−2=45」が、x軸方向の障害物の最大値(dbの項目参照)。 $zeny=30…定数 この定数を増やすと、縦軸空間が広くなる(最大99)。0〜30で、計31行の空 間をもっている。 db…$db…変数 障害物のデータベース。10進数2桁で、横軸1行分の障害物を描画できる。 簡略図で描くと、 ■ ■■■■00 ■■ ■■■01 ■■■ ■■02 ■■■■ ■03 …のように、2桁の数字は岩の中の道の位置を表わしている(45で最右端)。 障害物はぜんぶで31行あるので、2桁の数字が31並ぶ。たとえば、上図の3行の 岩と道は、00010203の8桁の数字で表わすことができる。 x…$ichi…変数 キャラ猫の位置。障害物と同じ数字になると左がぶつかり、「障害物+7」になると 右がぶつかり、猫は死ぬ。「障害物−1」「+6」で障害物に接触するので、顔が恐怖 にひきつる(操作の項の図を参照)。 on…$on…変数 1で通常の状態。0で起動初期。2〜7でキャラ猫が死ぬアニメの状態。8でアニメ が終了して、スコアを表示している状態。 m…$m…変数 0で猫が左を向く。1で右。 s…$s…変数 スコア。記事の行数の制限から、スコア・パラメータが、落下スピードも兼ねている (大きいほど速い)。 go…$go…変数 キャラ猫の進行方向。0で連続左。1で1つ左。2で下。3で1つ右。4で連続右。 手法 注意が必要な手法を解説しよう。 ●&getiwa(→for(0..30){$iwa[$_]=substr($d b,($_ * 2),2);})により、ズラズラと数字が並ぶ$dbを2桁ずつの 変数に分解し、$iwa[X]に入れている。 ●&rotateでは、キャラ猫を1つ分落下させている。正確には、$iwa[X] を一つずつズラし、障害物を上昇させているのだ。 最下端では、「$iwa[30]=($iwa[30]+ int(rand(3)) -1)」により、乱数で障害物の間の道の位置を、±1の範囲で変化することでうねら せている。 最上端では、数値がズレると、キャラ猫がズレるので、いちばん上と二番目は必ず同 じ数字になるようにしている。 何のことか分からない読者は、「$iwa[0]=$iwa[1]」を削除すれば、 納得すると思う。 ●&prnmainでは、実際に障害物を描いている。「for(0..$zeny) 」のループが、「$_=0」「$_=1」のときは、キャラ猫の上部分と下部分を描い ている。キャラ猫の位置により、左右に描く全角空白の個数を調整している部分が少し 面倒なところ。 操作・起動 キャラ猫はネットで流行っているネコキャラのバリエーションで作った。 非公開のローカルWebサーバを起動させ、cgi-binフォルダにdeath. plをコピー(リネーム不可)し、ブラウザから、「http://localhos t/cgi-bin/death.pl」を起動すれば、ゲームが始まる。最初は、イ ラつくほど遅いが、だんだん、スピードアップする。スコア1000くらいから、まと もな速度になるだろう。 中速度からはじめたい場合は、「http://localhost/cgi-bi n/death.pl?db=00+x=3+s=2000+on=1+go=2+」 のようにパラメータを与えて起動する。sを大きくすると速くなる。 操作は、実に単純。画面上の「<←↓→>」をクリック。左から、「連続左」「一つ 左」「下(連続解除)」「一つ右」「連続右」。
猫の向きが変わったり、岩にぶつかりそうになると、顔が変わる。
いずれにしてもクソゲー。救いようはない。これは、ゲームそのものを楽しむのでは なく、ゲームで猫を殺したいS(サド)か、ネコのアニメを見て、最後に罵倒されたい M(マゾ)が1分、時間をつぶすためのゲームである(笑)。
ネット上で公開 ローカルWebサーバのためのゲームだが、ブロードバンド・ユーザーや、学校の専 用線につないだサーバを触れるユーザーなら、ネットで公開することもできるだろう。 回線の速度は、速ければ速いほどよい。 Webサーバの設定を代え、ポートを外にも開き、ゲームを公開してみよう。 以下私見だが、HTTPDを公開するなら、「AN HTTP Server」など の歴史の浅いWebサーバより、思い切って「apache」を導入しよう。「IIS 」に関しては、「AN HTTP」より脆弱だとも思えないが、普及しているので、タ ーゲットにされやすい。Webサーバを公開したとたんに、「IIS」を狙った連続攻 撃に、ただちにさらされるので、マメなアップデートを行なえない素人は手を出さない ほうが無難かもしれない。 外部に対してポートを開いたら、自分のマシンのIPアドレスを調べよう。IPが「 www.xxx.yyy.zzz」だとしたら、「http://www.xxx.y yy.zzz/cgi-bin/death.pl」にアクセスすれば、Win以外の OSからでもこのゲームを楽しむことができる。実はこのクソゲー、マルチプラットホ ームだったのだ(当たり前)。 Linuxマシンへ対応させるのも簡単である。1行目を「#!/usr/bin/ jperl」などとしてjperlにパスを通し、「charset=ShiftJI S\">」のタグを「charset=x-euc-jp\">」にする など、文字コードを気にすれば、まず動くだろう。 高速ブロバン時代こそ、Webサーバ+Perlスクリプトのクソゲー 次にくる、さらなる高速ブロードバンド時代、光ファイバーFTTH時代にはいった いどのようなコンテンツを供給したらよいのか。ちまた巷では、話題が尽きない。映画 ?ミュージックビデオ?そう、動画。やっぱり動画なのか、結局は。行きつく先は、そ こしかないのか。 しかし、私はこう考える。Perlによるクソゲーを、ギガ級の高速回線で楽しむこ とをこそ、人は、豊かと呼ぶのだ……と。 誰かこの方法で『パックマン』をつくってほしい。 (辻 豊史) HP「今日からPerlプログラマー(http://www.geocities co.jp/SiliconValley-Cupertino/6103/)」 リスト1 「リアルタイム・アクションゲーム」スクリプト(death.pl) sjis保存。jperlで起動させる。 ※注! 以下の「□」は、総て、「 」(全角空白)に置換して使用すること! #!C:/Perl/bin/MSWin32-x86-object/jperl #↑apache者は、パスを書く必要がある。↓□は、総て全角空白のことである $qs = $ENV{'QUERY_STRING'}; $aki = "□□□□□□□□□□□□□"; $zenx=45;$zeny=30;$db=&ps("db"); $ichi=&ps("x");$on=&ps("on"); $m=&ps("m"); $s=&ps("s"); $go=&ps("go"); if ($on eq "") { $db ="20";$db x= ($zeny + 1); $ichi=23;$on=1;$m=0;$s=0;$go=2;srand; } $kgo = $go; ($kgo==0)&&($kgo=1); ($kgo==4)&&($kgo=3); $ichi = $ichi + $kgo - 2; ($ichi < 0) && ($ichi = 0); ($ichi > ($zenx + 6)) && ($ichi = $zenx + 6); ($go >= 1)&&($go <= 3)&&($go=2); &getiwa; &rotate; $br = "<BR><BR><BR><BR><BR><BR><BR><BR>"; $sp="□□□□□□□";#←全角空白7ケ $deadz="<HR></BODY></HTML>"; $dead[1]="□ ∧∧□あ……!<BR>□( ゚◆゚)∩<BR>⊂ ・**;∴<BR>□〜\□・ヽ.<BR>□□□□U U<BR>$br<BR>"; #dead処理 $dead[2]="$sp□(´⌒(´<BR>□□□□□□(´⌒;;;<BR>□□□(´⌒(´⌒;; <BR><BR>ひゅ〜<BR>□□・*<BR>□*;∴<BR>□□□□ノ∩ <BR>□□⊂□ ヽ <BR>□□□/(□。A。 )っ<BR>□□ U□∨□∨ <BR><BR><BR><BR>"; $dead[3]="$sp ・<BR><BR>$sp□*<BR><BR>$sp□∴;<BR><BR><BR><BR>$sp□□□*;<BR><BR>$sp□∴;*<BR><BR>□□□□∧∧□□|□□□どさりっ!<BR>\⊂(□□ ⊂⌒`つ□/<BR>"; $dead[4]="$br$sp$spふら〜.....<BR>$sp$sp$sp ∧∧<BR>$sp$sp$sp(; ゚д゚)<BR>$sp$sp$sp/□づつ<BR>$sp$sp□□□□〜/□ /<BR>$sp$sp□□□□□(/□∪"; $dead[5]="<BR>$br<BR><BR><BR>$sp$sp$sp□□(□□□∧∧<BR>$sp$sp$sp□⊂⌒つ*゜◇゜)つバタッ!";$dead[6]="<BR><BR><BR>□□□□⊂⊃<BR>□□□□∧ ∧<BR>□□□□( ゚Д゚)□ヴヴヴヴ...<BR>□□□|⌒つ□つ<BR>□□□川 |□|<BR>□□□□U□U<BR><BR><BR><BR>□□∧∧<BR>つ*゜◇゜)つ";$dead[7]="<BR>⊂⊃<BR>∧ ∧<BR>(゚Д゚ )ヘタクソッ<BR>⊂ □)⌒|<BR>□|□|川<BR>□U U$br"; if ($on==8) { $speed=""; &head; print"score□$s";exit; } if (($on > 1) || ($iwa[2] >= $ichi)||($iwa[2]+7<=$ichi)){ $speed=2000; $on++;&head;print $dead[($on-1)];print $deadz;exit; } $r1="□(□□∧∧♪";$l1="□ ∧∧□□)□"; $r2="⊂'⌒つ'Д`)つ"; $l2="⊂(゚Д゚⊂⌒'つ"; if (($iwa[2]+1 == $ichi) || ($iwa[2]+6 == $ichi)) { $l1=" Σ∧∧□く∩";$l2 = "∩(゚◆゚⊂⌒' )"; $r2="( '⌒つ゚◆゚)∩";$r1="∩/ ∧∧□□"; } $s=$s+10;$speed = 900-int($s/2); ($speed < 20) && ($speed = 20); #game main; &head; &scline; &prnmain; print $deadz; sub scline { $s = sprintf("%05d", $s); print "$aki<FONT SIZE=+3>score□$s$aki<A HREF=\"${url}m=0\+go=0\+\"><</A>□<A HREF=\"${url}m=0\+go=1\+\">←</A> <A HREF=\"${url}m=$m\+go=2\+\"> ↓</A> <A HREF=\"${url}m=1\+go=3\+\">→</A>□<A HREF=\"${url}m=1\+go=4\+\">></A></FONT><BR>\n"; } sub head { $url = "death.pl\?db=${db}\+on=${on}\+s=$s\+x=$ichi\+"; $dead0="Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><TITLE>DEAD</TITLE><META http-equiv=Content-Type content=\"text/html; charset=Shift_JIS\"><BODY onLoad=setTimeout('location.href=\"${url}m=$m\+go=$go\+\"\',$speed)>"; print $dead0; } sub getiwa { for (0 .. $zeny) { $iwa[$_] = substr($db, ($_ * 2), 2); } } sub prnmain { for (0 .. $zeny ) { $chara = $aki; if ($_ < 2){ $c1=($ichi-$iwa[0]-1); $c2=5-$c1;$chara=""; for (1..$c1) { $chara.="□"; } ($m==0)&&($_==0)&&($chara.=$l1); ($m==1)&&($_==0)&&($chara.=$r1); ($m==0)&&($_==1)&&($chara.=$l2); ($m==1)&&($_==1)&&($chara.=$r2); for (1..$c2) { $chara.="□"; } } $now = $_; for (0 .. ($iwa[$now] ) ) { print "■"; } print $chara; for (0 .. ($zenx - $iwa[$now]) ) { print "■"; } print "<BR>\n"; } } sub rotate { for (0 .. ($zeny - 1) ) { $iwa[$_] = $iwa[($_ + 1)]; } $iwa[0]=$iwa[1]; $iwa[$zeny] = ( $iwa[$zeny] + int (rand (3)) - 1); ($iwa[$zeny]<0) && ($iwa[$zeny] = 0); ($iwa[$zeny] > $zenx)&&($iwa[$zeny]=$zenx); $db = ""; for (0 .. $zeny) { $db .= sprintf("%02d", $iwa[$_]); } } sub ps { local ($hensu) = @_; local ($psl) = $qs; $psl =~ s/^$hensu=([^+]*)\+?.*$/$1/; $psl =~ s/^.*\+$hensu=([^+]*)\+?.*$/$1/;return ($psl); } −−−−−−−−−上記は、雑誌「I/O」掲載版−−−−−−−−−−−−− -------以下は書籍「今日からPerl/CGIプログラマー」掲載の機能アップ版-------- ---以下に関しての詳細は、書籍「今日からPerl/CGIプログラマー」を参照のこと--- ---(書籍「今日からPerl/CGIプログラマー」は、図書館や大型書店にあります。)-- #!C:/Perl/bin/perl #↑apache者は、パスを書く必要がある。↓□は、総て全角空白のことである #ギコ猫アタッカー #リアルタイムCGIゲーム # #perlスクリプトである。jperlでは動作しない。 #EUC+LFで保存すること。 # #1行目を「#! /usr/bin/perl」などと、パスを通せば #Unix系サーバでも動作可能 # #copyright 2003 『今日からPerl/CGIプログラマー』 辻豊史 #http://www.geocities.co.jp/SiliconValley-Cupertino/6103/ # #註・「□」は、総て全角空白のことである #---定数決定 $zenx=45;#画面全体の横軸の大きさ $zeny=30;#画面全体の縦軸の大きさ $aki = "□□□□□□□□□□□□□"; #---QUERY_STRINGを変数に分解する @get = split(/&/, $ENV{'QUERY_STRING'}); foreach (@get) { ($x ,$y) = split(/=/, $_);$q{"$x"} = $y;} $db=$q{"db"};$ichi=$q{"x"};$on=$q{"on"};$m=$q{"m"};$s=$q{"s"};$go=$q{"go"}; #---最初の起動の場合変数を初期値に(スコアがある場合のみスコアクリアしない) if ($on eq "") {$db ="20"; $db x= ($zeny + 1); $ichi=23;$on=1;$m=0;$go=2;srand;(!($s>10))&&($s=0);} #---$go 進む方向 $kgo goの「0」「1」は左「3」「4」は右なのでkgoで調整 $kgo=$go;($kgo==0)&&($kgo=1);($kgo==4)&&($kgo=3);$ichi=$ichi+$kgo-2; #---$ichiが画面からはみ出ないように ($ichi < 0) && ($ichi = 0);($ichi > ($zenx + 6)) && ($ichi = $zenx + 6); ($go >= 1)&&($go <= 3)&&($go=2); #---障害壁位置決定・障害壁ローテイト @iwa = &getiwa($zeny,$db);($db,@iwa) = &rotate($zeny,@iwa); #---描画定数 $br="<BR><BR><BR><BR><BR><BR><BR><BR>";$sp="□□□□□□□";#←全角空白7ケ $page_end="<HR></BODY></HTML>"; #---死去アニメ画像 $dead[1]="□ ∧∧□あ……!<BR>□( ゚◆゚)∩<BR>⊂ ・**;∴ <BR>□〜\□・ヽ.<BR>□□□□U U<BR>$br<BR>";#dead処理 $dead[2]="$sp□(´⌒(´<BR>□□□□□□(´⌒;;;<BR>□□□(´⌒(´⌒;; <BR><BR>ひゅ〜<BR>□□・*<BR>□*;∴<BR>□□□□ノ∩ <BR>□□⊂□ ヽ <BR>□□□/(□。A。 )っ<BR>□□ U□∨□∨ <BR><BR><BR><BR>"; $dead[3]="$sp ・<BR><BR>$sp□*<BR><BR>$sp□∴;<BR><BR><BR> <BR>$sp□□□*;<BR><BR>$sp□∴;*<BR><BR>□□□□∧∧□□|□□□どさりっ! <BR>\⊂(□□ ⊂⌒`つ□/<BR>"; $dead[4]="$br$sp$spふら〜.....<BR>$sp$sp$sp ∧∧<BR>$sp$sp$sp(; ゚д゚) <BR>$sp$sp$sp/□づつ<BR>$sp$sp□□□□〜/□ / <BR>$sp$sp□□□□□(/□∪"; $dead[5]="<BR>$br<BR><BR><BR>$sp$sp$sp□□(□□□∧∧<BR> $sp$sp$sp□⊂⌒つ*゜◇゜)つバタッ!"; $dead[6]="<BR><BR><BR>□□□□⊂⊃<BR>□□□□∧ ∧ <BR>□□□□( ゚Д゚)□ヴヴヴヴ...<BR>□□□|⌒つ□つ <BR>□□□川 |□|<BR>□□□□U□U<BR><BR><BR><BR>□□∧∧ <BR>つ*゜◇゜)つ"; $dead[7]="<BR>⊂⊃<BR>∧ ∧<BR>(゚Д゚ )ヘタクソッ<BR>⊂ □)⌒| <BR>□|□|川<BR>□U U$br"; #---終了 if($on==8){$speed="10000";&head(undef,undef,$speed,undef,undef,$s,undef); print"score□$s<BR><BR>10秒後に再開します → <A HREF=$ENV{'SCRIPT_NAME'}?on=9&>NO</A>";exit;} if($on==9){$speed="300000";&head(undef,undef,$speed); print"最初からやる → <A HREF=$ENV{'SCRIPT_NAME'}>click</A>";exit;} #---死去アニメ if (($on > 1) || ($iwa[2] >= $ichi)||($iwa[2]+7<=$ichi)){ $speed=2000; $on++;$url = &head($go,$m,$speed,$db,$on,$s,$ichi);print $dead[($on-1)]; print $page_end;exit;} #---キャラ猫アニメ $r1="□(□□∧∧♪";$l1="□ ∧∧□□)□"; $r2="⊂'⌒つ'Д`)つ";$l2="⊂(゚Д゚⊂⌒'つ"; if(($iwa[2]+1==$ichi)||($iwa[2]+6==$ichi)){$l1=" Σ∧∧□く∩"; $l2="∩(゚◆゚⊂⌒' )";$r2="( '⌒つ゚◆゚)∩";$r1="∩/ ∧∧□□";} #---スピード計算(スコアより算出) $s=$s+10;$speed = 900-int($s/2);($speed < 20) && ($speed = 20); #--game main $url = &head($go,$m,$speed,$db,$on,$s,$ichi); &scline($s,$url);#操作パネル &prnmain($zeny,$zenx,$ichi,$m,$r1,$r2,$l1,$l2,@iwa);#メイン描画 print $page_end; #---サブルーチン #---操作パネル表示 sub scline { my $s = shift;my $url =shift; $s=sprintf("%05d", $s);print "$aki<FONT SIZE=+3>score□$s$aki <A HREF=\"${url}m=0\&go=0\&\"><</A>□<A HREF=\"${url}m=0\&go=1\&\">←</A> <A HREF=\"${url}m=$m\&go=2\&\"> ↓</A> <A HREF=\"${url}m=1\&go=3\&\">→ </A>□<A HREF=\"${url}m=1\&go=4\&\">></A></FONT><BR>\n";} #---HTMLヘッダと次画面読み込み表示 sub head {my $go = shift;my $m = shift;my $speed = shift; my $db = shift;my $on = shift;my $s = shift;my $ichi = shift; my $url = "$ENV{'SCRIPT_NAME'}?db=${db}\&on=${on}\&s=$s\&x=$ichi\&"; my $dead0 = "Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-// W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><TITLE>CAT ATTACKER</TITLE> <META http-equiv= Content-Type content=\"text/html; charset=x-euc-jp\"> <BODY onLoad=setTimeout('location.href=\"${url}m=$m&go=$go\&\"\',$speed)>"; print $dead0;return($url)} #---障害物(岩壁)の位置を確定($dbには岩壁のない位置が入っている。 #---例えば、03 04 04……のように2桁分で区切れる。 #---2桁分で画面1行分の岩壁の位置が計算できる sub getiwa { my $zeny = shift;my $db = shift;my (@iwa); for (0 .. $zeny) { $iwa[$_] = substr($db, ($_ * 2), 2);} return(@iwa); } #---メイン部分描画 sub prnmain { ($zeny,$zenx,$ichi,$m,$r1,$r2,$l1,$l2,@iwa) = @_; for (0 .. $zeny ) { my $chara = $aki;my $now = $_; #--最初の二行はキャラ猫を描くので$akiを作成しなおす if($_<2){$chara="";my $c1=($ichi-$iwa[0]-1);my $c2=5-$c1; for(1..$c1){$chara.="□";} ($m==0)&&($now==0)&&($chara.=$l1); ($m==1)&&($now==0)&&($chara.=$r1); ($m==0)&&($now==1)&&($chara.=$l2); ($m==1)&&($now==1)&&($chara.=$r2); for(1..$c2) {$chara.="□";} } #---障害壁の中にキャラ猫or空白($aki)を描画 for (0..($iwa[$now])){print "■";} print $chara; for(0..($zenx - $iwa[$now]) ) { print "■"; } print "<BR>\n"; } } #---障害壁を一つアップ sub rotate { my $zeny = shift;my @iwa = @_;my $db = ""; for (0 .. ($zeny - 1) ) { $iwa[$_] = $iwa[($_ + 1)];} #---一行目は二行目と一緒にしてキャラ猫の場所を確保 $iwa[0]=$iwa[1];$iwa[$zeny]=($iwa[$zeny]+int(rand(3))-1); ($iwa[$zeny]<0) &&($iwa[$zeny]=0);($iwa[$zeny]>$zenx)&&($iwa[$zeny]=$zenx); for (0 .. $zeny) { $db .= sprintf("%02d", $iwa[$_]);} return($db,@iwa); }