ゲーム開発講座
Chapter1-3
-計算と条件の使いかただよ-
 
 
-はじめに- 
 
みなちんこんにちわ。 
オッスおらケムニャ。 
ゲーム開発講座の時間だぜ。
ヤフー! 
ポチだよ。 
今日は何をするんだっけ?
そうだな、算数でもするか。
なん・・・だと!? 
ゲーム作りてぇってのに算数・・・ 
数学どころか算数・・・! 
小学生のお勉強・・・・!
難しく考えんなよ。 
ゲームで使う計算なんて特異なもの以外ぜんぶ算数だ。
算数くらい今更勉強しなくてもわからー! 
ユタの学校で習ったわ!
(ユタ育ちだったのか・・・) 
別に算数の勉強するワケじゃないよ。 
変数の計算というのをやるんだけどソレは算数なんだ。 
算数が解かってんならすぐに出来るってことよ。
算数ができるとゲームが作れる!?
うん、作れる。
ロスの学校じゃ教えてくれなかったヨー!
(どっちなんだよ) 
さて今回使うサンプルと素材だ。 
サンプルダウンロード 

じゃあまず変数の使い方をやってみようか。

変数の使い方。
ほんじゃ、変数の勉強だ。
たまに聞くけど変数ってなんなの? 
重要?
重要重要、超重要。 
変数が無いと大概のゲームを作れないからね。 
変数というのはよく言われている説明では”箱”だね。 
箱にはデータを入れる事ができる。 
でもこの説明、俺は解かり難い気がして好きじゃないんだけど 
理解すると的をついてると思うよ。
うん、全く解からないなぁ。 
箱に入るデータってどういうこと?
まぁやったら解かるよ。 
変数ってのは前ラベルみたいに好きな名前をつける事が出来るんだ。 
例えば、 
a=10 
とすると、aという名前の変数が作成され、その中身が数字の10になる。 
こういう事もできるよ。 
a=10+2 
こうするとaの中身は12になる。
10+2=a 
じゃあないの? 
あとコレ意味あるの?
数学の計算式とは少し違うんだ。 
最初に変数名を入れて=を入れると、次の式にかかれた答えが変数の中に入る事になる。 
さて次に、さっきのだけで終わったら変数の意味が今一つ無いから中身を変えて見ようか。 
a=10 
b=15 
と、二つの変数を作ったとして次に 
a=a+b 
という式を書くと、aは10+15で25になる。
なるほど、なんとなく箱って言った意味が判ったかも。 
でも変数の重要性がまだ解からないよ。
まぁもう少し変数を理解してからだその辺りは。 
変数には数値型と文字列型があるんだ。 
さっきの式で作った変数は数値型。 
数値型は数字をつかった計算式を作る事が出来る。 
次に文字列型。 
a="おはようございました" 
数字ではなく"で囲んだ文字を入れることによって文字列型にすることができる。 
文字列型でも式を作る事が出来、たとえば 
a="おは" 
b="ようじょ" 
a=a+b 
とすると変数aの中身は"おはようじょ"になる。
数値型と文字型を足すとどうなるの?
文字型になるよ。 
a=10 
b="おうよ" 
a=a+b 
とするとaの中身は"10おうよ"という文字になる。 
a=b 
とすると、まぁ大体見当がつくだろうけどaの中身は”おうよ”になる。 
あ、文字型には制限文字数というのがあって、ソレを超えるとエラーが出るから気をつけて。 
a= 
とかで作ると文字数は64文字までしか入らない。
64文字入れば十分な気がするけど何か問題があるの?
うーん、64文字は少ないぞ。 
半角で64文字、全角で32文字だ。 
サウンドノベルとかのシナリオのデータを変数に集約しておく場合は、 
何万文字も入れないといけなくなる。 
そこで文字列型の制限文字数を増やす命令sdimがある。 
sdim p1,p2 
p1に作りたい変数名を入れ、p2に何文字まで入れる事ができるようにしたいかを数字で書く。 
sdim a,30000 
とすると変数aには3万文字まで入れる事ができるようになる。
さ、三万文字・・・ラディッツですら戦闘能力1500なのに! 
入れる事の出来る文字数はいくらでも増やせるの?
メモリーの限界があるし、HSPの認識できる数字のサイズもあるから 
いくらでもって事はないけどまぁいくらでもいけると思ってくれ。 
しかしsdimを使うとメモリーにその分だけ容量を確保しようとするから 
とんでもない数値をついカっとなって入れてみたなんてするとフリーズする恐れがあるから 
多くても1MBくらいにしておこうぜ。 
フリーズどころかクラッシュしちゃったらおしっこ漏らしますよポチさん?
ひぃ、気をつけなきゃ! 
変数の使い方は解かったからその用途を説明してよ。
そうだな、変数の使い道は他の命令と組み合わせる事にある。 
たとえばmesと組み合わせてみよう 
今までのmesの使い方は 
mes "文章" 
だったけど、こういう使い方ができる。 
a="文章" 
mes a 
また、命令内でも計算が出来るのでこういう事もできるよ。 
	a=1000
	b=30
	mes a+b			;a+bの結果が表示される。
	mes "今日は"+b+"日"	;文字列型の"今日は"と数値型の"30"と文字列型の"日"が足されて全て文字列型になる
	mes a+b+"円"		;始めに数値型の計算をすると文字型が無視されるので注意。
	mes ""+a+b+"円"		;始めに文字列を入れると全て文字列として足される。
	stop
 あと、そうだなぁ。 
変数に画像ファイルのサイズを入れておいてgcopyで使ったり、 
posで位置を定めたり。 
ああそうだ、アクションゲームとかでキャラクターが移動したとき、 
変数を足したり引いたりして位置を決めて、posで位置を定めるとか。
ああそうか。 
なんとなく理解したよ。
あと+しかやってないけど他にも色々あるぞ。 
-で引き算 
*で掛け算 
/で割り算 
\で割った時の余りの数 
実際やってみようか 
	a=10
	b=3
	mes a+b		;足し算
	mes a-b		;引き算
	mes a*b		;掛け算
	mes a/b		;割り算
	mes a\b		;余り
	stop
 
あれ? 
割り算の答え少しおかしいのが出たよ?
いいところに気がついたな。 
あとで角砂糖をやろう。 
HSPは普通じゃ小数点が表示できないんだ。 
まぁ小数点みたいな細かい事きにすんな。 
小数点でない事によって助かる所もあるしな!
そんな適当な事言うなよー。 
あと角砂糖なんていらねぇよ!
そうは言うがな少佐、出来ないものを無いもの強請りするな。 
一応機能を拡張させるDLLを使えば使えるんだが今は気にすんな。 
どうしてもしたいなら割られる数値に10掛けてから計算して1の位の前にドットでも打てばいいさ。 
あと計算の時注意しないといけない事があるんだ。 
+以外は数値型変数で使えるけど文字列型じゃ計算できない。 
まぁ綿密に言うと出来るには出来るけど"123"-3なんて計算しても 
"120"なんて答えは出ないから気をつけて。 
それと0で数を割ろうとしたときもエラーが出るから気をつけて。
なるほど、難しくはないけど注意しなきゃね。
条件式
んじゃ次は条件式いってみるか。 
コレは重要だぜ。 
ゲーム作る上じゃもうコアって感じだ。 
コアドリルって感じだ。
そんな重要なの?
そうだな、コレがないと勇者は歩けないし気に入った女の子の気を引き続けてもフラグたたないし、 
ロックマンは何もできずにメットにティウンティウンされる。
そりゃ大変じゃないか! 
どうやるんだよ!?
やり方は簡単。 
if p1 
p1には条件を入れる。 
その条件が合っているとその行にある他の命令が実行される。 
コレはさっきやった計算が生きてくるぞ。
んー? 
条件って何? 
どうすんの?
そうだなぁ。 
if a=10:mes "実行するぜ!" 
こんな感じ。 
変数aの中身が10ならその後ろのmesが実行されるんだ。 

条件は文字でもいいぞ。 
if a="はまち":mes "aの中身はまさにはまち" 
変数aが文字列型で中身がはまちならmesが実行される。 

if a=b:mes "aとbは同じものだぜ!" 
こういう事も出来る。 

=を!に変えると今度は逆に同じで無い場合実行される。
if a!"くつ下":mes "なんとaの中身はくつ下ではないという事実!"

あと計算をしたい時は式を()で括らないとだめだから気をつけて。 
if a=(b*3):mes "今のaはbの三倍!" 

さらに<や>を使い、〜以上や〜以下を識別する事も出来る。 
if a<b:mes "bはaよりでけぇ"。 
この時<=や>=という表記にすると同じ数も含む識別もできるぞ。

こんな感じだね? 
*start

	if a=5:mes "5回ループしたよ"
	if a=10:mes "10回目で止まるよ":stop
	a=a+1
	goto *start
 
お、いいね。 
でもちょっと注意しなければいけない事がある。 
ループさせるのはいいけどループ中はプログラムが走り続けて止まらない状態なんだ。 
もしstopで止まれなかったらプログラムがずっと走り続けてフリーズを起こすんだ。
えええ、それは困るなぁ。 
プログラム作る時は慎重にならないと。
でも安心してくれ。 
stop以外にも一時的にプログラムを止める方法がある。 
それがwaitとawait。 
wait p1 
await p1 
これは一定時間停止するプログラムでコレをループに入れるとフリーズは起きない。 
p1に待ち時間を入れるんだ。 
waitは1で1/100秒停止する、つまりwait 100でちょうど1秒の停止。 
awaitは1で1/1000秒停止する、つまりawait 1000でちょうど1秒の停止。 

waitに比べてawaitは精密で、 
wait 100はまぁ大体1秒 
await 1000はかなり精密な1秒になる。

んじゃ、awaitを使えばいいんだね?
いいや、そうでもないよ。 
awaitは使用するCPU率が高くなるから精密な時間計算が必要だったり 
1/1000以下の停止が必要な時以外はwaitでいいよ。
ちょっとしたゲームを作ってみよう。
よーしポチ、変数の計算とifは理解したかい?
大体解かったわ。
なら話は早い。 
お前はすでに・・・ 
簡単なRPGの戦闘プログラムを作れる!
嘘だ!
ヒィ、ナタはやめろ! 
出来る事だけで考えるんだ。 
あ、でもそうだな。 
もう一つだけ命令を覚えとくか。 
rnd p1,p2 
コレはランダムの数値を得る事ができる命令で、 
p1に変数をいれ、p2に数字を入れると変数に0〜指定した数値-1までの数のうち 
どれかが入れられる。 
rnd a,20 
とすると、aの中は0〜19のうちのどれかの数値が入る。 

RPGの戦闘では攻撃したときダメージにばらつきがあるだろ。 
ソレを出すにはランダム命令があると再現が便利だよ。 
あとコレはランダムに数字を得る事ができるけど、得る数字の順番はいつも決まっているんだ。 
そこで 
randomize 
を一度でも実行すると完全にランダムになるぞ。

んじゃ、rnd使うならrandomizeは必要不可欠ってことだね。
まぁな。 
でもパターンを固定したい時は使わないほうがいいかもね。 
たとえばリプレイデータとかを作れるゲームを作った時、 
右から攻撃がきたから左に避けるってのを再現したいのに 
左からきてぶつかってしまうっていう事故が起きるからね。
なるほど、そうだよね。 
んで、RPG作れるの? 
まったく思いつかない!
まぁ、まだ脳がプログラム脳になってないから仕方ないか。 
カンの良い人はすでに作れると思うよ。 
とりあえずルールを作るか。 
ゲームは戦闘だけで簡単なマンツーマンバトル。 
コマンドは攻撃、必殺、防御、逃げるの4つで 
攻撃は25%で威力二倍の改心の一撃が出る、 
必殺はHPを20消費して三倍のダメージを出す、 
防御は次に受けるダメージを半減させる、 
逃げるは50%の確立で戦闘から逃げる事が出来る。
わぁ、防御と逃げるってこの場合存在価値無くない?
いいんだよ、作りを理解するためのプログラムなんだから。 
ダメージ計算は、 
ダメージ=((攻撃力+ランダム-守備力)*必殺の威力)/防御効果 
って感じになるな。 
必殺の威力と防御効果の変数の中身は普段1にして選択されると他の数値にする、 
という形をとればいい。 
あと必殺の威力の変数、改心の一撃がでたら2にするのもいいね。
選んだコマンドごとに計算式を出すんじゃなくて 
そうやったら確かに便利だね。
それじゃ簡単なフロチャート書いてみるか。 
 
ちょっと雑な表だけど流れは解かるんじゃないかな。
あ、こうすると解かりやすい。 
慣れてくるまでこういうの書いたほうがいいかもね。
慣れても書いた方がいい。 
メモ帳とかチラシ裏でもいいから書いておくと整理しやすいからね。 
特に大きいものを作った時、一度製作期間が開いたときは大変だ。 
んじゃ、次に変数を決めるか。 
hp :ヒットポイント 
atk :攻撃力 
def :防御力 
rndm :ランダム系のチェック 
sp :必殺と改心の倍数 
gud :防御の有無 
敵の変数はコレらの変数の前にeをつけようか。 
あと注意しなければいけないことがあるぞ。 
RPGでは攻撃力str、精神力intという表記があるけど 
命令でもstrとintが有るからその変数を作る事が出来ないんだ。 
それじゃサンプルの「snple01_02.as」を開いて実行してみてくれ。
な、長い! 
ifとか沢山ある! 
あ、ちょっとラベルが日本語で解かりやすいかも。 
でもちゃんとRPGの戦闘っぽい!
解かりにくいだろうけど「;」を使ってそのプログラムが 
どう動いているか理解しながらプログラムの動き通りみていけば 
結構解かりやすいだろう? 
あとラベルが日本語なのはちょっとかっこ悪いかもしれないけど 
それによって自分がわかりやすいならソレでいいと思う。 
完成品は中身だれも見れないしね! 

しかしちょっとこのプログラム長い上に同じような事何度もしているよな? 
画面のリロード何度もしていてそれでプログラムも長くなっている。 
ここで新しくgosub という命令を使ってみようか。 
gosub *ラベル 
と 
return 
gosubはgotoと同じ動きをするんだけど、returnを実行すると直前に飛んだgosubの行に 
戻ってくる事が出来るんだ。 
何度も同じような処理をしたい時、その動きをプログラムしたラベルを作っておいて、 
gosubで飛ぶようにするとかなり便利になるぞ。 
gosubを使う時注意しなければいけない事は、gosubで飛んだラベル内でまたgosubで飛ぶ、 
を繰り返すことが出来るのは32回まででそれ以上飛ぶとエラーが出て止まるので注意してくれ。 
gosubを使ったサンプルは「snple01_03.as」だ。

お、これは便利だね。 
プログラムもスマートになった。 
でもこのRPGなんか不細工だね。
どんな事が出来るかってだけだからな。 
本格的なRPGはまた今度だ。 
んじゃ、今日はここまでだ
次回予告
ふう。 
今回のサンプル作りは不細工だけど確かにちょっとした知識で 
RPGが作れるっていう実感が持ててちょっと嬉しかったよ。 
次回は何するの?
そうだな。 
プレイヤーがプログラムを操作するのにbutton命令使ってたよな。 
あれじゃかっこ悪いしアクションゲームじゃ使えないからキー入力の命令文とか 
・・・そうだアニメーションとかしてみるか。 
うーん、もう初歩基礎覚える事少なくなってきたな。
そいつぁつまり私はかなり極まってるって事カナ?カナ!? 
壮大なゲーム作れちゃうカナ!
うほ、図々しい子! 
お前なんかプログラムの片足の踵もつっこんじゃいねえよ! 
弁えろ雌犬が!
よ、避けたはずなのになんか痛い! 
やるなポチ。
自分から当たりに行ったように見えたんだけど
まぁしかし、「プログラムの組み方」の発想が出来るようになったら 
少ない命令でも十分ゲームを作れるようになる。 
まだ習得した命令は少なく、まだまだ沢山あるけど基礎から覚えると 
新しい命令の吸収も早くなり、習うまでもなく新しいものを身に付けていけるようになる。 
基礎と継続は力ってやつだ。
まだまだ道は遠そうに見えて、そう遠くも無いってことか。 
んじゃ、また来週!
バカヤロウ 
俺には他にする事があるんだよ。 
ってなワケでまた来週じゃなくてまた次回!
今日はここまで。
 
今回のまとめ 
変数=数値や文字、又は計算式 
変数の中に数値や文字を入れる。 
計算式を書いた場合、その答えが変数に入る。 
数値は半角の数字を、文字を入れる場合は「"」でくくった中に文章を書く。 
計算式には以下のようなものがある。 
+:足し算(文字と文字を足した場合、二つの文章を結合させる事が出来る) 
-:引き算 
*:掛け算 
/:割り算 
\:割り算をした時の余りの数 
また変数は他の命令の中に組み込む事が出来る。 
	a=10
	b=3
	mes a+b
	mes a-b
	mes a*b
	mes a/b
	mes a\b
	a="おはよう"
	b="ござい"
	mes a
	mes a+b
	mes a+b+"ました"
	stop
 
sdim p1,p2 
変数の中に文字を入れた場合、半角64文字、全角32文字しか入らないが、 
この命令を使う事によって、入れる事の出来る文字数を増やすことが出来る。 
p1に拡張したい変数名を入れp2に入れる事のできる半角文字数を入れる。 
	sdim a,1024
	a="これでaの中に半角1024文字、全角512文字入れる事が出来る。"
	a=a+"1024で1KBです。"
	mes a
 
if 条件式
条件式を満たすと同じ行の命令が実行される。
条件式は計算式と同じものを使う事が出来、また以下のようなものがある。
a<b:変数aが変数bより小さい時、条件を満たす。
a>b:変数aが変数bより大きい時、条件を満たす。
a<=b:変数aが変数bと同じかまたそれより小さい時条件を満たす。
a>=b:変数aが変数bと同じかまたそれより大きい時条件を満たす。
a!b:変数aと変数bが別の時、条件を満たす。
a=b:変数aと変数bが同じ時、条件を満たす。
	a=10		;変数の中身を変えて実行してみてください
	b=15

	if a=b:mes "aとbは同じで中身は"+a+"です。"
	if a!b:mes "aとbは別物でaは"+a+"で、bは"+b
	if a<b:mes "aは"+a+"なのでbより小さいです"
	if a>b:mes "aは"+a+"なのでbより大きいです"
	if a=(b+10):mes "aはbよりちょうど10大きい数値です"
	if a=(b*3):mes "aはbの三倍です"
	if a="おはよう":mes "aの中にはおはようという文字が入っています。"
	stop
 
もどる