StarlingGraphics / Starling-Extension-Graphics

flash.display.Graphics style extension for the Starling Flash GPU rendering framework
https://github.com/StarlingGraphics/Starling-Extension-Graphics/wiki
MIT License
285 stars 88 forks source link

Collision in games - New Graphics Extension Feature #97

Open IonSwitz opened 10 years ago

IonSwitz commented 10 years ago

Following a question on the Starling Forum, I realized that this Graphics Extension, with the new Collision stuff can be used in games to great effect.

I have added a method to Stroke called "fromBounds" that creates a bounding box in a Stroke, which can be used for quick collision detection.

The example below creates a "laser" beam that zigzags across the screen. As squares move across , they get hit by the laser beam, but with really quick and fast object aligned and geometry based collision detection.

Why is this awesome? Well, in a game, the developer can create these Strokes to perform the collision detection, addChild them to the stage, and set them to visible = false, and still rely on them for collisions.

The discussion at Starling Forum is here:

http://forum.starling-framework.org/topic/bounds-intersect-question

Another beauty of this? We don't have to generate the triangles to use this, all that is needed is the vertex lines created by addVertex.

The code example follows

IonSwitz commented 10 years ago

package { import flash.display.Shape; import starling.display.graphics.Graphic; import starling.display.graphics.NGon; import flash.geom.Point; import flash.geom.Rectangle; import starling.core.Starling; import starling.display.graphics.Stroke; import starling.display.Sprite; import starling.events.Event;

public class GeometryHitTest extends Sprite
{
    private var hitPoint:Point = new Point();
    private var hitPointVector:Vector.<Point>;
    private var laserStroke: Stroke;
    private var creepStrokes: Vector.<Stroke> = new Vector.<Stroke>();
    private var creepSpeed: Vector.<Number> = new Vector.<Number>();

    public function GeometryHitTest()
    {
        addEventListener(Event.ADDED_TO_STAGE, onAdded);
    }

    private function onAdded ( e:Event ):void
    {
        stage.color = 0;

        laserStroke = new Stroke();
        laserStroke.addVertex(0, 0, 1, 0xFF0000);
        laserStroke.addVertex(300, 200, 1, 0xFF0000);
        laserStroke.addVertex(200, 400, 1, 0xFF0000);
        laserStroke.addVertex(600, 800, 1, 0xFF0000);
        laserStroke.x = 100;
        laserStroke.y = 100;
        addChild(laserStroke);
        laserStroke.visible = true; // set to false when running the actual game

        var i:int = 0;
        var creepBox:Rectangle = new Rectangle(30, 30, 50, 50); // Get this bounding box from your "real" creeps
        for ( i = 0; i < 100; i++ )
        {
            var creepStroke:Stroke = new Stroke();
            creepStroke.fromBounds(creepBox);
            creepStroke.alignPivot();
            creepStroke.x = ((i/10* 60)) ;
            creepStroke.y = ((i%10)*60) + 160;
            addChild(creepStroke);
            creepStroke.visible = true; // set to false when running the actual game
            creepStrokes.push(creepStroke);

            creepSpeed.push(2); // start speed in x for example
        }

        hitPointVector = new Vector.<Point>(100, true);
        for ( i = 0; i < 100; i++ )
            hitPointVector[i] = new Point();

        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }

    private function enterFrameHandler( event:Event ):void
    {
        var i:int = 0;
        // Move objects
        for ( i = 0; i < creepStrokes.length; i++ )
        {
            if ( creepStrokes[i].x < 0 || creepStrokes[i].x > 1000)
                creepSpeed[i] = creepSpeed[i] * -1;

            creepStrokes[i].x += creepSpeed[i];
        }
        // perfrom collisions
        for ( i = 0; i < creepStrokes.length; i++ )
        {
            if ( Stroke.strokeCollideTest(laserStroke, creepStrokes[i], hitPoint, hitPointVector) )
            { // hitPoint is one of all hits, use hitPointVector if you want to find all hits.
                creepStrokes[i].rotation += 0.2;
            }
        }
    }

    private function disposeGraphic(g:Graphic) : void
    {
        removeChild(g);
        g.dispose();
    }

}

}

makc commented 10 years ago

I have added a method to Stroke called "fromBounds" that creates a bounding box in a Stroke

why is this not pull request?

IonSwitz commented 10 years ago

Should it be?

I'm not super-great at how GitHub projects usually run, but what would be the benefit of a pull request, when it is completely new functionality?