▼ActionScript 2.0メモ▼
格闘ゲーム


格闘ゲームを作成する。


4キー 左移動
5キー 決定・攻撃
6キー 右移動

携帯電話(W43S等)で実行するには↓へアクセス。
http://npaka.net/flash/as20/kakuto/kakuto.swf


リソース
ソースコードを配置するフォルダにresフォルダを作成してそこに置く。
0.png

1.png

2.png

3.png

4.png

5.png

6.png

7.png

8.png

9.png

10.png


ソースコード
A.as
//格闘ゲーム(本体)
class A extends MovieClip {
    //キー定数
    private var KEY_NONE:Number  =-999;//なし
    private var KEY_LEFT:Number  =4;//左
    private var KEY_RIGHT:Number =6;//右
    private var KEY_UP:Number    =2;//上
    private var KEY_DOWN:Number  =8;//下
    private var KEY_SELECT:Number=5;//決定
        
    //シーン定数
    private var S_TITLE:Number   =0;//タイトル
    private var S_PLAY:Number    =1;//プレイ
    private var S_GAMEOVER:Number=2;//ゲームオーバー

    //アクション定数
    private var A_NONE:Number  =-1;//なし
    private var A_LEFT:Number  =0;//左
    private var A_RIGHT:Number =1;//右
    private var A_ATTACK:Number=2;//攻撃
    private var A_DAMAGE:Number=3;//ダメージ
    private var A_DOWN:Number  =4;//ダウン

    //システム
    private var scene:Number   =0;//シーン
    private var init:Number    =0;//初期化
    private var keyEvent:Number=0;//キーイベント
    private var keyState:Number=0;//キー状態
    private var img:Array=new Array(11);//イメージ

    //格闘家
    private var ftX:Array     =new Array(2);//X座標
    private var ftCmd:Array   =new Array(2);//命令
    private var ftAct:Array   =new Array(2);//行動
    private var ftActIdx:Array=new Array(2);//行動INDEX
    private var ftImgIdx:Array=new Array(2);//イメージINDEX
    private var ftHP:Array    =new Array(2);//HP

    
    //コンストラクタ
    function A () {
        var i:Number;

        //イメージの取得
        for (i=0;i<11;i++) {
            img[i]=Util.addImage(this,"r"+i);
        }
        img[9].setXY((128-76)/2,45);
        img[10].setXY((128-67)/2,45);

        //矩形の追加
        ftHP[0]=Util.addRect(this,50,8,0xffff00,0,0xffff00);
        ftHP[0].setXY(75,5);
        ftHP[1]=Util.addRect(this,50,8,0xffff00,0,0xffff00);
        ftHP[1].setXY(53,5);

        //マスクの指定
setMask(Util.addRect(this,128,156)); //キーリスナーの指定 Key.addListener(this); //定期処理の開始 init=S_TITLE; setInterval(this,"onTick",100); } //定期処理の処理 private function onTick():Void { var i:Number,j:Number,dx:Number; //シーンの初期化 if (init>=0) { //タイトルとプレイの初期化 if (init==S_TITLE || init==S_PLAY) { for (i=0;i<2;i++) { ftX[i] =(i==0)?91:37; ftAct[i] =A_NONE; ftActIdx[i] =0; ftImgIdx[i] =0; ftHP[i]._width=50; ftHP[i]._visible=true; } img[9 ]._visible=false; img[10]._visible=false; } //ゲームオーバー if (init==S_GAMEOVER) { if (ftHP[0]._visible) { img[9]._visible=true; } else { img[10]._visible=true; } } //共通の初期化 scene =init; init =-1; keyEvent=KEY_NONE; } //キーイベントの処理 ftCmd[0]=A_NONE; ftCmd[1]=A_NONE; if (scene==S_PLAY) { //プレイヤー if (((1<<KEY_LEFT) &keyState)!=0) ftCmd[0]=A_LEFT; if (((1<<KEY_RIGHT)&keyState)!=0) ftCmd[0]=A_RIGHT; if (keyEvent==KEY_SELECT) ftCmd[0]=A_ATTACK; //敵 ftCmd[1]=calcAI(ftX,ftAct); } else { if (keyEvent==KEY_SELECT) init=S_PLAY; } keyEvent=KEY_NONE; //格闘家の処理 for (i=0;i<2;i++) { j=(i==0)?1:0; dx=0; ftImgIdx[i]=0; //命令 if (ftAct[i]<=A_RIGHT) { ftAct[i]=ftCmd[i]; ftActIdx[i]=0; } //衝突判定 if (ftAct[i]==A_ATTACK && ftActIdx[i]<2 && Math.abs(ftX[0]-ftX[1])<20 && ftAct[j]!=A_DAMAGE) { ftAct[j] =A_DAMAGE; ftActIdx[j]=0; //ゲームオーバー if (ftHP[j]._width<=8) { ftHP[j]._visible=false; ftAct[j]=A_DOWN; init =S_GAMEOVER; } else { ftHP[j]._width-=8; } } //左移動 if (ftAct[i]==A_LEFT) { dx=-4; } //右移動 else if (ftAct[i]==A_RIGHT) { dx=4; } //攻撃 else if (ftAct[i]==A_ATTACK) { if (ftActIdx[i]<2) dx=(i==0)?-6:6; ftImgIdx[i]=1; if (++ftActIdx[i]>6) ftAct[i]=A_NONE; } //ダメージ else if (ftAct[i]==A_DAMAGE) { dx=(i==0)?4:-4; ftImgIdx[i]=2; if (++ftActIdx[i]>4) ftAct[i]=A_NONE; } //ダウン else if (ftAct[i]==A_DOWN) { dx=(i==0)?6:-6; ftImgIdx[i]=3; } //移動 ftX[i]+=dx; if (ftX[i]<0) ftX[i]=0; if (ftX[i]>128) ftX[i]=128; if (ftX[0]-ftX[1]<18) ftX[i]=(i==0)?ftX[1]+18:ftX[0]-18; } //描画 for (i=1;i<9;i++) img[i]._visible=false; img[ftImgIdx[0]+1]._visible=true; img[ftImgIdx[0]+1].setXY(ftX[0]-15,80); img[ftImgIdx[1]+5]._visible=true; img[ftImgIdx[1]+5].setXY(ftX[1]-15,80); ftHP[1]._x=53-ftHP[1]._width; } //敵の思考ルーチン private function calcAI(x:Array,action:Array):Number { var distance:Number=0;//格闘家の距離 var attack:Number =0;//攻撃の優先度 var move:Number =0;//移動の優先度 //距離による優先度の上下 distance=Math.abs(x[1]-x[0]); if (distance<20) { attack+=Util.rand(5); move +=Util.rand(7)-4; } else if (distance<25) { attack+=Util.rand(3); move +=Util.rand(9)-3; } else { attack+=Util.rand(3)-2; move +=Util.rand(8)-2; } //現在のアクションによる優先度の上下 if (action[1]==A_LEFT) move+=2; if (action[1]==A_RIGHT) move-=2; //結果 if (attack> 1) return A_ATTACK; if (move <-1) return A_LEFT; if (move > 1) return A_RIGHT; return A_NONE; } //キーダウンイベントの処理 private function onKeyDown() { var keyCode:Number=Key.getCode(); //決定 if (keyCode==13) keyEvent=KEY_SELECT; //携帯 if (48<=keyCode && keyCode<=58) { this.keyState|=(1<<(keyCode-48)); this.keyEvent=keyCode-48; } //PC if (37<=keyCode && keyCode<=40) { if (keyCode==37) keyCode=KEY_LEFT; if (keyCode==38) keyCode=KEY_UP; if (keyCode==39) keyCode=KEY_RIGHT; if (keyCode==40) keyCode=KEY_DOWN; this.keyState|=(1<<keyCode); this.keyEvent=keyCode; } } //キーアップイベントの処理 private function onKeyUp() { var keyCode:Number=Key.getCode(); //携帯 if (48<=keyCode && keyCode<=58) { this.keyState^=(1<<(keyCode-48)); } //PC if (37<=keyCode && keyCode<=40) { if (keyCode==37) keyCode=KEY_LEFT; if (keyCode==38) keyCode=KEY_UP; if (keyCode==39) keyCode=KEY_RIGHT; if (keyCode==40) keyCode=KEY_DOWN; this.keyState^=(1<<keyCode); } } }

Util.as
//ユーティリティ
class Util {
    //ラベルの追加
    static function addLabel(parent:MovieClip,
        text:String):TextField {
        //初期値
        if (text==undefined) text="";

        //インスタンス名の自動生成
        if (parent.nameIdx==undefined) parent.nameIdx=0;
        var name:String="_name"+(parent.nameIdx++);

        //テキストフィールドの追加
        parent.createTextField(name,
            parent.getNextHighestDepth(),0,0,0,0);
        var mc:TextField=parent[name];
        mc.autoSize  ="left";//オートサイズ
        mc.selectable=false; //選択不可
        mc.text=text;        //テキスト
        mc._x  =0;           //X座標
        mc._y  =0;           //Y座標
        
        //書式
        mc.format=new TextFormat();
        mc.format.font ="_等幅"; //フォント
        mc.format.size =12;      //文字サイズ
        mc.format.color=0x000000;//文字色
        mc.setTextFormat(mc.format);
        
        //XY座標の指定
        mc.setXY=function(_x:Number,_y:Number) {
            this._x=_x;
            this._y=_y;
        }

        //テキストの指定
        mc.setText=function(_text:String) {
            this.text=_text;
            this.setTextFormat(this.format);
        }
        
        //文字サイズの指定
        mc.setFontSize=function(size:Number) {
            this.format.size=size; 
            this.setTextFormat(this.format);
        }
        
        //文字色の指定
        mc.setFontColor=function(color:Number) {
            this.format.color=color;
            this.setTextFormat(this.format);
        }
        return mc;
    }

    //イメージの追加
    static function addImage(parent:MovieClip,
        id:String):MovieClip {

        //インスタンス名の自動生成
        if (parent.nameIdx==undefined) parent.nameIdx=0;
        var name:String="_name"+(parent.nameIdx++);

        //MovieClipの追加
        parent.attachMovie(id,name,parent.getNextHighestDepth());
        var mc:MovieClip=parent[name];

        //XY座標の指定
        mc.setXY=function(_x:Number,_y:Number) {
            this._x=_x;
            this._y=_y;
        }
        return mc;
    }

    //矩形の追加
    static function addRect(parent:MovieClip,
        w:Number,h:Number,color:Number,thick:Number,bgColor:Number):MovieClip {
        //初期値
        if (color  ==undefined) color  =0x000000;
        if (thick  ==undefined) thick  =0;
        if (bgColor==undefined) bgColor=0x000000;

        //インスタンス名の自動生成
        if (parent.nameIdx==undefined) parent.nameIdx=0;
        var name:String="_name"+(parent.nameIdx++);

        //矩形の追加
        parent.createEmptyMovieClip(name,
            parent.getNextHighestDepth());
        var mc:MovieClip=parent[name];
        if (bgColor>=0) mc.beginFill(bgColor);
        mc.lineStyle(thick,color);
        mc.moveTo(0,0);
        mc.lineTo(w,0);
        mc.lineTo(w,h);
        mc.lineTo(0,h);
        mc.lineTo(0,0);
        if (bgColor>=0) mc.endFill();

        //XY座標の指定
        mc.setXY=function(_x:Number,_y:Number) {
            this._x=_x;
            this._y=_y;
        }
        return mc;
    }

    //乱数の取得
    static function rand(num:Number):Number {
        return Math.floor(Math.random()*num);
    }
}

application.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<movie version="7" width="128" height="156" framerate="10">
    <background color="#000000"/>
    <clip import="classes.swf" />
    <frame>
        <library>
            <!-- クラス -->
            <clip id="Application" class="A" />

            <!-- リソース -->
            <clip id="r0" import="res/0.png" />
            <clip id="r1" import="res/1.png" />
            <clip id="r2" import="res/2.png" />
            <clip id="r3" import="res/3.png" />
            <clip id="r4" import="res/4.png" />
            <clip id="r5" import="res/5.png" />
            <clip id="r6" import="res/6.png" />
            <clip id="r7" import="res/7.png" />
            <clip id="r8" import="res/8.png" />
            <clip id="r9" import="res/9.png" />
            <clip id="r10" import="res/10.png" />
        </library>
        <place id="Application" name="app" x="0" y="0" depth="1000" />
    </frame>
</movie>


コンパイル
mtasc -version 7 -swf classes.swf -header 128:156:10 A
swfmill simple application.xml kakuto.swf



−戻る−