HSP3 ゲームのプログラミング | |
プログラミング例(カブ・ゲーム) |
リンクをクリックするとリストが表示される。
課題 (card61.hsp)
シャッフルの結果を画像で表示する。
;card61.hsp dim card, 40 ;カード用 randomize buffer 1 picload "card1.bmp" screen 0 gmode 0, 40, 55 gosub *shuffle ;カードシャッフル ;結果表示 repeat 40 x0 = card(cnt) \ 13 * 40 ;カードの位置計算 y0 = card(cnt) / 13 * 55 pos (cnt \ 10) * 40, cnt / 10 * 50 ;画像描画位置 gcopy 1, x0, y0 ;画像コピー loop stop ;カードシャッフル ----- *shuffle ;配列初期化 card(0) = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 card(20) = 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48 ;シャッフル repeat 200 ;200回 r1 = rnd(40) r2 = rnd(40) wk = card(r1) card(r1) = card(r2) card(r2) = wk loop return
課題 (card62.hsp)
カードの置き場所の座標を設定して、その置き場所に四角形を描画する。
;card62.hsp #define gf_clear color 0, 100, 0 : boxf 0, 0, 639, 369 ;ゲーム領域消去 #define mes_clear color 0, 100, 0 : boxf 0, 370, 639, 479 ;メッセージ領域消去 dim card, 40 ;カードの山用 dim ptx, 19 : dim pty, 19 ;カード置き場所座標 dim crd, 19 ;配布カードの通番格納用 randomize buffer 1 picload "card1.bmp" ;ウィンドウID1番に画像読み込み screen 0 gmode 0, 40, 55 ;コピーモード0。カード1枚のサイズ40×55ドット title "カブ・ゲーム" ;カード置き場所計算 repeat 15 ptx(cnt) = 70 + cnt \ 3 * 20 + cnt / 3 * 100 pty(cnt) = 250 + cnt \ 3 * 25 loop repeat 3, 15 ;3回繰り返す。cntの初期値を15にする。 ptx(cnt) = 250 + cnt \ 3 * 50 pty(cnt) = 50 loop ptx(18) = 50 : pty(18) = 50 gf_clear ;ゲーム領域消去 gosub *gf_disp ;ゲーム領域描画 mes_clear ;メッセージ領域消去 stop ;----- サブルーチン ----- ;ゲーム領域描画 ----- *gf_disp ;カード置き場所描画 color 0, 120, 0 foreach ptx boxf ptx(cnt), pty(cnt), ptx(cnt) + 40, pty(cnt) + 55 loop return ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card63.hsp)
1枚目のカード配布の処理を追加する。また、カードの山の置き場にカード裏面の画像も表示する。
;card63.hsp << 省略 >> gmode 0, 40, 55 ;コピーモード0。カード1枚のサイズ40×55ドット font "MS ゴシック", 18, 1 title "カブ・ゲーム" ;カード置き場所計算 repeat 15 ptx(cnt) = 70 + cnt \ 3 * 20 + cnt / 3 * 100 pty(cnt) = 250 + cnt \ 3 * 25 loop repeat 3, 15 ;3回繰り返す。cntの初期値を15にする。 ptx(cnt) = 250 + cnt \ 3 * 50 pty(cnt) = 50 loop ptx(18) = 50 : pty(18) = 50 foreach crd crd(cnt) = -1 ;配布カード初期化 loop cnum = 0 ;取り出すカード番号(インデックス) gf_clear ;ゲーム領域消去 gosub *gf_disp ;ゲーム領域描画 mes_clear ;メッセージ領域消去 gosub *shuffle ;カードシャッフル ;1枚目配布 color 0, 0, 0 : pos 20, 450 : mes "カード配布中です。" repeat 6 ;6枚分 crd(cnt * 3) = card(cnum) ;カード配布 cnum = cnum + 1 ;インデックス加算 loop gosub *gf_disp ;ゲーム領域描画 stop ;----- サブルーチン ----- ;ゲーム領域描画 ----- *gf_disp ;カード置き場所描画 color 0, 120, 0 foreach ptx boxf ptx(cnt), pty(cnt), ptx(cnt) + 40, pty(cnt) + 55 loop ;配布カード描画 foreach crd if crd(cnt) ! -1 { pos ptx(cnt), pty(cnt) gcopy 1, crd(cnt) \ 13 * 40, crd(cnt) / 13 * 55 } loop ;カードの山(カードの裏)描画 pos ptx(18), pty(18) gcopy 1, 80, 220 return ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card64.hsp)
カード移動のアニメーションの処理を追加する。
;card64.hsp << 省略 >> ;1枚目配布 color 0, 0, 0 : pos 20, 450 : mes "カード配布中です。" repeat 6 ;6枚分 nn = cnt * 3 ;置き場所計算 gosub *card_move ;カード移動アニメーション crd(nn) = card(cnum) ;カード配布 cnum = cnum + 1 ;インデックス加算 loop gosub *gf_disp ;ゲーム領域描画 stop ;----- サブルーチン ----- ;カード移動アニメーション ----- *card_move kaisu = 10 ;分割数 dx = abs(ptx(nn) - ptx(18)) / kaisu ;移動量計算 dy = abs(pty(nn) - pty(18)) / kaisu repeat kaisu, 1 redraw 0 gosub *gf_disp ;ゲーム領域描画 pos ptx(18) + dx * cnt, pty(18) + dy * cnt ;座標設定 gcopy 1, 80, 220 ;画像コピー redraw 1 wait 5 ;時間待ち loop return ;ゲーム領域描画 ----- *gf_disp gf_clear ;ゲーム領域消去 ;カード置き場所描画 color 0, 120, 0 foreach ptx boxf ptx(cnt), pty(cnt), ptx(cnt) + 40, pty(cnt) + 55 loop ;配布カード描画 foreach crd if crd(cnt) ! -1 { pos ptx(cnt), pty(cnt) gcopy 1, crd(cnt) \ 13 * 40, crd(cnt) / 13 * 55 } loop ;カードの山(カードの裏)描画 pos ptx(18), pty(18) gcopy 1, 80, 220 return ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card65.hsp)
カード選択の処理を追加する。
;card65.hsp << 省略 >> ;1枚目配布 pos 20, 450 : mes "カード配布中です。" repeat 6 ;6枚分 nn = cnt * 3 ;置き場所計算 gosub *card_move ;カード移動アニメーション crd(nn) = card(cnum) ;カード配布 cnum = cnum + 1 ;インデックス加算 loop gosub *gf_disp ;ゲーム領域描画 ;カード選択 *selcard selc = -1 ;選択カード番号0-4 mes_clear ;メッセージ領域消去 pos 20, 450 : mes "カードをクリックして選択してください。" *selcard1 repeat ;永久ループ stick kk ;キー入力 if kk = 256 : break ;左クリック await 100 loop repeat 5 ;カード(0),B,E,H,Kチェック if abs(ptx(cnt * 3) + 20 - mousex) <= 20 & abs(pty(cnt * 3) + 28 - mousey) <= 28 { selc = cnt ;選択カード番号格納 break } loop if selc = -1 : goto *selcard1 ;カード以外の場所をクリックした dialog selc : goto *selcard stop ;----- サブルーチン ----- ;カード移動アニメーション ----- *card_move << 省略 >> ;ゲーム領域描画 ----- *gf_disp << 省略 >> ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card66.hsp)
賭点入力の処理を追加する。
;card66.hsp << 省略 >> ptx(18) = 50 : pty(18) = 50 tokuten = 200 ;持ち点初期化 foreach crd crd(cnt) = -1 ;配布カード初期化 loop cnum = 0 ;取り出すカード番号(インデックス) << 省略 >> *selcard1 repeat ;永久ループ stick kk ;キー入力 if kk = 256 : break ;左クリック await 100 loop repeat 5 ;カード(0),B,E,H,Kチェック if abs(ptx(cnt * 3) + 20 - mousex) <= 20 & abs(pty(cnt * 3) + 28 - mousey) <= 28 { selc = cnt ;選択カード番号格納 break } loop if selc = -1 : goto *selcard1 ;カード以外の場所をクリックした ;dialog selc : goto *selcard ;賭点入力 pos ptx(selc * 3), pty(selc * 3) + 60 ;選択カードの下 input kake ;入力ボックス button "OK", *b_ok ;OKボタン button "Cancel", *b_cancel ;キャンセルボタン stop ;ボタンのクリックを待つ *b_cancel ;キャンセル時の処理 clrobj ;オブジェクト(入力ボックスとボタン)をすべて消去 goto *selcard *b_ok ;OK時の処理 clrobj ;オブジェクトをすべて消去 if kake > tokuten | kake <= 0 : goto *selcard ;賭点チェック mes_clear ;メッセージ領域消去 pos ptx(selc * 3), pty(selc * 3) + 120 mes "賭点=" + kake stop ;----- サブルーチン ----- ;カード移動アニメーション ----- *card_move << 省略 >> ;ゲーム領域描画 ----- *gf_disp << 省略 >> ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card67.hsp)
2,3枚目のカード配布の処理を追加する。
;card67.hsp << 省略 >> *b_ok ;OK時の処理 clrobj ;オブジェクトをすべて消去 if kake > tokuten | kake <= 0 : goto *selcard ;賭点チェック mes_clear ;メッセージ領域消去 pos ptx(selc * 3), pty(selc * 3) + 120 mes "賭点=" + kake ;2,3枚目配布 repeat 6 ;6人分 ;2枚目配布 nn = cnt * 3 + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;2枚目 cnum = cnum + 1 ;インデックス加算 gosub *gf_disp ;ゲーム領域描画 ;2枚の合計計算 gosub *get_yaku2 ;役計算(2枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 if selc = cnt { ;選択したカード dialog "もう一枚引きますか。", 2, "かぶ・ゲーム" if stat = 6 { ;3枚目引く ;3枚目配布 nn = nn + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;3枚目 cnum = cnum + 1 ;インデックス加算 ;3枚の合計計算 gosub *get_yaku3 ;役計算(3枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 } } else { ;未選択カードと親 if yaku(cnt) <= 5 | (yaku(cnt) <= 7 & rnd(10) < 5) { ;3枚目引くか判定 ;3枚目配布 nn = nn + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;3枚目 cnum = cnum + 1 ;インデックス加算 ;3枚の合計計算 gosub *get_yaku3 ;役計算(3枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 } } gosub *gf_disp ;ゲーム領域描画 ;合計点表示 if cnt = 5 { ;親 pos ptx(cnt * 3), pty(cnt * 3) + 60 } else { ;親以外 pos ptx(cnt * 3), pty(cnt * 3) + 140 } color 0, 0, 0 mes "合計=" + yaku(cnt) loop stop ;----- サブルーチン ----- ;役計算(2枚) ----- *get_yaku2 yakuten = ((crd(nn - 1) \ 13 + 1) + (crd(nn) \ 13 + 1)) \ 10 ;2枚の合計 if nn >= 15 { ;親 if (crd(nn - 1) \ 13 + 1) = 1 & (crd(nn) \ 13 + 1) = 9 : yakuten = 11 ;1と9の場合 if (crd(nn - 1) \ 13 + 1) = 9 & (crd(nn) \ 13 + 1) = 1 : yakuten = 11 } else { ;親以外 if (crd(nn - 1) \ 13 + 1) = 1 & (crd(nn) \ 13 + 1) = 4 : yakuten = 10 ;1と4の場合 if (crd(nn - 1) \ 13 + 1) = 4 & (crd(nn) \ 13 + 1) = 1 : yakuten = 10 } return ;役計算(3枚) ----- *get_yaku3 yakuten = ((crd(nn - 2) \ 13 + 1) + (crd(nn - 1) \ 13 + 1) + (crd(nn) \ 13 + 1)) \ 10 ;3枚の合計 return ;カード移動アニメーション ----- *card_move << 省略 >> ;ゲーム領域描画 ----- *gf_disp << 省略 >> ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card68.hsp)
勝敗判定と得点表示の処理を追加する。
;card68.hsp << 省略 >> ;合計点表示 if cnt = 5 { ;親 pos ptx(cnt * 3), pty(cnt * 3) + 60 } else { ;親以外 pos ptx(cnt * 3), pty(cnt * 3) + 140 } color 0, 0, 0 mes "合計=" + yaku(cnt) loop ;勝敗判定・勝敗結果表示 repeat 5 ;5人分 pos ptx(cnt * 3), pty(cnt * 3) + 160 ;勝敗表示座標 if selc = cnt { ;選択したカード if yaku(5) = yaku(cnt) : color 255, 0, 255 : mes "引き分け" if yaku(5) > yaku(cnt) : color 0, 0, 0 : mes "負け" : tokuten = tokuten - kake if yaku(5) < yaku(cnt) : color 255, 0, 0 : mes "勝ち" : tokuten = tokuten + kake } else { ;未選択カードと親 if yaku(5) = yaku(cnt) : color 255, 0, 255 : mes "引き分け" if yaku(5) > yaku(cnt) : color 0, 0, 0 : mes "負け" if yaku(5) < yaku(cnt) : color 255, 0, 0 : mes "勝ち" } loop gosub *gf_disp ;ゲーム領域描画 ;親合計点再表示 pos ptx(15), pty(15) + 60 color 0, 0, 0 : mes "合計=" + yaku(5) stop ;----- サブルーチン ----- ;役計算(2枚) ----- *get_yaku2 << 省略 >> ;役計算(3枚) ----- *get_yaku3 << 省略 >> ;カード移動アニメーション ----- *card_move << 省略 >> ;ゲーム領域描画 ----- *gf_disp gf_clear ;ゲーム領域消去 ;カード置き場所描画 color 0, 120, 0 foreach ptx boxf ptx(cnt), pty(cnt), ptx(cnt) + 40, pty(cnt) + 55 loop ;配布カード描画 foreach crd if crd(cnt) ! -1 { pos ptx(cnt), pty(cnt) gcopy 1, crd(cnt) \ 13 * 40, crd(cnt) / 13 * 55 } loop ;カードの山(カードの裏)描画 pos ptx(18), pty(18) gcopy 1, 80, 220 ;得点表示 pos 550, 180 color 0, 0, 0 : mes "持ち点" mes strf("%06d", tokuten) return ;カードシャッフル ----- *shuffle << 省略 >>
課題 (card69.hsp)
ゲーム繰り返しの処理を追加する。
;card69.hsp #define gf_clear color 0, 100, 0 : boxf 0, 0, 639, 369 ;ゲーム領域消去 #define mes_clear color 0, 100, 0 : boxf 0, 370, 639, 479 : color 0, 0, 0 ;メッセージ領域消去 dim card, 40 ;カードの山用 dim ptx, 19 : dim pty, 19 ;カード置き場所座標 dim crd, 19 ;配布カードの通番格納用 dim yaku, 6 ;役点(0-9,10(41),11(91)) randomize buffer 1 picload "card1.bmp" ;ウィンドウID1番に画像読み込み screen 0 gmode 0, 40, 55 ;コピーモード0。カード1枚のサイズ40×55ドット font "MS ゴシック", 18, 1 title "カブ・ゲーム" ;カード置き場所計算 repeat 15 ptx(cnt) = 70 + cnt \ 3 * 20 + cnt / 3 * 100 pty(cnt) = 250 + cnt \ 3 * 25 loop repeat 3, 15 ;3回繰り返す。cntの初期値を15にする。 ptx(cnt) = 250 + cnt \ 3 * 50 pty(cnt) = 50 loop ptx(18) = 50 : pty(18) = 50 tokuten = 200 ;持ち点初期化 *start foreach crd crd(cnt) = -1 ;配布カード初期化 loop cnum = 0 ;取り出すカード番号(インデックス) gf_clear ;ゲーム領域消去 gosub *gf_disp ;ゲーム領域描画 mes_clear ;メッセージ領域消去 gosub *shuffle ;カードシャッフル ;1枚目配布 pos 20, 450 : mes "カード配布中です。" repeat 6 ;6枚分 nn = cnt * 3 ;置き場所計算 gosub *card_move ;カード移動アニメーション crd(nn) = card(cnum) ;カード配布 cnum = cnum + 1 ;インデックス加算 loop gosub *gf_disp ;ゲーム領域描画 ;カード選択 *selcard selc = -1 ;選択カード番号0-4 mes_clear ;メッセージ領域消去 pos 20, 450 : mes "カードをクリックして選択してください。" *selcard1 repeat ;永久ループ stick kk ;キー入力 if kk = 256 : break ;左クリック await 100 loop repeat 5 ;カード(0),B,E,H,Kチェック if abs(ptx(cnt * 3) + 20 - mousex) <= 20 & abs(pty(cnt * 3) + 28 - mousey) <= 28 { selc = cnt ;選択カード番号格納 break } loop if selc = -1 : goto *selcard1 ;カード以外の場所をクリックした ;賭点入力 pos ptx(selc * 3), pty(selc * 3) + 60 ;選択カードの下 input kake ;入力ボックス button "OK", *b_ok ;OKボタン button "Cancel", *b_cancel ;キャンセルボタン stop ;ボタンのクリックを待つ *b_cancel ;キャンセル時の処理 clrobj ;オブジェクト(入力ボックスとボタン)をすべて消去 goto *selcard *b_ok ;OK時の処理 clrobj ;オブジェクトをすべて消去 if kake > tokuten | kake <= 0 : goto *selcard ;賭点チェック mes_clear ;メッセージ領域消去 pos ptx(selc * 3), pty(selc * 3) + 120 mes "賭点=" + kake ;2,3枚目配布 repeat 6 ;6人分 ;2枚目配布 nn = cnt * 3 + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;2枚目 cnum = cnum + 1 ;インデックス加算 gosub *gf_disp ;ゲーム領域描画 ;2枚の合計計算 gosub *get_yaku2 ;役計算(2枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 if selc = cnt { ;選択したカード dialog "もう一枚引きますか。", 2, "かぶ・ゲーム" if stat = 6 { ;3枚目引く ;3枚目配布 nn = nn + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;3枚目 cnum = cnum + 1 ;インデックス加算 ;3枚の合計計算 gosub *get_yaku3 ;役計算(3枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 } } else { ;未選択カードと親 if yaku(cnt) <= 5 | (yaku(cnt) <= 7 & rnd(10) < 5) { ;3枚目引くか判定 ;3枚目配布 nn = nn + 1 ;配布場所計算 gosub *card_move ;配布アニメーション crd(nn) = card(cnum) ;3枚目 cnum = cnum + 1 ;インデックス加算 ;3枚の合計計算 gosub *get_yaku3 ;役計算(3枚)→yakuten yaku(cnt) = yakuten ;役(合計点)格納 } } gosub *gf_disp ;ゲーム領域描画 ;合計点表示 if cnt = 5 { ;親 pos ptx(cnt * 3), pty(cnt * 3) + 60 } else { ;親以外 pos ptx(cnt * 3), pty(cnt * 3) + 140 } color 0, 0, 0 mes "合計=" + yaku(cnt) loop ;勝敗判定・勝敗結果表示 repeat 5 ;5人分 pos ptx(cnt * 3), pty(cnt * 3) + 160 ;勝敗表示座標 if selc = cnt { ;選択したカード if yaku(5) = yaku(cnt) : color 255, 0, 255 : mes "引き分け" if yaku(5) > yaku(cnt) : color 0, 0, 0 : mes "負け" : tokuten = tokuten - kake if yaku(5) < yaku(cnt) : color 255, 0, 0 : mes "勝ち" : tokuten = tokuten + kake } else { ;未選択カードと親 if yaku(5) = yaku(cnt) : color 255, 0, 255 : mes "引き分け" if yaku(5) > yaku(cnt) : color 0, 0, 0 : mes "負け" if yaku(5) < yaku(cnt) : color 255, 0, 0 : mes "勝ち" } loop gosub *gf_disp ;ゲーム領域描画 ;親合計点再表示 pos ptx(15), pty(15) + 60 color 0, 0, 0 : mes "合計=" + yaku(5) ;ゲーム再開確認 if tokuten = 0 { dialog "ゲーム・オーバーです。もう一度しますか。", 2, "かぶ・ゲーム" if stat = 6 :tokuten = 200 : goto *start } else { dialog "もう一度しますか。", 2, "かぶ・ゲーム" if stat = 6 :goto *start } end ;----- サブルーチン ----- ;役計算(2枚) ----- *get_yaku2 yakuten = ((crd(nn - 1) \ 13 + 1) + (crd(nn) \ 13 + 1)) \ 10 ;2枚の合計 if nn >= 15 { ;親 if (crd(nn - 1) \ 13 + 1) = 1 & (crd(nn) \ 13 + 1) = 9 : yakuten = 11 ;1と9の場合 if (crd(nn - 1) \ 13 + 1) = 9 & (crd(nn) \ 13 + 1) = 1 : yakuten = 11 } else { ;親以外 if (crd(nn - 1) \ 13 + 1) = 1 & (crd(nn) \ 13 + 1) = 4 : yakuten = 10 ;1と4の場合 if (crd(nn - 1) \ 13 + 1) = 4 & (crd(nn) \ 13 + 1) = 1 : yakuten = 10 } return ;役計算(3枚) ----- *get_yaku3 yakuten = ((crd(nn - 2) \ 13 + 1) + (crd(nn - 1) \ 13 + 1) + (crd(nn) \ 13 + 1)) \ 10 ;3枚の合計 return ;カード移動アニメーション ----- *card_move kaisu = 10 ;分割数 dx = abs(ptx(nn) - ptx(18)) / kaisu ;移動量計算 dy = abs(pty(nn) - pty(18)) / kaisu repeat kaisu, 1 redraw 0 gosub *gf_disp ;ゲーム領域描画 pos ptx(18) + dx * cnt, pty(18) + dy * cnt ;座標設定 gcopy 1, 80, 220 ;画像コピー redraw 1 wait 5 ;時間待ち loop return ;ゲーム領域描画 ----- *gf_disp gf_clear ;ゲーム領域消去 ;カード置き場所描画 color 0, 120, 0 foreach ptx boxf ptx(cnt), pty(cnt), ptx(cnt) + 40, pty(cnt) + 55 loop ;配布カード描画 foreach crd if crd(cnt) ! -1 { pos ptx(cnt), pty(cnt) gcopy 1, crd(cnt) \ 13 * 40, crd(cnt) / 13 * 55 } loop ;カードの山(カードの裏)描画 pos ptx(18), pty(18) gcopy 1, 80, 220 ;得点表示 pos 550, 180 color 0, 0, 0 : mes "持ち点" mes strf("%06d", tokuten) return ;カードシャッフル ----- *shuffle ;配列初期化 card(0) = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 card(20) = 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48 ;シャッフル repeat 200 ;200回 r1 = rnd(40) r2 = rnd(40) wk = card(r1) card(r1) = card(r2) card(r2) = wk loop return
プログラミング例 | |
2007 © Hiroshi Masuda |