トップ


中ボスをつける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を再度動かして、敵を出現させ、最後には大ボスを作成してみましょう。

  トップ