简体   繁体   中英

Resizing Movie Clips AS3

好的,所以我有一个Flash游戏,一个平台游戏。在这个游戏中,您必须跳过尖峰,因此我创建了尖峰并将其转换为符号,一个影片剪辑,当它注册为影片剪辑时,不是一个三角形(如尖峰),而是一个矩形。这意味着当玩家避开尖峰并跳跃时,如果他太近则死了,但是他没有撞到尖峰,则击中了周围的不可见矩形仍然可以更改影片剪辑的形状以使其适合尖峰和仅尖峰。

you can use hittest, here is an example of usage

http://www.foundation-flash.com/tutorials/as3hittesting/

From my experience dealing with the same type of issue, you can't really use the AS3 hitTestObject (which I would imagine you're using if you're having this problem) with the specific shape of an MC. It's always going to default to the box that takes up the space of the movieclip itself.

So to answer your question, no, you can't change the shape of the MC to make it spike only, by default hitTestObject uses the bounding box around the MC.

There are few ways around this (many people would suggest NOT using hitTestOjbect in general as it isn't very efficient and instead writing your own hit test code. I would suggest looking for examples of this online, there are lot of them).

Your other option if you don't want to deal with that, would be to create a separate series of box shaped mc's that act as your bounding boxes and can be arranged in arrays and then just run a loop through to see if your character is hitting any of those. That way you can adjust the bounding box sizes as you see it fit.

But if you want to use hitTestObject , unfortunately you have to use the whole object bounding box. Since i'm not entirely sure the details of how you're going about this, my best suggestion would be to just go online and read up on the basics of hit detection in AS3.

Your problem is with hit detection, not necessarily movie clips.

The internal hit test between objects will check the bounding boxes of the objects so that doesn't work for you.

If you can somehow use the player agent as a point (lowest point, like middle of his foot or something like that) you could use spike.hitTestPoint(globalFootX, globalFootY, true);

If that doesn't work you either have to manually create the hittest-representation for the items and do your own hittest logic.

The other solution is to draw the items to a seperate sprite and then see if the pixels overlap. I know I did this in an old AS2-project with AI-robots of irregular shapes moving around in an irregularly shaped world.

I'll provide that code for reference, it might be transformable to AS3 or at least you can use that as inspiration for what to google for in order to find that solution in AS3.

class messer_studios.utils.CollisionDetection {
    static public function checkForCollision(p_clip1:MovieClip, p_clip2:MovieClip, p_alphaTolerance:Number):Rectangle {     
        // set up default params:
        if (p_alphaTolerance == undefined) {
            p_alphaTolerance = 255;
        }

        // get bounds:   
        var bounds1:Object = p_clip1.getBounds(_root);
        var bounds2:Object = p_clip2.getBounds(_root);

        // rule out anything that we know can't collide:
        if (((bounds1.xMax < bounds2.xMin) || (bounds2.xMax < bounds1.xMin)) || ((bounds1.yMax < bounds2.yMin) || (bounds2.yMax < bounds1.yMin))) {
            return null;
        }
        //Debug.log("might collide");

        // determine test area boundaries:   
        var bounds:Object = {};
        bounds.xMin = Math.max(bounds1.xMin, bounds2.xMin);
        bounds.xMax = Math.min(bounds1.xMax, bounds2.xMax);
        bounds.yMin = Math.max(bounds1.yMin, bounds2.yMin);
        bounds.yMax = Math.min(bounds1.yMax, bounds2.yMax);

        // set up the image to use:
        var img:BitmapData = new BitmapData(bounds.xMax-bounds.xMin, bounds.yMax-bounds.yMin, false);

        // draw in the first image:
        var mat:Matrix = p_clip1.transform.concatenatedMatrix;
        mat.tx -= bounds.xMin;
        mat.ty -= bounds.yMin;
        img.draw(p_clip1, mat, new ColorTransform(1, 1, 1, 1, 255, -255, -255, p_alphaTolerance));

        // overlay the second image:
        mat = p_clip2.transform.concatenatedMatrix;
        mat.tx -= bounds.xMin;
        mat.ty -= bounds.yMin;
        img.draw(p_clip2, mat, new ColorTransform(1, 1, 1, 1, 255, 255, 255, p_alphaTolerance), "difference");

        // find the intersection:
        var intersection:Rectangle = img.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
        // if there is no intersection, return null:
        if (intersection.width == 0) {
            return null;
        }

        // adjust the intersection to account for the bounds:   
        intersection.x += bounds.xMin;
        intersection.y += bounds.yMin;
        return intersection;
    };

    public static function hitTestShape(mc1:MovieClip, mc2:MovieClip, alphaTolerence:Number):Boolean {
        return checkForCollision(mc1, mc2, alphaTolerence) != null ? true : false;
    }
}

You can use BitmapData along with hitTest to check pixel level collision like so.

( To test the code place two symbols on the Flash stage, "rectClip" and "spike". Also test it first keeping them away and then second time keep them touched and test it. )

(Either way you can set MouseMove or startDrag() and check it live.)

var rect:Rectangle = rectClip.getBounds(this);
var rectClipBmpData = new BitmapData(rect.width, rect.height, true, 0);
rectClipBmpData.draw(rectClip);

var spikeRect:Rectangle = spike.getBounds(this);
var spikeBmpData = new BitmapData(spikeRect.width, spikeRect.height, true, 0);
spikeBmpData.draw(spike);

if(rectClipBmpData.hitTest(new Point(rectClip.x, rectClip.y),
                                 255,
                                 spikeBmpData,
                                 new Point(spike.x,spike.y),
                                 255 ))
{
     trace("hit");
}else
{
     trace("No hit");
}

Best luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM