トップ


敵に弾を撃たせる
(Green.tonyuを作成して、Electoron.tonyuを撃たせる)


Green.tonyuを作成する

前ページでクラスの継承が完成しているはずです。敵を追加するのも簡単になりました。Greenというのを追加してみましょう。


Sample6.lzh

Green.tonyu
extends Enemy;


function asteroid(ax,ay,ang,maxis,frate){
  x=ax+maxis*cos(ang)*cos(ang)*cos(ang);
  y=ay+maxis*frate+maxis*frate*sin(ang)*sin(ang)*sin(ang);
}
mark=100;
life=5;
sx=x;
sy=y;
angle=270;
majorAxis=100;
flatRate=1/2;
i=0;
if (x>$myChar.x) vx=2; else vx=-2;
while (y<$screenHeight+15) {
  i++;
  asteroid(sx,sy,angle,majorAxis,flatRate);
  angle+=3;
  if(x<15 || x>$screenWidth-15) d=-d;
  atariHantei();
  if(p==$pat_Sample+19) vp=1;
  else if(p==$pat_Sample+21) vp=-1;
  if(i%20==0) p=p+vp;
  update();
}

三角関数のsin()とcos()を使用して、アステロイドと呼ばれる菱形の図形を描かせています。sin()やcos()を知らなくても、

function asteroid(ax,ay,ang,maxis,frate){
  x=ax+maxis*cos(ang)*cos(ang)*cos(ang);
  y=ay+maxis*frate+maxis*frate*sin(ang)*sin(ang)*sin(ang);
}

をレシピとして使用すれば誰でも出来ます。axとayは中心の座標、angは角度、maxisは長径、frateは扁平率(0<frate<1)です。

さて、口をパカパカ開けて移動していますが、これは
「口を開けたときに弾を撃たせる」 ということを意図して作りました。
口が開いたときに弾を撃たせるにはどうしたらよいでしょうか?

問題がたくさんありそうです。

まず、敵の弾を作るところから考えてみましょう。新しいオブジェクトを作ってElectronと名前を付けてください。

Electoron.tonyu
extends Enemy;


life=100;
while (y<$screenHeight) {
  y=y+2;
  atariHantei();
  update();
}

思ったよりも簡単にできました。ElectronもEnemyよりクラスを継承して、弾が当たっても壊れないようlifeを100に設定しました。

myCharの弾は貫通させたいという場合には、Enemyのクラスを継承せずに、atariHanteiメソッドを作成して、

function atariHantei() {
  if (crashTo($myChar)) $myChar.die();
}

としてあげればできそうです。

今回はアニメーションアダプタが使用できない例ですが、YellowもRedもアニメーションアダプタを使用しないで作成しました。

Green.tonyu
extends Enemy;


function asteroid(ax,ay,ang,maxis,frate){
  x=ax+maxis*cos(ang)*cos(ang)*cos(ang);
  y=ay+maxis*frate+maxis*frate*sin(ang)*sin(ang)*sin(ang);
}
mark=100;
life=5;
sx=x;
sy=y;
angle=270;
majorAxis=100;
flatRate=1/2;
i=0;
animationOn=0;
vp=0;
if (x>$myChar.x) vx=2; else vx=-2;
while (y<$screenHeight+15) {
  i++;
  asteroid(sx,sy,angle,majorAxis,flatRate);
  angle+=3;
  if(x<15 || x>$screenWidth-15) d=-d;
  atariHantei();
  if(rnd(50)==0 && animationOn==0) {
    vp=1;
    animationOn=1;
  }
  if(p==$pat_Sample+21 && vp==1) {
    vp=-1;
    appear(new Electoron(x,y,$pat_Sample+24));
  }
  else if(p==$pat_Sample+19 && vp==-1) {
    vp=0;
    animationOn=0;
  }
  if(i%20==0) p=p+vp;
  update();
}

プログラムが長くなり、複雑になりましたが、内容は簡単です。
animationOnという変数を新たに設けてあります。

ランダムに弾を発射してもらいたいので

if(rnd(50)==0 && animationOn==0) {

のようにrndを使用しました。animetionOnが0の時はアニメーションが行われていない状態です。
以前のようにvpを1に変え、animationOnを1にしてアニメーション中であることを記録します。
次に、口が全開になったときとは、pが$pat_Sample+21の時です。このときに弾を発射できるようにしますが、pが$pat_Sample+21の時に何度でも弾を吐き出されては困るので、vp==1という条件を馳せてあります。
vpはすぐに-1と変わるので1つのアニメーションに対して1つしか弾を発射できないはずです。
最後にpが$pat_Sample+19に戻ったときには、アニメーションを止めなくてはなりません。戻ってきたということはvp==-1のはずです。

p vp p=p+vp animation action
$pat_Sample+19 0 null 0 -
$pat_Sample+19 1 $pat_Sample+19+0 1 -
$pat_Sample+20 1 $pat_Sample+19+1 1 -
$pat_Sample+21 -1 $pat_Sample+20+1 1 appear(new Electoron())
$pat_Sample+20 -1 $pat_Sample+21-1 1 -
$pat_Sample+19 0 $pat_Sample+20-1 0 -
$pat_Sample+19 0 $pat_Sample+19-0 0 -

これで敵も弾を撃つことができるようになりました。

次は、また新しい敵を作成して、ちょっと変わったことをしてみましょう。

  トップ