// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // sakusaku.hsp // Last Modified:2006/10/31-12:03. // // 健常者が読めるものでもなさげ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 定数宣言 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ウィンドウ情報 #const MAIN_WINDOW_WIDTH 640 #const MAIN_WINDOW_HEIGHT 480 #const MAIN_WINDOW_WIDTH_HALF MAIN_WINDOW_WIDTH / 2 #const MAIN_WINDOW_HEIGHT_HALF MAIN_WINDOW_HEIGHT / 2 // ぶーすときー #const BOOST_KEY 16 | 32 | 64 // 配列変数の初期化用 #const NUM_USABLE_AMMOS 256 #const global NUM_USABLE_PARTICLE 2048 // パーティクル用変数のプロパティ #enum global _p_x_ = 0 #enum global _p_y_ #enum global _p_speed_ #enum global _p_hue_ #enum global _p_elemn_ // 弾用変数のプロパティ #enum global _a_x_ = 0 #enum global _a_y_ #enum global _a_speed_x_ #enum global _a_speed_y_ #enum global _a_used_ #enum global _a_elemn_ // ぱい #define global PI (3.141592) #define global PI_2_DIV_3 (2.0943951) // フェーズ管理 #enum ON_PLAYING=0 #enum ON_TITLE // ブール(気分で) #define TRUE 1 #define FALSE 0 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // モジュール // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #module // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 似たような処理を関数にしといて、気兼ねなくエフェクトを使いまくる // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - drawTriangle- - - - - - - - - - - - - - - - - - - - - - - - - // 三角形描く。正三角形。 // param x 中心X座標 // param y 中心Y座標 // param d 大きさ // param theta 回転角 // param alpha (合成時の)加算値 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #deffunc drawTriangle int x, int y, double d, double theta, int alpha // まずは頂点座標を計算する // 4つ目の座標と、1つ目の座標を一致させることで、 // 四角形を描く命令であるはずの"gsquare"に三角形を描かせる repeat 4 xs.cnt = x + d * cos( theta + PI_2_DIV_3 * cnt ) ys.cnt = y + d * sin( theta + PI_2_DIV_3 * cnt ) loop // で描く gmode 5, 0, 0, alpha gsquare -1, xs, ys return // - - - - - - - - - entryParticle - - - - - - - - - - - - - - - - - - - - - - - - // パーティクルを登録する。拡散型パーティクル。 // param x X座標 // param y Y座標 // param power パーティクルの力 // param hue パーティクルの色 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #deffunc entryParticle double x, double y, double power, double hue dim huga repeat power huga++ if( particles@._p_speed_.huga > 1.0 ) { // 使用済み continue cnt // 探しなおし } particles@.0.huga = x, y, power, hue loop return // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // モジュール終了 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #global // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // メイン // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; 中間コード節約用変数 fontFace = "MS Gochic" // 田植え randomize gosub*tinyInit repeat redraw : await 30 : redraw 0 // 背景初期化 // ダメージ受けた直後はちょっと赤くする color 0x33 + damaged * 0x60, 0x33, 0x66 boxf dim damaged // キー入力取得 stick key, 15 // オブジェ(太陽らしひ) sunRadPower *= 0.95 // 適当に加速度を弱める sunRad = 0.10 + sunRad + sunRadPower // 回転させる // 角度をPIずらし、二回に分けて書くことで太陽っぽい形にする repeat 2 color 0xff, 0x33, 0x33 ;drawTriangle タイトル画面なら右にずらす - 移動量 , タイトルならちょっと下にずらす , 大きく , 回転 , アルファ drawTriangle MAIN_WINDOW_WIDTH_HALF + phase * 540 - huge * 2, MAIN_WINDOW_HEIGHT_HALF + ( phase ) * 30, 30 + huge, PI * cnt + sunRad, 0x60 loop // タイトル if( phase ) { // 上下のしましま描く repeat MAIN_WINDOW_HEIGHT if( ( cnt & 2 ) * ( ( cnt - 240 ) / 120 ) ) { color line 0, cnt, MAIN_WINDOW_WIDTH, cnt } loop // ボタン押されたら点滅 // ボタン押されてなければ普通に表示 color 0x33, 0x99, 0x99 if( ( buttonPressed ) * ( cnt & 4 ) ) : else { // 右上の Sakusaku pos 500, 80 font fontFace, 32 mes "Sakusaku" // 左下の pos 20, 372 font fontFace, 24 mes "Rank " + high } // ボタン押された if( key ) { buttonPressed++ sunRadPower = 10.0 } // 太陽を移動 if( buttonPressed ) { huge += 16 } if( huge > 1024 ) { dim phase // 下の phase = ... と同じ・・・のはず ;phase = ON_PLAYING huge = MAIN_WINDOW_HEIGHT continue 0 } } else { // レベルアップ if( cnt \ 192 ) : else { level++ remainBoost += 3 } // 中央に pos 270, 120 font fontFace, 32, 16 color 0xcc, 0xcc, 0x33 // レベルアップ通知 if( cnt \ 192 < 24 ) { if( cnt & 4 ) { if( level == 1 ) { mes " Start!" } else { mes "Level " + level } } } if( life <= 0 ) { // 死 if( huge < 384 ) { entryParticle charPosX, charPosY, abs( 16 - huge * huge / 2048 ), 72 } if( huge > 256 ) { mes " Game Over" } if( huge > 768 ) { gosub*tinyInit } huge += 8 } else { huge -= ( huge > 0 ) * 8 } if( huge == 8 ) { continue 32 } accel = 1 // 適当に加速決めとく if( remainBoost > 0 ) { // ブースト使用可能 if( key & BOOST_KEY ) { // コントロールキー押された if( key & 15 ) { // 方向キーも押されてる(これが無いと空撃ちされちゃう) accel = 20 // スピードアップ remainBoost-- entryParticle charPosX, charPosY, 20, 32 } } } // 一定感覚でブーストが回復 remainBoost += ( cnt \ 128 == 0 ) // 0を下回ったら戻す remainBoost -= remainBoost > 8 // キャラのスピード決定 if( life > 0 ) { charSpeedX += accel * ( ( key & 4 ) != 0 ) - accel * ( ( key & 1 ) != 0 ) charSpeedY += accel * ( ( key & 8 ) != 0 ) - accel * ( ( key & 2 ) != 0 ) } // 適当に減速させる charSpeedX *= 0.85 charSpeedY *= 0.85 // 移動 charPosX += charSpeedX charPosY += charSpeedY // スピード計算 charSpeed = sqrt( charSpeedX * charSpeedX + charSpeedY * charSpeedY ) // 壁に当たった? ;if( charPosX < 0 || charPosX > MAIN_WINDOW_WIDTH ) { if( ( charPosX - MAIN_WINDOW_WIDTH_HALF ) / MAIN_WINDOW_WIDTH_HALF ) { charSpeedX *= -3.5 // 跳ね返り } ;if( charPosY < 0 || charPosY > MAIN_WINDOW_HEIGHT ) { if( ( charPosY - MAIN_WINDOW_HEIGHT_HALF ) / MAIN_WINDOW_HEIGHT_HALF ) { charSpeedY *= -3.5 // 跳ね返り } // 弾生成するかね? requireNewAmmo = ( huge < 8 ) * ( ( cnt \ ( 64 - level ) ) == 0 ) // 弾 repeat NUM_USABLE_AMMOS dup _ammo, ammos.0.cnt dup _ammoUsed, _ammo._a_used_ dup _ammoSpeedX, _ammo._a_speed_x_ dup _ammoSpeedY, _ammo._a_speed_y_ ;dup _ammoPosX, _ammo._a_x_ #define _ammoPosX _ammo dup _ammoPosY, _ammo._a_y_ if( _ammoUsed ) { // 中央オブジェとの当たり判定 if( ( _ammoPosX - MAIN_WINDOW_WIDTH_HALF ) / 30 ) : else : if( ( _ammoPosY - MAIN_WINDOW_HEIGHT_HALF ) / 30 ) : else { _ammoUsed = 0.0 entryParticle MAIN_WINDOW_WIDTH_HALF, MAIN_WINDOW_HEIGHT_HALF, 10, 128 sunRadPower += 0.4 } // キャラとのあたり定 if( ( _ammoPosX - charPosX ) * ( _ammoPosX - charPosX ) + ( _ammoPosY - charPosY ) * ( _ammoPosY - charPosY ) < ( charSize + 20 ) * ( charSize + 20 ) ) { _ammoUsed = 0.0 won = charSpeed > 20 if( won ) : else { // 負け life-- damaged++ } entryParticle charPosX, charPosY, 15, won * 128 } // 向き設定 direction = atan( charPosY - ( _ammoPosY + _ammoSpeedY ), charPosX - ( _ammoPosX + _ammoSpeedX ) ) _ammoSpeedX += cos( direction ) _ammoSpeedY += sin( direction ) _ammoSpeedX *= 0.955 _ammoSpeedY *= 0.95 // 移動 _ammoPosX += _ammoSpeedX _ammoPosY += _ammoSpeedY // 描く pget 3200 drawTriangle _ammoPosX, _ammoPosY, 10, direction, 0x40 } else { if( requireNewAmmo ) { _ammoUsed++ _ammoPosX = double( rnd( MAIN_WINDOW_WIDTH ) ), double( rnd( 2 ) * MAIN_WINDOW_HEIGHT ) } dim requireNewAmmo } loop // メーター repeat 16 // ライフ color 0x33, 0xff, 0x99 drawTriangle cnt * 20 + 20, 20, 10, 0, 60 + ( cnt < life ) * 80 // ブーストメータ color 0xff, 0x33, 0xaa if( cnt < 8 ) { drawTriangle MAIN_WINDOW_WIDTH - cnt * 20 - 20, MAIN_WINDOW_HEIGHT - 20, 10, 0, 180 - ( cnt >= remainBoost ) * 120 } loop // レベル pos 12, 448 font fontFace, 20, 17 mes "Level " + level // パーティクル描く repeat NUM_USABLE_PARTICLE dup _particle, particles.0.cnt dup _particle_p_speed, _particle._p_speed_ if( _particle_p_speed > 1 ) { hsvcolor _particle._p_hue_, 160, 128 _particle = _particle + _particle_p_speed * cos( cnt ), _particle._p_y_ + _particle_p_speed * sin( cnt ) drawTriangle _particle, _particle._p_y_, 4, direction, 0x80 _particle_p_speed *= 0.90 } loop // 重なったなら if( ( charPosX - MAIN_WINDOW_WIDTH_HALF ) / 30 ) : else : if( ( charPosY - MAIN_WINDOW_HEIGHT_HALF ) / 30 ) : else { // 巨大化 charSize++ } // だんだんちいさく if( cnt \ 8 ) : else { charSize -= charSize > 0 } // 自機 charRad = 0.09 + charRad + charSpeed / 20 color 0x99, 0xff, 0x99 if( huge < 320 ) { drawTriangle charPosX, charPosY, 10 + charSize - huge / 32, charRad, 0x60 } // 軌跡 entryParticle charPosX, charPosY, sqrt( charSpeed + 1 ), 72 } loop *tinyInit // キャラ変数 charPosX = MAIN_WINDOW_WIDTH_HALF charPosY = 400 charSpeedX = 0.0 charSpeedY = charSpeedX // パーティクル ddim particles, _p_elemn_, NUM_USABLE_PARTICLE // 弾 ddim ammos, _a_elemn_, NUM_USABLE_AMMOS if( high < level ) { high = level } // いろいろ life = 16 dim level huge = 160 dim buttonPressed dim charSize phase = ON_TITLE return