0

4 方向すべてを使用してキャラクターを動かす Flash ゲームをプログラムしようとしています。ゲーム内のキャラクターは実際には動きませんが、動きをシミュレートするために背景が動きます。ただし、壁をプログラミングする方法を理解する必要があります。衝突を認識するコードがありますが、それを行う最善の方法は何ですか? これは私のコードです:

stage.addEventListener(Event.ENTER_FRAME,handleCollision);

function handleCollision( e:Event ):void{

    if(hero.hitTestObject(wall))
       {
           wall.x-=5;
           Background.x-=5;
       }
}

これは衝突を認識し、背景と壁の動きを止めますが、キャラクターが右から壁にぶつかった場合にのみ機能します。このコードをすべての壁に差し込み、状況に合わせて調整する必要がありますか? または、コーディングを最小限に抑えることができるように、壁を操作するより合理的な方法はありますか?

更新: 配列を利用して壁を追跡するというジェイソンのアイデアを使用してみましたが、別の問題が発生しました。これまでの私のコードは次のとおりです。

stage.addEventListener(Event.ENTER_FRAME,onenter);

var wall:Array = [Northwall, Southwall, Eastwall, Westwall];

function onenter(e:Event):void {

if(Key.isDown(Key.RIGHT))
{
    Background.x-=5;
    hero.scaleX=1;
    for each(var wall:MovieClip in walls)
    {
        Northwall.x-=5;
        Southwall.x-=5;
        Eastwall.x-=5;
        Westwall.x-=5;
    }
    hero.gotoAndStop('walking sideways');
}
else if(Key.isDown(Key.LEFT))
{
    Background.x+=5;
    hero.scaleX=-1;
    for each(var walls0:MovieClip in walls)
    {
        Northwall.x+=5;
        Southwall.x+=5;
        Eastwall.x+=5;
        Westwall.x+=5;
    }
    hero.gotoAndStop('walking sideways');
}
else if(Key.isDown(Key.DOWN))
{
    Background.y-=5;
    for each(var walls1:MovieClip in walls)
    {
        Northwall.y-=5;
        Southwall.y-=5;
        Eastwall.y-=5;
        Westwall.y-=5;
    }
    hero.gotoAndStop('walking down');

}
else if(Key.isDown(Key.UP))
{
    Background.y+=5;
    for each(var walls2:MovieClip in walls)
    {
        Northwall.y+=5;
        Southwall.y+=5;
        Eastwall.y+=5;
        Westwall.y+=5;
    }
    hero.gotoAndStop('walking up');
}
else
{
    hero.gotoAndStop('still 1');
}




 for each (var walls:MovieClip in walls) {  
   if (hero.hitTestObject(Northwall))
{
    Background.y-=5;
}
else if (hero.hitTestObject(Southwall))
{
    Background.y+=5;
}
else if (hero.hitTestObject(Westwall))
{
    Background.x-=5;
}
else if (hero.hitTestObject(Eastwall))
{
    Background.x+=5;
}

コードはコンパイルされ、すべてが実行されますが、壁は登録されていません。if/else ステートメントの移動コードに関係していると思います。壁は背景と一緒に動くのではなく、キャラクターと一緒に動いていると思います。壁が背景と一緒に動くようにコーディングして、実際に壁にぶつかるかどうかを実際にテストするにはどうすればよいですか?

更新 2: 自分のプログラムで Jason が提供したコードを利用してみましたが、うまくいきました。キャラクターは移動して壁にぶつかることができ、ほとんどの移動コードは意図したとおりに機能します。ただし、イーストウォールだけは正しく機能しているようです。サウスウォールは横から登録しているようで、北から打とうとすると変な動きをします。当然、横からではなく北から登録して、イーストウォールに当たったときと同じ効果を出したいです。Northwall と Westwall もまったく登録されていないようです。これは完全に実装されたコードです:

var walls:Array = [Northwall, Southwall, Eastwall, Westwall];

stage.addEventListener(KeyboardEvent.KEY_DOWN,keydownHandler);
function keydownHandler(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case Keyboard.RIGHT:
            moveWalls(-5, 0);
            Background.x-=5;
            hero.scaleX=1;
            hero.gotoAndStop('walking sideways');
            break;
        case Keyboard.LEFT:
            moveWalls(5, 0);
            Background.x+=5;
            hero.scaleX=-1;
            hero.gotoAndStop('walking sideways');
            break;
        case Keyboard.UP:
            moveWalls(0, -5);
            Background.y+=5;
            hero.gotoAndStop('walking up');
            break;
        case Keyboard.DOWN:
            moveWalls(0, 5);
            Background.y-=5;
            hero.gotoAndStop('walking down');
            break;
    }
}

function moveWalls(x:Number, y:Number):void
{
    for each (var wall:DisplayObject in walls)
    {
        wall.x += x;
        wall.y += y;
    }
}

stage.addEventListener(Event.ENTER_FRAME,frameHandler);
function frameHandler(event:Event):void
{
    for each (var wall:DisplayObject in walls)
    {
        if (hero.hitTestObject(wall))
        {
            switch (wall)
            {
                case Northwall:
                    moveWalls(0, -5);
                    Background.y-=5;
                    break;
                case Southwall:
                    moveWalls(0, 5);
                    Background.y+=5;
                    break;
                case Westwall:
                    moveWalls(-5, 0);
                    Background.x-=5;
                    break;
                case Eastwall:
                    moveWalls(5, 0);
                    Background.x+=5;
                    break;
            }
        }
    }
}

問題は hitTest にあると思います。確信はないけど。また、ボタンを押しっぱなしにするとキャラクターが抵抗するのですが、長押しするとキャラクターが壁をすり抜けてしまいます。キャラクターが壁を通り抜けないようにするにはどうすればよいですか?

4

1 に答える 1

1

テストするすべてのオブジェクトのコレクションを保持し、ループを繰り返すことができます。

var walls:Array = [ northWall, southWall, westWall, eastWall ];

for each (var wall:DisplayObject in walls)
{
    if (hero.hitTestObject(wall))
    {
        // hit wall
    }
}

または、バインドされている文字とパスをヒット テストすることにより、逆を適用することもできます。

if(!hero.hitTestObject(path))
{
    // left path
}

それ以外の場合は、定義済みの境界の座標をテストできます。

var bounds:Rectangle = new Rectangle(0, 0, 400, 400);

if ((hero.x < bounds.x) ||
    (hero.x > (bounds.x + bounds.width)) ||
    (hero.y < bounds.y) ||
    (hero.y > (bounds.y + bounds.height)))
{
    // left path
}

更新:新しい例に基づいて、機能要求の実装例を次に示します。

Flash Pro での設定例:

Flash Pro のセットアップ

このプロジェクトは、私の Web サイトからダウンロードできます。

Flash Pro CS5.5: http://www.jasonsturges.com/labs/stack-overflow/examples/hero/Hero-cs5.5.fla
Flash Pro CS5: http://www.jasonsturges.com/labs/stack -overflow/examples/hero/Hero-cs5.fla
SWF: http://www.jasonsturges.com/labs/stack-overflow/examples/hero/Hero.swf

壁をそれぞれインスタンス名を持つムービー クリップとして使用すると、次のようにアクションを実装できます。

import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.DisplayObject;

// put walls in collection
var walls:Array = [ northWall, southWall, eastWall, westWall ];

// animtion listener
addEventListener(Event.ENTER_FRAME, frameHandler);

// key listeners
stage.addEventListener(KeyboardEvent.KEY_DOWN, keydownHandler);


// keyboard handling
function keydownHandler(event:KeyboardEvent):void
{
    switch (event.keyCode)
    {
        case Keyboard.RIGHT:
            moveWalls(-5, 0);
            break;
        case Keyboard.LEFT:
            moveWalls(5, 0);
            break;
        case Keyboard.UP:
            moveWalls(0, -5);
            break;
        case Keyboard.DOWN:
            moveWalls(0, 5);
            break;
    }
}

// utility to move all walls
function moveWalls(x:Number, y:Number):void
{
    for each (var wall:DisplayObject in walls)
    {
        wall.x += x;
        wall.y += y;
    }
}

// animation handler
function frameHandler(event:Event):void
{
    for each (var wall:DisplayObject in walls)
    {
        if (hero.hitTestObject(wall))
        {
            switch (wall)
            {
                case northWall:
                    moveWalls(0, -5);
                    break;
                case southWall:
                    moveWalls(0, 5);
                    break;
                case westWall:
                    moveWalls(-5, 0);
                    break;
                case eastWall:
                    moveWalls(5, 0);
                    break;
            }
        }
    }
}
于 2012-04-08T02:27:36.590 に答える