Sunday, November 24, 2013

Next Game in Progress

My next game for Kongregate has been started. It's an "homage" (read: blatant rip-off) of a classic early 80's arcade game. You stay at the center and change gun direction to shoot enemies and incoming bullets. The original was in color, but I wanted to get a b&w vibe for my version.

Anyone want to venture a guess as to the original?

Friday, November 22, 2013

Arbitrary Center Bitmap Rotation in OpenFL

The problem: Bitmap objects (and display objects in general) are always rotated about the (0,0) relative coordinate when the .rotation member is set. This does not allow an object to pivot on the spot, but rather orbit its upper left point.

The solution: specify a coordinate pair to act as the center, perform a matrix rotate transformation on the point to determine where it would be after the rotation and then translate the Bitmap object to account for the difference.

The downside: the x and y location of the rotating bitmap class must be tracked separately from the x and y of the parent Bitmap, as they will be different. Also, an update method must be called to do the offset.

// import the usual suspects
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import openfl.Assets;
import flash.Lib;
import flash.geom.Matrix;

class Main extends Sprite {

    private var myTest:RotatingBitmap;

    public function new() {
        super();
        myTest = new RotatingBitmap(
                   Assets.getBitmapData("assets/circle.png")
        );
        myTest.xloc = 400;
        myTest.yloc = 400;
        myTest.xcenter=25;
        myTest.ycenter=25;

        removeEventListener (Event.ENTER_FRAME, this_onEnterFrame);

addEventListener (Event.ENTER_FRAME, this_onEnterFrame);

    }

    private function this_onEnterFrame(event.Event):Void {
        myTest.rotation+=15;
        myTest.update();
    }    

}

class RotatingBitmap extends Bitmap {
        // the intended location, since x and y will be changing
public var xloc:Float;
public var yloc:Float;
        // the center x,y of the rotation
public var xcenter:Float;
public var ycenter:Float;

public function new(asset:Dynamic) {
                // load the asset and add to the stage
super(asset);
flash.Lib.current.addChild(this);
}

public function update() {
                // here's where the magic happens

                // define the rotation parms
var mymatrix:Matrix = new Matrix();
mymatrix.rotate(Math.PI*(this.rotation)/180);

                // create a point to represent the center
var mypoint = new flash.geom.Point(xcenter,ycenter);

                // transform into a new point
var newpoint:flash.geom.Point = mymatrix.transformPoint(mypoint);
                // move the bitmap to the proper new location
                this.x = xloc-newpoint.x;
this.y = yloc-newpoint.y;

}

}

Here is a little example of the default rotation and a rotation set at the (nearly) center of the image.

Monday, November 18, 2013

Dungeons and Dragsters

Despite it being mid/late November, I present my October Challenge submission, D&D. You race through the dungeon and smash into the dragon at the end. Go fast enough and defeat him, or ... not. How did this particular mash-up come about? I started with a concept I had been noodling over for a while, but as the deadline crept closer and closer I jokingly said, "I should just abandon the whole thing and remake Activision Dragster for the 2600." Somewhere in between what I had already done and the game I played as a youngster, Dungeons and Dragsters was born.

It took my coworkers approximately 60 seconds to figure out how to break the driving to get max velocity. Time to rework some of that gearing code.