前 次 トップ |
中ボスをつける2
middleBossの周りにRoundを8つ配置する
8つ置くということは、360/8=45度間隔で黄色い玉を配置すればよいことになります。
まず、黄色い玉のオブジェクトRoundが作成されていることを確認してください。
Round.tonyu |
---|
extends Enemy; while(1){ x=$middleBoss.x+80*cos(ang); y=$middleBoss.y+80*sin(ang); ang++; update(); } |
Roundは8つ作られる黄色い玉のことです。
先ほどと同じようにコンストラクタが必要です。
middleBoss.tonyu |
---|
extends Enemy; constructor round(x,y,p,ang) { //コンストラクター super(x,y,p); this.ang=ang; } while(1){ x=$middleBoss.x+80*cos(ang); y=$middleBoss.y+80*sin(ang); ang++; update(); } |
コンストラクタの仕様はHELPで確認してみてください。
x座標とy座標、画像変数p、それと角度angを受け取ることができるようになっています。
superというのでx,y,pはmiddleBoss側から送られてきた数値を使用することを定義しています。
angはappearの中には定義されていない数値でした。
コンストラクタの中でこのオブジェクトのangは送られてきたangを使用すると定義しておきました。
これで、黄色い玉の方は終わりです。次に、middleBossの方も変えておきましょう。
middleBoss.tonyu |
---|
extends Enemy; x=$screenWidth/2-50; y=-40; while(y<80){ x=$screenWidth/2-20; y++; drawSprite(x,y,$pat_Sample+2); update(); } vx=2; ang=0; for(i=1;i<=8;i++) appear(new Round(x,y,$pat_Sample+27,i*45)); while(1){ ang++; x+=vx; y=y+sin(3*ang)/2; if(x<80 || x>$screenWidth-80) vx=-vx; drawSprite(x,y,$pat_Sample+2); update(); } |
これで、黄色い玉RoundがmiddleBossの周りをまわるようになりました。
Roundにライフを100くらい持たせて、middleBossを守っているようにしてみましょう。
さらに、middleBossにはライフを200くらい持たせておきましょう。当たり判定メソッドをつけることを忘れないようにしましょう。
middleBoss.tonyu |
---|
extends Enemy; x=$screenWidth/2-50; y=-40; while(y<80){ x=$screenWidth/2-20; y++; drawSprite(x,y,$pat_Sample+2); update(); } vx=2; ang=0; life=200; mark=200; for(i=1;i<=8;i++) appear(new Round(x,y,$pat_Sample+27,i*45)); while(1){ ang++; x+=vx; y=y+sin(3*ang)/2; if(x<80 || x>$screenWidth-80) vx=-vx; drawSprite(x,y,$pat_Sample+2); atariHantei(); update(); } |
Round.tonyu |
---|
extends Enemy; constructor round(x,y,p,ang) { //コンストラクター super(x,y,p); this.ang=ang; } life=100; mark=50; while(1){ x=$middleBoss.x+80*cos(ang); y=$middleBoss.y+80*sin(ang); ang++; atariHantei(); update(); } |
middleBossには玉も撃たせるようにしておきましょう。Stingというオブジェクトを作成して、画像$pat_Sample+28を使用してみましょう。
middleBoss.tonyu |
---|
extends Enemy; function appearShoot() { if (rnd( 100 )==0) for(i=-2;i<=2;i++) appear(new Sting(x,y,$pat_Sample+28,i)); if (rnd( 100 )==0) appear(new Ball(x,y,$pat_Sample+25)); } x=$screenWidth/2-50; y=-40; while(y<80){ x=$screenWidth/2-20; y++; drawSprite(x,y,$pat_Sample+2); update(); } vx=2; ang=0; life=200; mark=200; for(i=1;i<=8;i++) appear(new Round(x,y,$pat_Sample+27,i*45)); while(1){ ang++; x+=vx; y=y+sin(3*ang)/2; if(x<80 || x>$screenWidth-80) vx=-vx; drawSprite(x,y,$pat_Sample+2); appearShoot(); atariHantei(); update(); } |
Sting.tonyu |
---|
extends Enemy; constructor sting(x,y,p,vx) { //コンストラクター super(x,y,p); this.vx=vx; if(!vx) vx=0; } while(1){ x=x+vx; y++; atariHantei(); update(); } |
コンストラクタを使用して、5方向に同時にStingを発射させています。さらに、Ballもたまに出現させています。
中ボスを出現させる
中ボスとは一対一で戦いたいものです。他の敵がいたのでは目障りな上、ゲームの難易度も非常に高くなり、バランスを崩してしまうことでしょう。
中ボスが出てくるときには、UFOは画面右端に止めておきましょう。
UFO.tonyu |
---|
extends SpriteChar; function appearEnemy() { if (rnd( 400 )==0) appear(new Item(rnd(530)+15,y,22)); if (rnd( 1600 )==0) appear(new Item(rnd(530)+15,y,17)); if (rnd( 50 )==0) appear(new skyBlue(x,y,$pat_Sample+2)); if (rnd( 100 )==0 && $score>100) appear(new Yellow(x,y,$pat_Sample+8)); if (rnd( 200 )==0 && $score>200) appear(new Red(x,y,$pat_Sample+11)); if (rnd( 800 )==0 && $score>300) appear(new Green(x,y+20,$pat_Sample+19)); if (rnd( 1600 )==0 && $score>400) appear(new Blue(x,y+20,$pat_Sample+22)); if ($score>1000 && stop==0) stop=1; } vx=2; stop=0; while(1) { if(! $myChar.isDead()) { if(!( (stop==1 || stop==2) && x>$screenWidth - 42 )) x=x+vx; else { if(stop==1){ appear(new middleBoss(x,y,$pat_Sample+26)); stop=2; } } if( stop==0 ) { appearEnemy(); } if( x<40 || x>$screenWidth - 40 ) vx=-vx; } update(); } |
stopという変数を使用しています。得点が1000点以上でstopを1にします。これで、中ボスは出現します。
中ボスが何回も出てきたのではこまりますので、stopを2にしました。UFO自体は画面の右端から2だけ左側に来たら止まってくれるはずです。
stopが0の時だけ敵が出てきますので、stopが1や2の時には出現しません。
これで、中ボスの完成です。初期画面の中ボスのオブジェクトを消して、ゲームを実際に行ってみてください。
エラーとバグが1つずつ見つかったと思います。
エラーはRoundクラスで「nullはオブジェクトではないため変数yを参照できません」だと思います。
バグはF9でもう一度実行したときに、ボスが右端ま行って止まり、中ボスが突然出現してくることだと思います。
何故このようなことが起ったのでしょうか?
Round.tonyu |
---|
extends Enemy; constructor round(x,y,p,ang) { //コンストラクター super(x,y,p); this.ang=ang; } life=100; mark=50; while(1){ for( t in $Chars ){ if( t is middleBoss ){ x=t.x+80*cos(ang); y=t.y+80*sin(ang); } } ang++; atariHantei(); update(); } |
弾が敵に当たっても貫通しないようにするでも説明しましたが、middleBossオブジェクトが「どのmiddleBossなのかわからなくなってしまった」からエラーがでてきたのです。新規作成で作成したオブジェクトに関しては$middleBossで.xなどで参照できましたが、appearで出現させたオブジェクトはfor...in文を使用して目的のオブジェクトを明確にしなければなりません。
バグについては、このように考えてください。$scoreは0に見えますが、これはグローバル変数なので、その数値は残ります。F9でUFOはもう一度読み込まれたのですが、そのときにはまだ$scoreが前回の1000以上の数値だったということです。実際にはF9をもう一度押せば元通りに戻ったと思います。このバグを解消するためには、$scoreの初期化を早めなければならなさそうです。
Text.tonyu |
---|
extends TextChar; $bgcolor=11816980; $se_shootingsample1.play(); i=255; while(1) { text="Score:"+$score; if($myChar.isDead()) { if(i>0) i--; if(i==250) for(t in $chars) if(t is Enemy) t.die(); if(i==200) appear(new Blue($screenWidth/2,$UFO.y,$pat_Sample+22)); if(i==1) $UFO.die(); $bgcolor=color( 0, 0, i); drawText($screenWidth/2-130,$screenHeight/2-30,"Game Over",color(255-i,255-i,255-i),50); update(); } else update(); } |
UFO.tonyu |
---|
extends SpriteChar; function appearEnemy() { if (rnd( 400 )==0) appear(new Item(rnd(530)+15,y,22)); if (rnd( 1600 )==0) appear(new Item(rnd(530)+15,y,17)); if (rnd( 50 )==0) appear(new skyBlue(x,y,$pat_Sample+2)); if (rnd( 100 )==0 && $score>100) appear(new Yellow(x,y,$pat_Sample+8)); if (rnd( 200 )==0 && $score>200) appear(new Red(x,y,$pat_Sample+11)); if (rnd( 800 )==0 && $score>300) appear(new Green(x,y+20,$pat_Sample+19)); if (rnd( 1600 )==0 && $score>400) appear(new Blue(x,y+20,$pat_Sample+22)); if ($score>1000 && stop==0) stop=1; } $score=0; vx=2; stop=0; while(1) { if(! $myChar.isDead()) { if(!( (stop==1 || stop==2) && x>$screenWidth - 42 )) x=x+vx; else { if(stop==1){ appear(new middleBoss(x,y,$pat_Sample+26)); stop=2; } } if( stop==0 ) { appearEnemy(); } if( x<40 || x>$screenWidth - 40 ) vx=-vx; } update(); } |
これで全ての問題が解決されたことを確認してみてください。Textクラスの$score=0の一文は消さなくても同じ結果を得ることはできます。見やすいように消しておきました。
中ボスはこれで完成しました。次は、中ボス後にUFOを再度動かして、敵を出現させ、最後には大ボスを作成してみましょう。
前 次 トップ |