;=========================================================== ; 2008/08/24 ; 蟲 0.9 ; GAM-22 ;=========================================================== /*---------------------------------------------------------- ; log ;----------------------------------------------------------- [0.1] 蟲がマウスに集まる [0.2] 配色変更、仲間同士で距離を保つように [0.3] 脚の追加 [0.4] 蟲の変数管理を、var(個体, 長さ)→ var(節) に変更 クリックで蟲回避、右クリックで蟲ランダム破壊 r) 蟲の間接破壊を想定 m) AXsize マイナス、2次元配列の Error7 から解放 d) 処理速度が低下(重大) [0.5] ドラックで描ける線分で、蟲を切断する処理を実装 蟲の長さにより、判定の大きさを変化 起動時、蟲の長さ(10or20)をランダムに決定 [0.6] 蟲がレザーに触れたときの効果 [0.7] 血しぶきを再現(廃止するかもしれません) 蟲のグラデーションをランダムに調整 [0.8] 蟲を全てバラバラにするゲームに HSPTVランキングに対応 [0.9] ルール変更、制限時間内で頑張るゲームに ;----------------------------------------------------------- ; パラメータ省略 ;----------------------------------------------------------- 0. color 22,0,0 → color 22 : -4byte 0. color 222,0,22 → color 22,,22 : -0byte 1. color 0,0,0 → color 2. var(2,0) → var(2) 3. redraw 1 → redraw ;----------------------------------------------------------- ; 数学系メモ ;----------------------------------------------------------- 1. 内積 = ax*bx + ay*by 2. ベクトル(x,y)の法線 = (-y,x) ;----------------------------------------------------------- ; その他 ;----------------------------------------------------------- 1. 人に見せるようなレベルじゃないことは自覚しています 2. コメントの「;」と「//」の使い分けが微妙です ;---------------------------------------------------------*/ ;----------------------------------------------------------- ; HSPTV ;----------------------------------------------------------- #runtime "hsptv" #regcmd 18 #cmd hsptv_send $00 ;----------------------------------------------------------- ; 定数 ;----------------------------------------------------------- ; ファイル名 #packopt name "worms" ; 画像バッファ #const buf_win 1 ; 円周率 (無駄に桁が多い) π = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 ; 円周率/2 πh = 1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017412671058534 ; 1° #define ° 0.01745329251994329576923690768488612713442871888541725456097191440171009114603449443682241569634509482 ; debug mode #define debug 0 ; screen shot #define ss 0 ; key code #const esc 128 #const click 256 #const right 512 ; 非トリガーキー #const non_trigger click ;----------------------------------------------------------- ; 起動 ;----------------------------------------------------------- // 乱数初期化 randomize // rank notesel rank // comment comment = "comments please" mode ++ goto *reset *send // スコア送信 hsptv_send rank, score, comment mode -- *reset ;----------------------------------------------------------- ; 部品描画 ;----------------------------------------------------------- buffer buf_win color : boxf ;------------------------------------------------------- ; Aパーツ(体) ;------------------------------------------------------- // 形状生成 color 48,48,48 circle 65,3, 76,32 circle 84,3, 95,32 circle 64,0, 96,30 // グラデーション加工 repeat 16 gmode 5, 32,32, cnt*cnt+20 pos 16+cnt/4, 16+cnt/4 grotate buf_win, 64,0, 0, 32-0.5*cnt*(rnd(7)+2),32-cnt loop // ダメージ用 color 255 circle 32,0, 63,31 gsel 0 : clrobj ;----------------------------------------------------------- ; rank ;----------------------------------------------------------- hsptv_send rank, -1 ;----------------------------------------------------------- ; 初期化 ;----------------------------------------------------------- ; 蟲のリミット i_max_limit = 280 /mode // 蟲の種類 (長さ変えてるだけ) ; 普通 i_base_len = 10 i_draw_h = 1 if rnd(2) { ; ムカデ i_base_len = 20 i_draw_h = 10 } dim bld_max dim i_max dim score dim mcnt *main ;----------------------------------------------------------- ; main start ;----------------------------------------------------------- // stick key_log = key stick key, non_trigger f = mcnt\2 // draw start redraw 0 // background color : boxf ;----------------------------------------------------------- ; レーザー、判定 ;----------------------------------------------------------- ; レーザーの法線 v1 = laser_y -mousey v2 = -laser_x +mousex ; 正規化 v3 = sqrt(v1*v1 + v2*v2) if v3>0 : v3 = 1.0/v3 v1 *= v3 v2 *= v3 repeat (i_max-1) *(i_max>=1), 1 i_dam(cnt) = 0 ; 蟲を線分に bx1 = i_x(cnt-1 +i_type(cnt)) by1 = i_y(cnt-1 +i_type(cnt)) bx2 = i_x(cnt) by2 = i_y(cnt) #if debug color 255 line bx1,by1, bx2,by2 #endif ; 以下、説明不可 if (v1*(bx2-bx1) + v2*(by2-by1))!0 { v4 = -(v1*bx1 + v2*by1 - (laser_x*v1 + laser_y*v2)) / (v1*(bx2-bx1) + v2*(by2-by1)) if v4>0 & v4<=1 { x = bx1+(bx2-bx1)*v4 y = by1+(by2-by1)*v4 if (laser_x-x)*(mousex-x)+(laser_y-y)*(mousey-y) < 0 { if key_log&click { if key&click:else{ ; スコア換算 if bld_max { point.bld_max = limit(100-mcnt+bld_cnt(bld_max-1),0,$7FFFFFFF) if point(bld_max)>=100 : point.bld_max = 333 score += point(bld_max)*playing } ; 切断!! i_type.cnt = 1 ; 血しぶき bld_t.bld_max = cnt bld_cnt.bld_max = mcnt bld_max++ } i_dam(cnt) += f } } } } loop ;----------------------------------------------------------- ; 蟲、AI ;----------------------------------------------------------- // 蟲ループ開始 repeat i_max rcnt = cnt if i_type.rcnt { ;------------------------------------------------------- ; 頭 ;------------------------------------------------------- // 長さ計測 repeat , rcnt+((rcnt+2)<=i_max) if i_type(cnt) | (cnt+1)>=i_max { i_len.rcnt = cnt-rcnt break } loop // ターゲット(マウス)接近、クリック時回避 i_target.cnt = atan(i_y(cnt)-mousey, i_x(cnt)-mousex) -πh +π*((key&click)!0) v1 = i_len(cnt)*4 #if debug circle i_x(cnt)-v1,i_y(cnt)-v1, i_x(cnt)+v1,i_y(cnt)+v1, 0 #endif repeat i_max // 仲間から回避 if rcnt!cnt & i_type.cnt { x = i_x(cnt+i_len(cnt)/2) -i_x(rcnt) y = i_y(cnt+i_len(cnt)/2) -i_y(rcnt) if (x*x+y*y) <= v1*v1 { i_target.rcnt = atan(y,x) -πh } } loop #if debug line i_x(rcnt),i_y(rcnt), i_x(rcnt)+cos(i_target(rcnt)-πh)*50, i_y(rcnt)+sin(i_target(rcnt)-πh)*50 #endif // 目標追従 if cos(i_r.cnt)*cos(i_target.cnt)+sin(i_r.cnt)*sin(i_target.cnt) <= 0.5 {; 蛇行タイミング (ターゲットから一定の角度がある場合) i_snake.cnt = -0.05 + 0.1*(-sin(i_r.cnt)*cos(i_target.cnt) + cos(i_r.cnt)*sin(i_target.cnt)>=0); 蛇行方向 (内積を利用) } // 頭移動 i_r.cnt += i_snake.cnt i_x.cnt += 1.75 *cos(i_r(cnt)-πh) *(i_len(cnt)>=2) i_y.cnt += 1.75 *sin(i_r(cnt)-πh) *(i_len(cnt)>=2) } else { ;------------------------------------------------------- ; 体 ;------------------------------------------------------- // 体移動(っていうか引っ張る) i_r.cnt = atan( i_y(cnt)-i_y(cnt-1), i_x(cnt)-i_x(cnt-1) ) -πh i_x.cnt = i_x(cnt-1) + cos(i_r(cnt)+πh)*8 i_y.cnt = i_y(cnt-1) + sin(i_r(cnt)+πh)*8 } ;----------------------------------------------------------- ; 描画 ;----------------------------------------------------------- // 蟲 x = i_x.cnt y = i_y.cnt r = i_r.cnt ; 脚 v1 = r +sin (πh *(mcnt+cnt)/5) /2 v2 = 9 +(0.15/i_draw_h)*i_w(cnt) color 200,200,200 line x,y, x+cos(v1)*v2, y+sin(v1)*v2 color 128,128,128 line x,y, x+cos(v1+π)*v2, y+sin(v1+π)*v2 ; 体 gmode 2, 32,32 pos x,y grotate buf_win, 32*i_dam(cnt),0, r, 17 +(0.2/i_draw_h)*i_w(cnt),9 // 蟲ループ終了 loop // 血しぶき repeat bld_max v1 = bld_t(cnt) v2 = mcnt-bld_cnt(cnt) // point if v2<=10 { color limit(point(cnt)-v2*4,10,255) pos i_x(v1)+10,i_y(v1)+10 mes "+"+point(cnt) } repeat v2*(v2<=26), 8 v3 = °*rnd(180) +i_r(v1) pos i_x(v1)-cos(v3)*cnt, i_y(v1)-sin(v3)*cnt gmode 4, 32,32, 222-v2*v2/5 grotate buf_win, 32,0, v3, 5-cnt/8, 2 loop loop // レーザー if key&click { if key_log&click:else { // 始点 laser_x = double.mousex laser_y = double.mousey } // 描画 hsvcolor mcnt\192,200,255; カラフル♪ if f : line laser_x,laser_y, mousex,mousey } ;----------------------------------------------------------- ; 仕上げ ;----------------------------------------------------------- gmode 5, 1,1, 80 color 222,222,222 command = "\n" if mode=2 { ;--------------------------------------------------- ; 本番 ;--------------------------------------------------- if playing:else { pos 320, 240 : grotate buf_win, 78,2, 0, 400,150 pos 188,200 : mes "time over..." } if (time=0)*playing { ; タイムオーバー dim playing pos 188,228 : input comment, 200,24, 16 pos 388,228 : button "send", *send } time -= playing } else { if mode { ;------------------------------------------------------- ; タイトル ;------------------------------------------------------- if key&click { dim mode playing = 1 } if key&right { ; スタート mode = 2 playing = 1 time = 2222 goto *reset } if f : command = "[click]練習\n[right]本番" // 蟲 font "MS 明朝", 75 pos 270,50 : mes "蟲" // ランキング pos 320,300 : grotate buf_win, 78,2, 0, 550,222 font "", 15 repeat 30, ((mcnt/100)\3)*30 noteget v1, cnt y = ((cnt/3)\10)*20+200 if cnt\3:else{ pos 80,y : mes "no."+((cnt/3)+1) v1 += "pt" } pos (cnt\3)*100+150,y : mes v1 loop } else { ;--------------------------------------------------- ; 練習 ;--------------------------------------------------- if f : command += "[↑/↓]増減" // 蟲の数の調整 if (key&8)*i_max { ; 減らす (消す) i_max_limit -= i_base_len i_max -= i_base_len } if key&2 { ; 増やす i_max_limit += i_base_len } } } if key&esc { ; リセット (画像も作り直し) mode = 1 goto *reset } // 得点 pos 10,4 : mes "score: "+score+"pt\ntime: "+time+"\nbeing: "+i_max // コマンド pos 560,427 : mes command +"\n[esc]title" ;----------------------------------------------------------- ; main - end ;----------------------------------------------------------- // draw end redraw // screen shot #if ss if key&16 : bmpsave "ss_"+gettime(0)+"."+gettime(1)+"."+gettime(3)+"_"+gettime(4)+"."+gettime(5)+".bmp" #endif // wait await 30 // mcnt mcnt++ if (mcnt\20) | (i_max >= i_max_limit): else {; (mcnt\20)=0 & (i_max < i_max_limit) { (2byteしか削れない) // 蟲生成 repeat i_base_len i_type.i_max = (i_max\i_base_len)=0 i_len(i_max)++ i_snake.i_max = πh i_target.i_max = πh i_w.i_max = (3-cnt)*(cnt-4) i_x.i_max = πh*rnd(408) i_y.i_max = 640.0*rnd(2) -80 i_r.i_max = πh i_max++ loop } // loop goto *main