HSP3 ゲームのプログラミング
 ラケット・ゲーム制作 目次へ 次へ 

ラケット・ゲーム制作

(1) 計画

 基本的には、ウィンドウ内を動くボールをラケットで打ち返すゲームである。ここでは、ゲームのルールや画面構成などを考える。

・ウィンドウサイズは640×480とする。
 
ゲーム領域
・8ドット単位で幅60(60×8=480ドット)とする。
・ボールサイズは2×2、ラケットは4×1とする。
・一度打ち返すと10ポイントとする。
情報領域
・幅は640-480=160
 これを基本形として、制作しながら追加していくことにする。
 画像は次のようなものを用意する。
ダウンロード racket1.bmp (30KB)


(2) 基本部分作成

 ゲーム領域を設定して、ラケットでボールを打ち返すことができるようなプログラムを作成する。

サンプル
 課題move97.hspを元に考えていくことにする。次のプログラムはmove97.hspである。
 redraw 1を(*5)のgcopyの次行に移動している。このgcopyの後には描画命令がないためである。

    buffer 1                ;ウィンドウID 1番
    picload "move3.bmp"     ;(*1) 画像ファイル読み込み
    screen 0                ;ウィンドウID 0番
    gmode 2, 32, 32    ;(*1) コピーモード設定
    mm = 8             ;間隔
*start
    x0 = 12 : y0 = 12           ;(*3) キャラクタの座標
    dx0 = 1 : dy0 = 1           ;キャラクタの移動量
    x1 = 12 : y1 = 55           ;バーの座標
    dx1 = 2 : dy1 = 0           ;バーの移動量
    repeat
        redraw 0            ;仮描画
        color 255, 255, 255         ;(*4) 白色。背景と同じ色。
        boxf            ;(*4) ウィンドウと同じサイズの四角形を塗りつぶしで描画する。
        color 0, 0, 0           ;(*4) 黒色
        pos x0 * mm, y0 * mm    ;カレントポジション設定
        gcopy 1, 0, 0           ;画像コピー
        pos x1 * mm, y1 * mm    ;カレントポジション設定
        gcopy 1, 64, 0, 32, 8   ;(*5) 画像コピー
        redraw 1        ;実描画
        if abs(x0 - x1) <= 2 & y0 + 3 = y1 : dy0 = -dy0         ;(*6) 衝突判定
        x0 = x0 + dx0       ;x座標加算
        y0 = y0 + dy0       ;y座標加算
        if x0 > (ginfo_winx - 32) / mm : dx0 = -dx0     ;(*7) 右壁衝突
        if x0 <= 0 : dx0 = -dx0                         ;(*7) 左壁衝突
        if y0 > (ginfo_winy - 32) / mm : break          ;(*7) 下壁衝突
        if y0 <= 0 : dy0 = -dy0                         ;(*7) 上壁衝突
        stick key, 15           ;キー入力
        if key & 1 : x1 = x1 - dx1          ;左
        if key & 4 : x1 = x1 + dx1          ;右
        if key & 128 : end                  ;[Esc]
        x1 = limit(x1, 0, (ginfo_winx - 32) / mm)    ;(*8)
        await 100       ;無限ループの時のお約束
    loop
    dialog "もう一度しますか。", 2
    if stat = 6 : goto *start
    end

(*1) 画像(ボール)ファイルと画像サイズを2×2(16×16ドット)に変更する。

picload "move3.bmp"   ;画像ファイル読み込み → picload "racket1.bmp"    ;画像ファイル読み込み
gmode 2, 32, 32    ;コピーモード設定 → gmode 2, 16, 16    ;コピーモード設定

(*2) 乱数を使用するので乱数の初期化命令randomizeを追加する。また、ゲーム領域のサイズを変数winx, winyに格納しておく。それぞれ、ラベル*startの直前に挿入する。

winx = 60 : winy = 60    ;ゲーム領域のサイズ
randomize    ;乱数初期化

(*3) ボールの出現位置を乱数で決定する。

x0 = 12 : y0 = 12    ;キャラクタの座標 → x0 = rnd(winx - 2) : y0 = 2    ;ボールの初期座標

(*4) ゲーム領域を緑色で消去するように変更する。

color 255, 255, 255    ;白色。背景と同じ色。 → color 0, 128, 0    ;緑色
boxf ;ウィンドウと…を塗りつぶしで描画する。 → boxf 0, 0, winx * mm - 1, winy * mm    ;ゲーム領域消去
color 0, 0, 0 ;黒色 → 削除

(*5) バー(ラケット)の描画パラメータを変更する。

gcopy 1, 64, 0, 32, 8    ;画像コピー → gcopy 1, 16, 0, 32, 8    ;ボール描画

(*6) ボールとバーの衝突判定を変更する。

 まず、xの範囲は図のように、x1-1 ≦ x0 ≦ x1+3 となる。
   x0≧x1-1 → x0-x1≧-1 → x0-x1-1≧-1-1 → x0 - x1 - 1 ≧ -2
   x0≦x1+3 → x0-x1≦3  →  x0-x1-1≦3-1 → x0 - x1 - 1 ≦ 2
 判定の式は次のようになる。
   abs(x0 - x1 - 1) <= 2
 次に、yの判定はy0+2とy1が一致したとき衝突したと判定する。判定の式は次のようになる。
   y0 + 2 = y1
 x, y両方の条件を満たしたときに衝突したと判定する。条件式は次のようになる。

if abs(x0 - x1) <= 2 & y0 + 3 = y1 : dy0 = -dy0        ;衝突判定
    ↓
if abs(x0 - x1 - 1) <= 2 & y0 + 2 = y1 : dy0 = -dy0        ;衝突判定

(*7) ボールと壁(ウィンドウ枠)の衝突判定を変更する。

if x0 >= (ginfo_winx - 32) / mm : dx0 = -dx0  ;右壁に衝突。 → if x0 >= winx - 2 : dx0 = -dx0    ;右壁衝突
if x0 <= 0 : dx0 = -dx0                       ;左壁に衝突。 → 変更なし
if y0 >= (ginfo_winy - 32) / mm : break       ;下壁に衝突。 → if y0 >= winy : break     ;下壁衝突
if y0 <= 0 : dy0 = -dy0                       ;上壁に衝突。 → 変更なし

(*8) バーが壁(ウィンドウ枠)を超えないための制限式を変更する。

x1 = limit(x1, 0, (ginfo_winx - 32) / mm) → x1 = limit(x1, 0, winx - 4)



課題(racket91.hsp)
 変更点*1〜*8について修正せよ。


(リスト)新しいウィンドウで開く


 ラケット・ゲーム制作 目次へ 次へ 
2007 © Hiroshi Masuda

 

 

inserted by FC2 system