0

我和我的朋友正在尝试制作一款 rpg 风格的游戏,您可以从上面看到您的角色,但我们遇到了一些物体碰撞问题。可能值得一提的是,我们在 Flash CS6 中的一个面向对象的 AS3 项目中这样做。

很抱歉,如果这个问题已经被问了一百万次,但我们整天都在寻找解决方案,到目前为止我们发现的要么是对我们来说有点太先进的东西,比如 box2d/nape,要么只是简单的碰撞检测我们已经知道了。

我们遇到的问题是我们想要一种方便的方法来检测碰撞并防止主角与场景中的对象重叠,而不会让它冻结或卡住。到目前为止,我们已经放弃了解决问题的所有尝试,但这里是其余代码,以帮助您了解我们所处的位置(抱歉,如果难以阅读)。任何形式的建议或参考相关教程表示赞赏。

主要班

package {

import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;

public class Engine extends MovieClip
{
    private var hero:Hero;
    private var box1:Box1;

    public function Engine()
    {
        box1 = new Box1();
        stage.addChild(box1);
        box1.x = stage.stageWidth / 4;
        box1.y = stage.stageHeight / 2;

        hero = new Hero(stage, box1);
        stage.addChild(hero);
        hero.x = stage.stageWidth / 2;
        hero.y = stage.stageHeight / 2;
    }

}
}

人物类

package 
{

import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;

public class Hero extends MovieClip
{
    private var box1:Box1;
    private var stageRef:Stage;
    private var vy:Number = 0;
    private var vx:Number = 0;
    private var limit:Number = 30;
    private var rad:Number;
    private var bounce:Number = 0.125;
    private var _max:Number = 8;

    public function Hero(stageRef:Stage, box1:Box1)
    {
        //box variable was used in previous experiments with hit tests
        this.box1 = box1;
        this.stageRef = stageRef;
        Input.initialize(stageRef);
        stageRef.addEventListener(Event.ENTER_FRAME, moveHero);
    }
    private function moveHero(e:Event):void
    {
        if (Input.kd("W","UP"))
        {
            vy = vy < 1 - _max ? _max * -1:vy - 1;
        }
        if (Input.kd("S","DOWN"))
        {
            vy = vy > _max - 1 ? _max:vy + 1;
        }
        else if (!Input.kd("W", "UP", "S", "DOWN"))
        {
            if (vy > 1)
            {
                vy = vy < 1 ? 0:vy - 1;
            }
            else
            {
                vy = vy > -1 ? 0:vy + 1;
            }

        }
        if (Input.kd("A","LEFT"))
        {
            vx = vx < 1 - _max ? _max * -1:vx - 1;
        }
        if (Input.kd("D","RIGHT"))
        {
            vx = vx > _max - 1 ? _max:vx + 1;
        }
        else if (!Input.kd("A", "LEFT", "D", "RIGHT"))
        {
            if (vx > 1)
            {
                vx = vx < 1 ? 0:vx - 1;
            }
            else
            {
                vx = vx > -1 ? 0:vx + 1;
            }

        }
        if (x < limit)
        {
            x = limit;
            vx *=   -  bounce;
        }
        if (x > stage.stageWidth - limit)
        {
            x = stage.stageWidth - limit;
            vx *=   -  bounce;
        }
        if (y < limit)
        {
            y = limit;
            vy *=   -  bounce;
        }
        if (y > stage.stageHeight - limit)
        {
            y = stage.stageHeight - limit;
            vy *=   -  bounce;
        }

        x +=  vx;
        y +=  vy;
        rad = (Math.atan2(stage.mouseY - y,stage.mouseX - x)) * 180 / Math.PI;
        this.rotation = rad;


    }
}
}
4

1 回答 1

0

进行碰撞检测的一种简单方法是:

1) 尝试将对象 X 移动到新位置

2) 对于游戏 Y 中的每个其他对象,计算 Y 和 X 是否重叠(将对圆中的矩形、矩形中的矩形、圆中的圆等使用不同的算法)

3)如果它们确实重叠,请返回步骤 1,但尝试将其移动一半。或者:如果你碰撞的物体是圆形的,改变运动的角度使其与它相切,同时根据你旋转它的程度使其变小(角度变化的余弦,所以 0x 表示 90 度变化,(sqrt2 /2)x 表示 45 度变化,1x 表示 0 度变化,这在我看来是有道理的。)

4)如果你的移动成功了,保持它。如果运动长度变得非常小并且仍然被拒绝,假设您处于休息状态并放弃。

更复杂的算法会将您从碰撞的中心弹出,因此您将通过走进弯曲的物体等方式绕着弯曲的物体弯曲,但是您必须小心弹射不会与第三个物体发生碰撞对象 Z,它可能会变得很棘手。(您是否考虑过使用物理库?它们被编码是有充分理由的——物理很难做到正确。)

于 2013-01-22T03:20:11.537 回答