;=========================================================== ; 2008/08/23 ; 蟲 0.7 ; 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. 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. コメントの「;」と「//」の使い分けが微妙です 3. 目的も無いですし、面白くないと思います 4. どうしたらリアルに近づけるのでしょうか? ;---------------------------------------------------------*/ ;----------------------------------------------------------- ; 定数 ;----------------------------------------------------------- ; ファイル名 #packopt name "worms" ; 画像バッファ #const buf_win 1 ; 円周率 (無駄に桁が多い) π = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 ; 円周率/2 πh = 1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017412671058534 ; 1° #define ° 0.01745329251994329576923690768488612713442871888541725456097191440171009114603449443682241569634509482 ; 非トリガーキー #define non_trigger 256 ; debug mode #define debug 0 ; screen shot #define ss 0 ;----------------------------------------------------------- ; 起動 ;----------------------------------------------------------- // 乱数初期化 randomize ;----------------------------------------------------------- ; 部品描画 ;----------------------------------------------------------- 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-cnt32-0.5*cnt*(rnd(7)+2),32-cnt loop // ダメージ用 color 255 circle 32,0, 63,31 gsel 0 ;----------------------------------------------------------- ; 初期化 ;----------------------------------------------------------- ; 蟲のリミット i_max_limit = 300 // 蟲の種類 (長さ変えてるだけ) ; 普通 i_base_len = 10 i_draw_h++ if rnd(2) { ; ムカデ i_base_len = 20 i_draw_h = 10 } *main ;----------------------------------------------------------- ; main start ;----------------------------------------------------------- // stick key_log = key stick key, non_trigger // draw start redraw 0 // background color : boxf // 蟲の数の調整 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 } ;----------------------------------------------------------- ; レーザー、判定 ;----------------------------------------------------------- ; レーザーの法線 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&256 { if key&256:else{ i_type.cnt = 1; 切断!! bld_t.bld_max = cnt bld_cnt.bld_max = mcnt bld_max++ } i_dam(cnt) += mcnt\2 } } } } 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&256)!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 255,255,255 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 // メーター pos 0,0 : mes i_max // 血しぶき repeat bld_max v1 = bld_t(cnt) v2 = mcnt-bld_cnt(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&256 { if key_log&256:else { // 始点 laser_x = double.mousex laser_y = double.mousey } // 描画 hsvcolor mcnt\192,200,255; カラフル♪ if mcnt\2 : line laser_x,laser_y, mousex,mousey } ;----------------------------------------------------------- ; 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