//////////////////////////////////////////////////////////////////////////////// // huge.hsp // Last Modified:2007/09/28-23:52. // // コメント少ない/滅茶苦茶、故あんま参考にならないかも // //////////////////////////////////////////////////////////////////////////////// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // constant numbers // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Ship #enum _s_x_=0 #enum _s_y_ #enum _s_sx_ #enum _s_sy_ #enum _s_size_ #const SHIP_WIDTH 12 #const SHIP_WIDTH_HALF SHIP_WIDTH / 2 // Enemy #enum _e_x_=0 #enum _e_y_ #enum _e_life_ #enum _e_accel_ #enum _e_sx_ #enum _e_sy_ #enum _e_size_ #const ENEMY_CAPACITY 32 #const ENEMY_WIDTH 12 // Particle #enum _p_x_=0 #enum _p_y_ #enum _p_sx_ #enum _p_sy_ #enum _p_used_ #enum _p_size_ #const PARTICLE_CAPACITY 32 * 8 #const PARTICLE_WIDTH 2 // Ammo #enum _a_x_=0 #enum _a_y_ #enum _a_sx_ #enum _a_sy_ #enum _a_used_ #enum _a_owner_ #enum _a_size_ #const AMMO_CAPACITY 256 // owner of ammo #enum owner_ship_ = 0 #enum owner_enemy_ // Block #enum _b_x_=0 #enum _b_y_ #enum _b_used_ #enum _b_size_ #const BLOCK_CAPACITY 10 #const BLOCK_WIDTH 80 #const BLOCK_WIDTH_HALF BLOCK_WIDTH / 2 #const BLOCK_WIDTH_HALF_SQRT2 1.141592653 * BLOCK_WIDTH_HALF // Buffer #const MAIN_BUFFER_WIDTH 640 #const MAIN_BUFFER_HEIGHT 480 // phase #enum phase_title = 0 #enum phase_playing // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 関数 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #module // サイズ削減のために、関数名を短くする // かといって一文字じゃ使いにくいから、適当にそれっぽい名前のエイリアスを付けとく #deffunc e array xy, int w #define global square e grect xy, xy.1, 0, w, w grect xy, xy.1, 0, w - 2, w - 2 return // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 正方形同士の当たり判定 // x1 正方形のX座標そのいち // y1 正方形のY座標そのいち // w1 正方形の幅そのいち // x2 正方形のX座標そのに // y2 正方形のY座標そのに // w2 正方形の幅そのに // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #defcfunc f array xy1, int w1, array xy2, int w2 #define global isInSquare f dw = w1 + w2 return ( xy1 < xy2 + dw ) && ( xy1 + dw > xy2 ) && ( xy1.1 < xy2.1 + dw ) && ( xy1.1 + dw > xy2.1 ) // 軽い晩 ;return ( ( x1 - w1 < x2 + w2 ) && ( x1 + w1 > x2 - w2 ) && ( y1 - w1 < y2 + w2 ) && ( y1 + w1 > y2 - w2 ) ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 差を求める // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #define global diff g #deffunc g array xy_ret, array xy1, array xy2 xy_ret = xy1 - xy2 xy_ret.1 = xy1.1 - xy2.1 return // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 距離を求める // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #define global dist m #defcfunc m array xy return sqrt( xy * xy + xy.1 * xy.1 ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // パーティクル登録 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #define global entryParticle _ #deffunc _ array p, int mp dim nums repeat PARTICLE_CAPACITY@ dup particle@, particles@.0.cnt if( ( particle@._p_used_@ ) + ( nums >= mp * 3 ) ) { continue } nums++ power = rnd( mp ) rad = rnd( 100 ) particle@ = p, p.1, sin( rad ) * power, cos( rad ) * power, 1.0 loop return #global // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // global // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;#define NO_HSPTV #ifndef NO_HSPTV # runtime "hsptv" # regcmd 18 # cmd hsptv_send 0 #else if 0 { #deffunc hsptv_send var __a, int __b return } #endif d0 = 0.0 __xy = d0, d0 #define __xy__x __xy dup __xy__y, __xy.1 gosub*init // たうえ randomize gettime( 7 ) // 軽量版 int() #define ctype _int(%1) ( 0 + %1 ) fontFace = "MS ゴシック" repeat // 初期化 redraw : await 16 : redraw 0 frame++ #define ship_s_x_ ship dup ship_s_y_, ship._s_y_ pget 3200 if( damaged ) { color 0xff } dim damaged boxf stick key, 15 gmode 4, , , 64 if( phase ) : else { color 0x33, 0x33, 0xff pos 32, 192 font fontFace, 18, 17 repeat 15 noteget name, cnt * 3 + 1 noteget score, cnt * 3 mes strf( "%2d", cnt + 1 ) + strf( "%8d(", _int( score ) ) + name + ")" xy = 576, cnt * 48 square xy, 48 xy = cnt * 48, 144 square xy, 48 loop pos 280, 60 font fontFace, 48, 17 mes ":-))))))))" if( key ) { phase++ } } else { // 船の動き // (書いてて良くわからん) repeat 2 dup ship_s_sxy_, ship( _s_sx_ + cnt ) if( life > 0 ) { ship_s_sxy_ += 0.5 * ( ( key >> ( 2 + cnt ) & 1 ) - ( key >> ( cnt ) & 1 ) ) } ship_s_sxy_ *= 0.95 ship( cnt ) += _int( ship_s_sxy_ ) dup __xy_cnt, __xy( cnt ) __xy_cnt = ship( cnt ) + ship_s_sxy_ // 壁との当たり判定 huge = MAIN_BUFFER_WIDTH, MAIN_BUFFER_HEIGHT if( __xy_cnt < 0 || __xy_cnt > huge( cnt ) ) { ship_s_sxy_ *= -1 } loop // ブロックとの当たり判定 repeat BLOCK_CAPACITY dup block, blocks.0.cnt if( block._b_used_ ) { // ブロック使われてる? if( isInSquare( __xy, SHIP_WIDTH_HALF, block, BLOCK_WIDTH_HALF ) ) { repeat 2 d = ship.cnt - block.cnt if( d + SHIP_WIDTH_HALF < - BLOCK_WIDTH_HALF || d > BLOCK_WIDTH_HALF ) { ;if( ship.cnt + SHIP_WIDTH_HALF < block.cnt - BLOCK_WIDTH_HALF || ship.cnt > block.cnt + BLOCK_WIDTH_HALF ) { ship( _s_sx_ + cnt ) *= -1 } loop } // ついでにブロックを描く color 0x00, 0x00, 0xff square block, BLOCK_WIDTH } loop // 船描く if( life > 0 ) { color 0xff square ship, SHIP_WIDTH } else { frame = 1 gameOverCount++ entryParticle ship, gameOverCount \ 8 + ( gameOverCount > 96 ) * 16 } if( gameOverCount > 128 ) { dim phase hsptv_send buf, generation gosub*init } // ざんき xy = 632, 16 repeat 8 if( life <= cnt ) { color 0xff, 0xaa, 0xaa } xy -= 16 square xy, 12 loop if( generationUp ) { repeat ( generation / 4 ) + 1 ;enemy._e_x_ = double( rnd( 640 ) ) ;enemy._e_y_ = 1.0 * rnd( 480 ) ;enemy._e_life_ = 8.0 ;enemy._e_count_ = 0.0 ;enemy._e_accel_ = 0.030 * rnd( 10 ) enemies.0.cnt = double( rnd( MAIN_BUFFER_WIDTH ) ), double( rnd( MAIN_BUFFER_HEIGHT ) ), 6.0 + generation \ 2, 0.030 * rnd( 8 ), d0, d0 loop dim generationUp } #define sediff __xy #define sediffx __xy__x #define sediffy __xy__y // 敵描いたり dim enemyExist dim locked repeat ENEMY_CAPACITY dup enemy, enemies.0.cnt // ロックオン先変更 if( locked ) : else : if( ( key & 64 ) + ( enemyLockedEnemy._e_life_ == 0 ) ) { lockedEnemy++ lockedEnemy \= ENEMY_CAPACITY dup enemyLockedEnemy, enemies.0.lockedEnemy locked += enemyLockedEnemy._e_life_ lockEffectSpeed = 1.0 } if( enemy._e_life_ ) { enemyExist++ visible++ diff sediff, ship, enemy sedist = dist( sediff ) repeat BLOCK_CAPACITY dup block, blocks.0.cnt if( block._b_used_ ) { // 自機が見えているか調べる。具体的には、 // 敵の距離:自機の距離 = 敵の距離:ブロックの距離 // となるような、敵座標と自機座標の半直線状にある内分点の位置を算出して // そいつがブロックの内部にあるかしらべる。 // 位置関係によっては外分点になっちゃうから、そういうのは内積の値を見て対処する // もっと簡素にできんかな。文章といいアルゴリズムといい :< // - B**2 - 4 * a * c とか? diff sbdiff, ship, block sbdist = dist( sbdiff ) diff bediff, block, enemy xy = ship_s_x_ - sediffx * sbdist / sedist, ship_s_y_ - sediffy * sbdist / sedist diff ddxy, xy, block if( ( dist( ddxy ) < BLOCK_WIDTH_HALF_SQRT2 ) ) { if( bediff * sbdiff + bediff.1 * sbdiff.1 > 0 ) { // 外積がマイナスだから外分点 dim visible } break } } loop if( generationFrame < 64 ) { dim visible } repeat 2 if( visible ) { enemy( _e_sx_ + cnt ) += sediff(cnt) / sedist * enemy._e_accel_ } enemy( cnt ) += enemy( _e_sx_ + cnt ) enemy( _e_sx_ + cnt ) *= 0.95 loop // 絵ねミー描く gmode 4, , , limit( generationFrame * 2, 0, 96 ) color 0xff square enemy, ENEMY_WIDTH if( visible * ( generationFrame \ ( 32 - generation / 3 ) == 0 ) ) { repeat AMMO_CAPACITY dup ammo, ammos.0.cnt if( ammo._a_used_ ) : else { ammo = enemy._e_x_, enemy._e_y_, sediffx / sedist * 6.0, sediffy / sedist * 6.0, 1.0, 1.0/*owner_enemy_*/ break } loop } } loop #undef sediff #undef sediffx __xy__x #undef sediffy __xy__y // 弾 dim ammoCreated repeat AMMO_CAPACITY dup ammo, ammos.0.cnt dup ammo_a_used_, ammo._a_used_ // 弾発射 if( frame \ 8 + ammo_a_used_ + ammoCreated + ( enemyLockedEnemy._e_life_ == 0 ) ) : else { __xy = enemyLockedEnemy._e_x_ - ship_s_x_, enemyLockedEnemy._e_y_ - ship_s_y_ len = dist( __xy ) ammo = ship_s_x_, ship_s_y_, __xy__x / len * 8.0, __xy__y / len * 8.0, 1.0, d0 ammoCreated++ } if( ammo_a_used_ ) { repeat 2 dup ammo_a_xy_, ammo( cnt ) ammo_a_xy_ += ammo( _a_sx_ + cnt ) if( ammo_a_xy_ < 0 || huge < ammo_a_xy_ ) { ammo_a_used_ *= 0 } loop color 0x66, 0x99, 0xff gmode 4, , , 128 square ammo, 4 if( ammo._a_owner_ == owner_enemy_ ) { if( isInSquare( ammo, 2, ship, 6 ) ) { ammo_a_used_ *= 0 life-- damaged++ } } else { repeat ENEMY_CAPACITY dup enemy, enemies.0.cnt dup enemy_life_, enemy._e_life_ if( enemy_life_ ) { if( isInSquare( ammo, 2, enemy, 6 ) ) { ammo_a_used_ *= 0 enemy_life_-- if( enemy_life_ ) : else { entryParticle enemy, 10 } } } loop } repeat BLOCK_CAPACITY dup block, blocks.0.cnt if( block._b_used_ ) { if( isInSquare( block, BLOCK_WIDTH_HALF, ammo ) ) { ammo_a_used_ *= 0 break } } loop } loop // パーティクル描く gmode 4, , , 32 repeat PARTICLE_CAPACITY dup particle, particles.0.cnt if( particle._p_used_ ) { repeat 2 particle(cnt) += particle( _p_sx_ + cnt ) particle( _p_sx_ + cnt ) *= 0.95 loop color 0xff square particle, 4 memcpy __xy, particle._p_sx_, 16 if( dist( __xy ) <= 1 ) { particle._p_used_ *= 0 } } loop if( enemyLockedEnemy._e_life_ ) { color 0x00, 0xff, 0x99 a = lockEffectSpeed * 1000 grect enemyLockedEnemy._e_x_, enemyLockedEnemy._e_y_, lockEffectRad, a, a lockEffectRad = lockEffectSpeed + lockEffectRad lockEffectSpeed *= 0.8 lockEffectSpeed += 0.01 } if( enemyExist ) : else { generationUpEffectCount++ } if( generationUpEffectCount ) { generationUpEffectCount++ pget 3200 gmode 6, , , 32 grect 320, 240, 0, 640, 80 pos 240, 220 color font fontFace, 32 mes "Generation: " + generation if( generationUpEffectCount > 64 ) { generation++ dim generationUpEffectCount generationUp++ dim generationFrame } } generationFrame++ if( frame \ 32 == 0 ) { dup block, blocks( 0, rnd( BLOCK_CAPACITY ) ) #const NUM_HORIZONAL_BLOCK_CAPACITY MAIN_BUFFER_WIDTH / BLOCK_WIDTH #const NUM_VERTICLE_BLOCK_CAPACITY MAIN_BUFFER_HEIGHT / BLOCK_WIDTH __xy = double( rnd( NUM_HORIZONAL_BLOCK_CAPACITY ) * BLOCK_WIDTH + BLOCK_WIDTH_HALF ), double( rnd( NUM_VERTICLE_BLOCK_CAPACITY ) * BLOCK_WIDTH + BLOCK_WIDTH_HALF ) pget __xy__x, __xy__y if( isInSquare( __xy, BLOCK_WIDTH_HALF, ship, SHIP_WIDTH_HALF ) ) : else : if( ginfo_g == 0xff ) { memcpy block, __xy, 16 block._b_used_++ } } } loop *init //ddim ship, _s_size_ ship = 320.0, 240.0 // 変数初期化 ddim enemies, _e_size_, ENEMY_CAPACITY ddim ammos, _a_size_, AMMO_CAPACITY ddim blocks, _b_size_, BLOCK_CAPACITY ddim particles, _p_size_, PARTICLE_CAPACITY hsptv_send buf, -1 notesel buf life = 8 dim gameOverCount dim Generation dup enemyLockedEnemy, enemies return /* * TODO: * * FIXME: * * NOTE: * */