; ; HSP キャラクタ表示サンプル5 ; ( HSP ver2.2e以上で動作します ) ; randomize ; 乱数を不定にする wx=640:wy=384 ; ウインドゥのサイズ screen 0,wx,wy,1 ; Windowをパレットモードで初期化 buffer 3,,,1 ; 仮想画面をパレットモードで初期化 picload "testchr.bmp" ; 仮想画面にキャラクタデータをロード chrsx=64:chrsy=64 ; キャラクタのサイズを指定 chrx=0:chry=64 ; キャラクタのデータがある左上の座標 ; ; 複数をキャラクタを動かす(背景付きスクロール) ; ; sprite4.asをさらに改造して自分とリンゴとの当たり判定をつけ、得点が ; 加算されるようにしました。自分(首)が、リンゴに当たるとマイナス4点、 ; 通常は1点づつ加算されていく簡単なゲームの形式になっています。 ; 当たり判定は、XとY座標を比較して自分が表示されているエリアと、 ; リンゴが表示されているエリアが重なっているかどうかで判定しています。 ; 表示されているサイズが64×64ドットなので、左上の座標から64×64の範囲 ; に、比較対象のキャラクタが入っているかどうかをif命令で比較します。 ; ; score=0 ; スコアを0に設定 rollx=0 ; X方向スクロールカウンター myf=1 ; 自分のキャラクター状態フラグ myx=80:myy=180 ; 自分のキャラクター初期位置X,Y ; ; マップデータの初期設定 ; mapx=10:mapy=6 ; マップのX,Yサイズ alloc map,1000 ; マップデータの領域を確保 map = "3330000000" ; Y=0のマップデータ map += "3000000000" ; Y=1のマップデータ map += "3004440000" ; Y=2のマップデータ map += "0000000000" ; Y=3のマップデータ map += "1000000011" ; Y=4のマップデータ map += "1100001111" ; Y=5のマップデータ buffer 4,wx,wy,1 ; ID4に仮想画面を作成 palcopy 3 ; ID3のパレットをコピーしてくる gosub *map_draw ; 背景マップを作成 ; ; 配列変数への初期設定 ; kazu=12 ; 同時に表示するキャラクタの数 dim x,kazu ; キャラクタの数だけ変数xの配列変数を確保 dim y,kazu ; キャラクタの数だけ変数yの配列変数を確保 dim px,kazu ; キャラクタの数だけ変数pxの配列変数を確保 ax=0:ay=0:apx=0 ; dup命令で使用する変数を宣言(ダミー) repeat kazu ; キャラクタの数だけループさせる dup ax,x.cnt ; 変数axをx.cntの代用にする dup ay,y.cnt ; 変数ayをy.cntの代用にする dup apx,px.cnt ; 変数apxをpx.cntの代用にする rnd ax,50:ax=ax*10+50 ; X座標を乱数で設定する rnd ay,30:ay=ay*9+20 ; Y座標を乱数で設定する rnd apx,4:apx++ ; 動くドット数を乱数で設定する loop ; ループ終了 *chrmove ; メインループ ; gsel 0 ; 描画先をID0に redraw 2 ; 書き換えスイッチOFF a=640-rollx ; 左半分のサイズを計算 gmode 1,a,wy ; 左半分の画面サイズを指定 pos 0,0:gcopy 4,rollx,0 ; ID4から画面をコピー if rollx=0 : goto *nosplit ; 右半分がなければ次へ gmode 1,rollx,wy ; 右半分の画面サイズを指定 pos a,0:gcopy 4,0,0 ; ID4から画面をコピー *nosplit rollx+:if rollx=640 : rollx=0 ; スクロールカウンターが一周したら0に戻す myf=1 ; 自分の状態フラグをリセット myxe=myx+chrsx ; 自分の右下X座標を計算 myye=myy+chrsy ; 自分の右下Y座標を計算 repeat kazu ; キャラクタの数だけループさせる dup ax,x.cnt ; 変数axをx.cntの代用にする dup ay,y.cnt ; 変数ayをy.cntの代用にする dup apx,px.cnt ; 変数apxをpx.cntの代用にする ax-=apx ; X座標を変数apxのぶんだけ左に動かす if ax<=0 : ax=580 ; X座標が左端まできていたら、580に戻す pos ax,ay ; カレントポジションを変数ax,ayの場所に設定 a=0:gosub *chr_draw ; 重ねあわせキャラ表示 axe=ax+chrsx ; リンゴの右下X座標を計算 if axe<myx : goto *nohit ; リンゴが自分より左にあるか? if ax>=myxe : goto *nohit ; リンゴが自分より右にあるか? aye=ay+chrsy ; リンゴの右下Y座標を計算 if aye<myy : goto *nohit ; リンゴが自分より上にあるか? if ay>=myye : goto *nohit ; リンゴが自分より下にあるか? myf=2 ; 衝突しているフラグをセットする *nohit loop ; ループ終了 gosub *keychk ; キー入力チェック pos myx,myy ; カレントポジションをmyx,myyの場所に設定 a=myf:gosub *chr_draw ; 重ねあわせキャラ表示 if myf=1 : score+ : else : score-=4 ; 自分の状態に応じてスコアを加算 color 255,255,255 ; 文字の色を白に設定 pos 0,0:mes "score "+score ; スコアを表示 redraw 1 ; 最後に書き換えスイッチON await 20 ; 必ずウエイトを入れる goto *chrmove ; 無限にループさせる *keychk ; カーソルキー入力で自分(変数myx,myy)を動かすサブルーチン ; (カーソルキーを同時に押すことにより斜めにも移動できます) ; stick a,15 ; カーソルキーの情報を取得 if a&2 : goto *go_up ; 上を押しているか? if a&8 : goto *go_down ; 下を押しているか? goto *keychk2 ; 左右のチェックにジャンプ *go_up if myy>=8 : myy-=8 goto *keychk2 *go_down if myy<316 : myy+=8 *keychk2 if a&1 : goto *go_left ; 左を押しているか? if a&4 : goto *go_right ; 右を押しているか? return *go_left if myx>=8 : myx-=8 return *go_right if myx<580 : myx+=8 return *map_draw ; マップ描画ルーチン ; a=0 gmode 1,chrsx,chrsy ; 高速モードでコピー指定 yy=0:i=0 ; 画面左上から順番に描画する repeat mapy xx=0 repeat mapx peek a,map,i:i+ ; マップデータ読み出し pos xx,yy ; 変数xx,yyが描画先の座標になる a-='0' ; 1桁数字の文字を0〜9の数値に変換 gcopy 3,a*chrsx,0 ; チップをコピー xx+=chrsx ; 1つ右にずらす loop yy+=chrsy ; 1つ下にずらす loop return *chr_draw ; 重ねあわせキャラクタ描画ルーチン ; ( カレントポジションに変数aのキャラNo.を表示する) ; gmode 2,chrsx,chrsy ; 重ねあわせモードとコピーサイズの設定 gcopy 3,a*chrsx+chrx,chry ; 重ねあわせコピーを実行 return ; サブルーチン終了 back