語らいの一時オンライン

HSP3.3でブロック崩しを作る!

<第1回>ラケットボールを作ってみる!

<第2回>ブロックを追加してみる!

<第1回>ラケットボールを作ってみる!

2012/10/2

まずはブロック以外を作ってみる

ゲーム作りの基本中の基本であろうブロック崩しですが、実は私自分で作ったことがありません!
せっかくなので、この機会に作ってみようと思います。
是非初心者の方も入力して動かしながら、そして色々数字を変えてみながら作っていってみて下さい。
それでは、始まります。


ブロック崩しを作るに当たって、必要な要素はなんでしょうか?
1.ボール
2.パドル
3.ブロック
4.壁
主なものはこんなところでしょう。
ひとまず、壁は画面の端で代用することにします。
ブロックも配置やら当たり判定やら面倒そうなので、後回しにします。
今回はパドルをマウスで操作して、ボールを跳ね返すことができ、下に落としてしまったらゲームオーバーというところまでやってみます。
プログラムに注釈を付けているので、分かりにくそうな部分のみ解説します。

まず、冒頭の「#define」というところでは、「定数」を定義しています。
簡単に言うと、以降のプログラムで同じ値を使うものを宣言しています。
ここで決めておくと、後で何かのサイズなどを変えたいと思った時に、この定数の宣言のところだけを変えればプログラム全てに適用できるという大変便利なものです。
小規模なプログラムではあまりメリットを感じないかもしれませんが、後々バージョンアップしていく際にはその意義をご理解いただけると思います。

次に*mainの中の「redraw 0」と「redraw 1」なんですが、これは実際の画面に描画するかどうかを決めています。
まず画面を描画しない設定にしておいて、内部処理で画面をクリア→ボールを描画→パドルを描画→実際の画面に描画というようにすることで、画面のチラツキを防止しています。

続いて「x+=dx」「y+=dy」という部分ですが、これは「x=x+dx」「y=y+dy」と同じ意味で、ボールを移動させています。
プログラムを少し短くでき、見た目にもすっきりするので、慣れたら使ってみてください。

そして、今回一番ややこしそうな箇所、ボールの当たり判定です。
「if x<0 or x+size>winx:dx=-dx」ですが、「x<0」はウインドウの左端に達した場合、「size」はボールのサイズ、「winx」はウインドウのXサイズなので、「x+size>winx」はウインドウの右端に達した場合です。
「dx=-dx」とすることで、ボールの動く方向を反対にしています。
「if x>=px-p_size-size & x<=px+p_size+size & y+size=py:dy=-dy」については、「px-p_size-size」がパドルの左端、「px+p_size+size」がパドルの右端を表しています。
パドルの端に当たった場合を考え、左右はボール一個分当たり判定を広げています。

		

*init #define winx 320//画面のXサイズ #define winy 480//画面のYサイズ #define size 12//ボールのサイズ x=160.0:y=0.0//ボールの初期位置 dx=4.0:dy=4.0//ボールの移動速度 px=300:py=440//パドルの初期位置 p_size=20//パドルのサイズ screen 0,winx,winy,0//画面作成 pos 90,200:color 0,0,0:mes"Click to start!"//スタート画面 *start stick st//入力設定 if st=256:goto *main//マウスの左クリックでメイン処理へ await//ウェイト goto *start//戻る *main redraw 0//画面を描画しない color 255,255,255:boxf 0,0,winx,winy//白で画面全体を塗り潰す color 0,0,0:circle x,y,x+size,y+size//黒でボールを描く x+=dx//ボールのX座標に移動速度を足す y+=dy//ボールのY座標に移動速度を足す if x<0 or x+size>winx:dx=-dx//ボールが左右の端に行ったらボール速度を反転(逆方向) if y<0 or y+size>winy:dy=-dy//ボールが上下の端に行ったらボール速度を反転(逆方向) if x>=px-p_size & x<=px+p_size & y+size=py:dy=-dy//ボールがパドルに当たったらボール速度を反転(逆方向) if y=480-size:pos 120,200:color 0,0,0:mes"Game Over":redraw 1:await 1000:goto *init//ゲームオーバー処理 px=mousex:color 255,0,0:boxf px-p_size,py,px+p_size,py+8//パドルを表示 await 2//ウェイト redraw 1//画面を描画する goto *main//戻る

次回はブロックを配置して、ブロックの当たり判定を入れて、ブロック崩しが完成します!
お楽しみに♪


HSP参考書色々


メインページへ戻る

<第2回>ブロックを追加してみる!

2012/10/4

ブロックを追加して当たり判定を付ける

前回はブロック以外の部分を作りました。
今回はいよいよブロックを配置し、当たり判定を付けてブロック崩しとして完成させます。

まず初期設定でボールの初期位置等を変更し、スコアの初期化を追加しています。
続いてブロックの初期設定を行っています。
20個のブロックを作ることとし、ブロックのフラグ、位置、サイズを設定します。
この際、「dim」という命令を使用していますが、これはその変数の最大個数を決めています。
プログラム用語では「配列」と言います。
イメージとしては、値を入れる箱が変数とすると、その箱が横に繋がっているような感じです。
箱の何番目に何が入っているかという風に使用していくものです。
例えばblfの場合は、「blf.i」のように変数の名前の後に「.i」のように表記し、ブロックのi番目に0が入っているか1が入っているかを判断し、ブロックを表示するかどうかを決めています。
ゲームが始まる段階ではblf.0からblf.19まで全て1にし、ブロックが全て存在するという設定をしています。
同様にブロックのXサイズ、Yサイズも設定しています。

ブロックの表示部分では、「blf.i」の値をチェックし、1であれば表示しますが、0の場合は何もしません。つまり表示しません。

ブロックとボールの当たり判定が今回の一番の難所です。
プログラムをパッと見た感じだと何が何やら分からないかもしれませんが、行っていることが分かると読めるようになると思います。
まず、「if blf.i=0:_continue」という部分です。
ここではブロックがない場合に次のブロックの判定を行うように「_continue」命令を使っています。
もしこの文がないとどうなるかというと、ないはずのブロックにボールが跳ね返ってしまいます。一度試してみるのもいいでしょう。
次にボールがブロックの上から当たった場合を考えてみましょう。
「if(y+size=bly.i) & (x>=blx.i-size & x<=blx.i+blx_size.i+size):blf.i=0:dy=-dy:sc+=100:_break」という文ですが、まず「if(y+size=bly.i)」というのはボールの下のY座標がi番目のブロックのY座標と等しければという意味です。
「x>=blx.i-size & x<=blx.i+blx_size.i+size」はボールのX座標がi番目のブロックの左端のX座標-ボール一個分以上かつ、i番目のブロックの右端のX座標+ボール一個分以下という意味です。「-size」「+size」でボール一個分左右に当たり判定を広げています。
そして、その条件と合致した時に「blf.i=0:dy=-dy:sc+=100:_break」を実行します。
「blf.i=0」でブロックのフラグをオフにして消去します。
「dy=-dy」でボールの移動方向を反転させます。
「sc+=100」でスコアに100点追加します。
「_break」でループから抜けます。
ボールが他の方向から当たった場合も殆ど同じ処理なので割愛します。

最後にクリア判定の処理を見てみます。
ここではclというフラグを作り、blf.0からblf.19まで全て加算し、その値が0であればクリアという判定をしています。
このやり方以外にもブロックを崩すごとにフラグに加算し、その値を調べるという方法でもいいと思います。

この講座では一応の完成ですが、ブロックの当たり判定が完璧とは言えませんし、1面しかなかったり、1回のミスでゲームオーバーになってしまったり、色々改良の余地もあります。
是非皆さん自身の手で改良を行ってみて下さい。
プログラム上達の近道はとにかく自分で考えて打ってみることに尽きます。

		

*init title"Block" #define winx 320//画面のXサイズ #define winy 480//画面のYサイズ #define size 12//ボールのサイズ x=160.0:y=140.0//ボールの初期位置 dx=2.0:dy=2.0//ボールの移動速度 px=300:py=440//パドルの初期位置 p_size=25//パドルのサイズ sc=0//スコア //ブロックの初期設定
dim blf,20//ブロックのフラグを初期化 dim blx,20//ブロックのX位置を初期化 dim bly,20//ブロックのY位置を初期化 dim blx_size,20//ブロックのXサイズを初期化 dim bly_size,20//ブロックのYサイズを初期化 //ブロックの初期設定 for i,0,20 blf.i=1//ブロックのフラグを立てる blx_size.i=40//ブロックのXサイズ bly_size.i=10//ブロックのYサイズ //ブロックのX位置 if i>=15:blx.i=20+(i-15)*60 if i<15 & i>=10 :blx.i=20+(i-10)*60 if i<10 & i>=5 :blx.i=20+(i-5)*60 if i<5:blx.i=20+i*60 //ブロックのY位置 if i>=15:bly.i=30 if i<15 & i>=10 :bly.i=60 if i<10 & i>=5 :bly.i=90 if i<5:bly.i=120 next screen 0,winx,winy,0//画面作成 pos 90,200:color 0,0,0:mes"Click to start!"//スタート画面 *start stick st//入力設定 if st=256:goto *main//マウスの左クリックでメイン処理へ await//ウェイト goto *start//戻る *main title"Block score:"+sc//タイトルとスコア表示 redraw 0//画面を描画しない color 255,255,255:boxf 0,0,winx,winy//白で画面全体を塗り潰す //クリア判定 cl=0//クリア判定用変数 for i,0,20 cl+=blf.i//ブロックのフラグを全て足す next if cl=0:pos 100,200:color 0,0,0:mes"Game Clear!!":redraw 1:await 2000:goto *init//クリア処理 //ブロックの表示 for i,0,20 if blf.i=1:color 0,0,255:boxf blx.i,bly.i,blx.i+blx_size.i,bly.i+bly_size.i//ブロックのフラグが立っていれば表示 next //ブロックとボールの当たり判定 for i,0,20 if blf.i=0:_continue//ブロックがない場合は次のブロックの判定を行う if(y+size=bly.i) & (x>=blx.i-size & x<=blx.i+blx_size.i+size):blf.i=0:dy=-dy:sc+=100:_break//ボールが上から当たった場合 if(bly.i+bly_size.i=y) & (x>=blx.i-size & x<=blx.i+blx_size.i+size):blf.i=0:dy=-dy:sc+=100:_break//ボールが下から当たった場合 if(y>=bly.i-size & y<=bly.i+bly_size.i+size) & (x+size=blx.i):blf.i=0:dy=-dy:sc+=100:_break//ボールが左から当たった場合 if(y>=bly.i-size & y<=bly.i+bly_size.i+size) & (x=blx.i+blx_size.i):blf.i=0:dy=-dy:sc+=100:_break//ボールが右から当たった場合 next color 0,0,0:circle x,y,x+size,y+size//黒でボールを描く x+=dx//ボールのX座標に移動速度を足す y+=dy//ボールのY座標に移動速度を足す if x<0 or x+size>winx:dx=-dx//ボールが左右の端に行ったらボール速度を反転(逆方向) if y<0 or y+size>winy:dy=-dy//ボールが上下の端に行ったらボール速度を反転(逆方向) if x>=px-p_size-size & x<=px+p_size+size & y+size=py:dy=-dy//ボールがパドルに当たったらボール速度を反転(逆方向) if y=480-size:pos 120,200:color 0,0,0:mes"Game Over":redraw 1:await 1000:goto *init//ゲームオーバー処理 px=mousex:color 255,0,0:boxf px-p_size,py,px+p_size,py+8//パドルを表示 await 2//ウェイト redraw 1//画面を描画する goto *main//戻る


HSP参考書色々


メインページへ戻る


コンタクト


掲示板

メール

リンク用バナー

バナー
バナー