忍者ブログ

幻日記

お絵描き&ゲーム制作好きの ひとりごと日記

AS3横スクロールアクションゲーム制作5

操作方法:
↑…ジャンプ。押す長さ長さによって変ります
←→…移動。同時押しでブレーキ
スペース…攻撃、アイテムを取った後だと飛び道具になります

攻撃はスペースキーで統一しました。
左に浮かんでいる黄色いアイムを取ってからスペースを押すと
物理攻撃から飛び道具に変ります。
今の所↓キーは使わない感じに戻ってしまいましたが
後々アイテムを拾うキーなんかに振り当てようかな、と考えてます。

今回の大幅な変更点はブロックの概念を取り入れたこと。
空中に浮いてる黒紫の■に乗ることができます。
まだ判定が甘い感じですが今の所このままで進めようかと思います。
床の緑の部分もブロックに書き換えました。
これだけで1日が終わってしまったとは自分でもビックリ。

以前TonyuSystemでブロックの概念を作った時は
それほど難しくなかったんだけど、今回は
「主人公の足元にブロックが存在する」という状態を認識するのに
for文や配列を使わないといけなかったのがミソ。

↓これから実装していく予定など
・現在、攻撃は右方向に固定されている。左や上にも攻撃できるように進行
(Shiftを押している間は主人公を固定させ、全方向に攻撃を打てるようにしたい)
・必要であれば画面をスクロールさせるコードを追加させる
・敵を具体化させ、重力の概念、攻撃の概念を加える
・キーの↓を押すとアイテムが拾えるようにする
・飛び道具がブロックを貫通しないようにする
・主人公の回避or防御モーションの追加

個人的にはスマブラやデッドライジングっぽい要素を付け足していきたいです。
var left_flg  : Boolean = false;//←を押してるかどうかのフラグ
var right_flg : Boolean = false;//→を押してるかどうか…
var up_flg : Boolean = false;//↑を押してるかどうか…
var down_flg : Boolean = false;//↓を押してるかどうか…
var space_flg : Boolean = false;//スペースを押してるか…
 
var vx : Number = 0;//主人公の横加速度
var vy : Number = 0;//主人公の縦加速度
var delay : int = 0;//攻撃のディレイ。0だと攻撃可能になる。
var j_flg : Boolean = true;//ジャンプのフラグ。false=可
var weapon: int = 0;//選択中の武器
var timer : int = 0;//ゲームの時間軸を表す変数
 
var bullet_array01:Array = new Array();//弾1用配列
var attack_array01:Array = new Array();//攻撃1用配列
var enemy_array01:Array = new Array();//敵1用配列
var item_array01:Array = new Array();//アイテム1用配列
var weapon_array:Array = new Array();//選択武器配列
var block_array:Array = new Array();//ブロック配列
 
var s_right:int ;//主人公の右端
var s_left :int ;//主人公の左端
var s_top  :int ;//主人公の上端
var s_bottom:int;//主人公の下端
 
var b_right:int ;//ブロックの右端
var b_left :int ;//ブロックの左端
var b_top  :int ;//ブロックの上端
var b_bottom:int;//ブロックの下端
 
 
// キーボードが押されたときに呼び出されるイベント
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownFunc);
function KeyDownFunc(event:KeyboardEvent):void{
if(event.keyCode == 37){
left_flg = true;
}
if(event.keyCode == 39){
right_flg = true;
}
if(event.keyCode == 38){
up_flg = true;
}
if(event.keyCode == 32){
space_flg = true;
}
if(event.keyCode == 40){
down_flg = true;
}
}
 
 
// キーボードが離されたときに呼び出されるイベント
stage.addEventListener(KeyboardEvent.KEY_UP, KeyUpFunc);
function KeyUpFunc(event:KeyboardEvent):void{
    if(event.keyCode == 37){
        left_flg = false;
    }
if(event.keyCode == 39){
        right_flg = false;
    }
if(event.keyCode == 38){
        up_flg = false;
    }
if(event.keyCode == 32){
        space_flg = false;
    }
if(event.keyCode == 40){
        down_flg = false;
    }
 
}
 
// 毎フレーム実行されるイベント
 
stage.addEventListener(Event.ENTER_FRAME, function(event:Event):void{
//■timerが0の時に敵を準備---------------------------------
if(timer==0){
var block:Block = new Block();//床になるブロックを配置
block_array.push(block);
block_array[block_array.length-1].x = 400;
block_array[block_array.length-1].y = 580;
block_array[block_array.length-1].gotoAndStop(2);
addChild(block_array[block_array.length-1]);
 
var enemy:Enemy01 = new Enemy01();//敵を配置
enemy_array01.push (enemy);
enemy_array01[enemy_array01.length-1].x = 600;
enemy_array01[enemy_array01.length-1].y = 260;
addChild (enemy_array01[enemy_array01.length-1]);
 
var enemy:Enemy01 = new Enemy01();//敵を配置
enemy_array01.push (enemy);
enemy_array01[enemy_array01.length-1].x = 700;
enemy_array01[enemy_array01.length-1].y = 550;
addChild (enemy_array01[enemy_array01.length-1]);
 
var item:Item01 = new Item01();//アイテムを配置
item_array01.push(item);
item_array01[item_array01.length-1].x =100;
item_array01[item_array01.length-1].y =450;
//var item_array01[item_array01.length-1].i_state:int = 1;
addChild(item_array01[item_array01.length-1]);
 
var block:Block = new Block();//ブロックを配置
block_array.push(block);
block_array[block_array.length-1].x = 200;
block_array[block_array.length-1].y = 400;
addChild(block_array[block_array.length-1]);
 
var block:Block = new Block();//ブロックを配置
block_array.push(block);
block_array[block_array.length-1].x = 500;
block_array[block_array.length-1].y = 540;
addChild(block_array[block_array.length-1]);
}
 
//■移動に関する処理----------------------------------------
if(left_flg && right_flg){//←→同時に押してる場合
if(vx<1 && vx>-1){
vx=0;//加速度が0に近づくと完全に停止させる
}else{
vx+= -vx/2;//加速度を減らしていく
}
}else if(left_flg && vx>-10 && Syuzinko.x-Syuzinko.width/2 > 0){//←を押す
        vx -= 0.5;
if(Syuzinko.x>stage.stageWidth){//画面→からはみ出るのを防ぐ
Syuzinko.x=stage.stageWidth;
}
}else if(left_flg && vx>=-10 && Syuzinko.x-Syuzinko.width/2 > 10){//←を押す(ダッシュ時)
vx = -10;
}else if(right_flg && vx<10 && Syuzinko.x+Syuzinko.width/2 < stage.stageWidth){//→を押す
vx += 0.5;
if(Syuzinko.x<0){//画面←からはみ出るのを防ぐ
Syuzinko.x=0;
}
}else if(right_flg && vx<=10 && Syuzinko.x+Syuzinko.width/2 < stage.stageWidth-10){//→を押す(ダッシュ時)
vx = +10;
}else{//何も押していない場合
if(vx<1 && vx>-1){
vx=0;//加速度が0に近づくと完全に停止させる
}else{
vx+= -vx/4;//加速度を減らしていく
}
}
//■ジャンプに関する処理----------------------------------------
if(up_flg && !j_flg){
vy = -20;//ジャンプさせる
j_flg = true;
trace("ジャンプしたよ");
}
if(j_flg && vy <-15 && !up_flg){//ジャンプの出だしで↑を押していない場合は
vy+=10;//小ジャンプに変更
}
//■攻撃に関する処理----------------------------------------
if(weapon==0 && space_flg && delay==0){//装備が無い場合、素手で攻撃
var attack:Attack01 = new Attack01();
attack_array01.push(attack);
addChildAt(attack,1);
attack.x = Syuzinko.x;
attack.y = Syuzinko.y;
delay=16;
}else if(weapon==1 &&space_flg && delay==0){//ハンドガン1を装備し、スペースを押し、ディレイ0の時
            var bullet:Bullet01 = new Bullet01();//弾を作成
            bullet_array01.push(bullet);//その弾を配列へ入れる
            addChildAt(bullet, 1);//画面内に登場させる
            bullet.x = Syuzinko.x;
            bullet.y = Syuzinko.y;
delay=12;
}
//□弾が画面外へ飛んでいった場合、削除する
if(bullet_array01.length != 0){//弾が画面内に存在する場合
for(var i:int=0; i<bullet_array01.length; i++){//弾全てに対し
if (bullet_array01[i].x > stage.stageWidth) {//ステージ外へ飛んだら
removeChild(bullet_array01[i]);//ステージから消すよう命令
bullet_array01.splice (i , 1);//配列からも削除しておく
}
    }
}
//□攻撃して一定時間が経った場合、削除する
if(attack_array01.length != 0){//攻撃が画面内に存在する場合
for(var i:int=0; i<attack_array01.length; i++){
attack_array01[i].x = Syuzinko.x;
attack_array01[i].y = Syuzinko.y;
if(attack_array01[i].life < 0){
removeChild(attack_array01[i]);
attack_array01.splice(i,1);
}
}
}
//■当り判定に関する処理----------------------------------------
//□弾の処理
loop1: for (i = 0 ; i < enemy_array01.length ; i ++) {
for (var j:uint = 0 ; j < bullet_array01.length ; j ++) {
if (enemy_array01[i].hitTestObject (bullet_array01[j])) {
removeChild (bullet_array01[j]);//弾が消える
bullet_array01.splice (j , 1);//
enemy_array01[i].life -= 1;//体力を減らす
if(enemy_array01[i].life<=0){//敵が死んでいれば
removeChild (enemy_array01[i]);//死亡処理
enemy_array01.splice (i , 1);
}
break loop1;
}
}
}
//□物理攻撃の処理
loop2: for (i = 0 ; i < enemy_array01.length ; i ++) {
for (var j:uint = 0 ; j < attack_array01.length ; j ++) {
if (enemy_array01[i].hitTestObject (attack_array01[j])) {
removeChild (attack_array01[j]);//弾が消える
attack_array01.splice (j , 1);//
enemy_array01[i].life -= 1;//体力を減らす
if(enemy_array01[i].life<=0){//敵が死んでいれば
removeChild (enemy_array01[i]);//死亡処理
enemy_array01.splice (i , 1);
}
break loop2;
}
}
}
 
//□アイテム獲得処理
if(weapon_array.length-1 < 5){//アイテムの所持数が5未満の時
loop3: for (i = 0 ; i < item_array01.length ; i ++) { //全ての落ちてるアイテムを参照
if (item_array01[i].hitTestObject (Syuzinko)) {//落ちてるアイテムと主人公がぶつかった場合
weapon = item_array01[i].i_state;//アイテムを手に持っている状態にする
removeChild (item_array01[i]);//アイテムが消えて
item_array01.splice (i , 1);//アイテムが配列から消える
weapon_array.push(weapon);//代わりに装備ボックスに入る 
MovieClip(getChildByName("slot"+i)).gotoAndStop(2);//装備スロットを変化
}
break loop3;
}
}
 
//■ブロックぶつかり判定処理----------------------------------------
//□横からのぶつかり判定
if(block_array.length != 0){
s_right = Syuzinko.x + Syuzinko.width/2;//主人公の右端
s_left  = Syuzinko.x - Syuzinko.width/2;//主人公の左端
s_top   = Syuzinko.y - Syuzinko.height/2;//主人公の上端
s_bottom= Syuzinko.y + Syuzinko.height/2;//主人公の下端
loop4: for(i = 0 ; i < block_array.length ; i ++){
b_right = block_array[i].x + block_array[i].width/2;//ブロックの右端
b_left  = block_array[i].x - block_array[i].width/2;//ブロックの左端
b_top   = block_array[i].y - block_array[i].height/2;//ブロックの上端
b_bottom= block_array[i].y + block_array[i].height/2;//ブロックの下端
 
if(block_array[i].hitTestPoint(s_right,Syuzinko.y) && vx>0){
vx= 0;//主人公が左から右へ触れた場合
Syuzinko.x--;
trace("左からあたる");
break loop4;
}else if(block_array[i].hitTestPoint(s_left,Syuzinko.y) && vx<0){
vx = 0;//主人公右から左へ触れた場合
Syuzinko.x++;
trace("右からあたる");
break loop4;
}else{trace("横は特に処理なし"+i);}
}
}
//□縦からのぶつかり判定
if(block_array.length != 0){
s_right = Syuzinko.x + Syuzinko.width/2;//主人公の右端
s_left  = Syuzinko.x - Syuzinko.width/2;//主人公の左端
s_top   = Syuzinko.y - Syuzinko.height/2;//主人公の上端
s_bottom= Syuzinko.y + Syuzinko.height/2;//主人公の下端
loop5: for(i = 0 ; i < block_array.length ; i ++){
b_right = block_array[i].x + block_array[i].width/2;//ブロックの右端
b_left  = block_array[i].x - block_array[i].width/2;//ブロックの左端
b_top   = block_array[i].y - block_array[i].height/2;//ブロックの上端
b_bottom= block_array[i].y + block_array[i].height/2;//ブロックの下端
if(block_array[i].hitTestPoint(Syuzinko.x,s_top) && vy<0){
Syuzinko.y = b_bottom + Syuzinko.height/2;
vy=-1;//ブロックに頭をぶつけた場合の処理
trace("頭をぶつけた");
break loop5;
}else if(!(block_array[i].hitTestPoint(Syuzinko.x,s_bottom+10)) && !j_flg){
trace("ブロックから落ちる"+i);
j_flg=true;
}if(block_array[i].hitTestPoint(Syuzinko.x,s_bottom+10) && vy>0 &&j_flg){
Syuzinko.y = b_top - Syuzinko.height/2;
vy=0;//ブロックに乗った場合の処理
j_flg=false;
trace("のったどーーー!"+i);
break loop5;
}if(block_array[i].hitTestPoint(Syuzinko.x,s_bottom+10)){
j_flg=false;
trace("とにかく足元にブロックがある"+i)
break loop5;
}else{trace("縦は特に処理なし"+i);}
}
}
//■無条件で起こる処理----------------------------------------
if(j_flg){
vy+=1;//空中に居る場合、落下させる
trace("落下した");
}
trace("ジャンプできる?="+j_flg);
trace(timer+"----------------------");
Syuzinko.x += vx;//主人公を動かす
Syuzinko.y += vy;
timer++;//時間が進み、timerをインクリメント
 
if(delay>0){//攻撃のディレイをデクリメント
delay--;
}
});

拍手