The Great Code Sharing Thread

90 posts (showing 1-20)
GroZZleR

Market Level 7Community Level 10
1594 posts
posted 2011-03-27T20:33:29-07:00 | edited 2011-07-28T17:30:36-07:00
GroZZleR

Market Level 7Community Level 10
1594 posts

Easy Sprite Camera

If you're using the Flash display list, this is a super easy to use camera that'll allow everything from panning, zooming and rotating with ease.  Just add the Camera (it's a sprite) to your main container and manipulate the camera like any other sprite to affect the entire scene.

It's based off the old VCam code.

[as3]

public class Camera extends Sprite
{
    protected var _stageWidth : Number;
    protected var _stageHeight : Number;
   
    protected var _cameraWidth : Number;
    protected var _cameraHeight : Number;       
   
    public function Camera(stageWidth : Number = 640, stageHeight : Number = 480)
    {
        this.graphics.lineStyle(2, 0x00FFFFFF);
        this.graphics.drawRect(0, 0, stageWidth, stageHeight);
        this.visible = false;
       
        this.width = stageWidth;
        this.height = stageHeight;
       
        this.scaleX = 1;
        this.scaleY = 1;
       
        _cameraWidth = stageWidth;
        _cameraHeight = stageHeight;
       
        _stageWidth = stageWidth;
        _stageHeight = stageHeight;
    }
   
    public function update() : void
    {           
        if (parent == null || stage == null)
            return;
           
        var width : Number = _cameraWidth * scaleX;
        var height : Number = _cameraHeight * scaleY;
       
        var ratioX : Number = _stageHeight / height;
        var ratioY : Number = _stageWidth / width;
       
        var matrix : Matrix = this.transform.matrix.clone();
        matrix.invert();
        matrix.scale(scaleX, scaleY);
        matrix.translate(width / 2, height / 2);
        matrix.scale(ratioX, ratioY);
       
        parent.transform.matrix = matrix;
        parent.transform.colorTransform = this.transform.colorTransform;
        parent.filters = this.filters;   
    }
}

[/as3]

Example

[as3]

// add it to your main container:

camera = new Camera();

_container.addChild(camera);

// later on manipulate the camera

camera.x = player.x; // focus the camera on the player

camera.y = player.y;

camera.update();

[/as3]

posted 2011-03-27T20:33:38-07:00 | edited 2011-03-27T20:48:13-07:00
Isu the Mule

Market Level 0Community Level 4
340 posts

I've got a question. Inevitably people are going to find bugs or add improvements to existing code. Is it better to re-post the code, or re-edit the original post?

Also, there are a lot of old posts with specific classes like this one, it wouldn't hurt to put some of those in the table of contents as well.

This is good, I'll go through some of my common classes and see if anything's polished enough to put up here later.

posted 2011-03-27T21:22:07-07:00
GroZZleR

Market Level 7Community Level 10
1594 posts

Good question... if the original poster doesn't edit the post, a fix might go unnoticed by someone using the code.  On the flip side, reposting a whole post just to fix a simple math error or something seems overkill.

I don't know.

posted 2011-03-27T21:41:52-07:00
Porter

Market Level 4Community Level 0
3406 posts

I would definitely suggest editing the original post. If anyone does post again with a fix, I'll do my best to check in and edit people's post for you.

Another addition you may look into adding, is to have a sample SWF showing what the code does. For instance, your camera would be nice to see in action with a simple background, and an object moving around. Nothing fancy, just enough to show the code in action, if applicable.

posted 2011-03-27T22:01:41-07:00 | edited 2011-03-27T22:02:33-07:00
pepperpunk

Market Level 3Community Level 11
2401 posts

Brilliant idea for a thread. I'll add a common staple that most of us probably use already:

Random whole number between (and including) any 2 values

 

[as3]
public static function randomNumber(low:Number, high:Number):Number
        {
        return Math.floor(Math.random() * (1+high-low)) + low;
        }[/as3]

Example of usage, generating and displaying a number between 1 and 6 inclusive:

 

[as3]
var d6_roll:Number;
d6_roll = randomNumber(1,6);
trace(d6_roll);[/as3]
posted 2011-03-28T00:21:49-07:00 | edited 2011-03-28T00:26:10-07:00
TheAwsomeOpossum

Market Level 0Community Level 4
334 posts

On Mar 27, 2011, GroZZleR said:

Easy Sprite Camera

...

Very nice, I think I will be using this some time =D.

posted 2011-03-29T01:43:08-07:00 | edited 2011-03-29T02:32:01-07:00
4urentertainment

Market Level 5Community Level 8
1676 posts

On Mar 28, 2011, pepperpunk said:

Brilliant idea for a thread. I'll add a common staple that most of us probably use already:

Random whole number between (and including) any 2 values

Why use Math.floor though? If I'm not mistaken, that always rounds *down*. Doesn't really make much of a difference, but I tend to use Math.round in these cases, just to round to whichever is closer.

posted 2011-03-29T16:19:09-07:00
Vega

Market Level 0Community Level 2
108 posts

Concerning Math.floor:

http://scriptplayground.com/tutorials/as/Generate-random-number-in-ActionScript-3/

 

Reason is if you put in 0 as low and 9 as high, that's actually 10 values. So therefore you need the (high - low + 1).

Regarding chance.
Math.random produces a number equal or greater than 0 and less than 1 (0 >= n < 1). So if you devide that range in 10 parts you get:
1st: 0 - 0.09999..
2nd: 0.1 - 0.19999..
3rd: 0.2 - 0.29999..
..
10th: 0.9 - 0.99999..

Now multiply by 10. If you now do a round() the first value will only be picked in the range 0 -> 0.49999.., while the second value will be picked in the range 0.5 - 1.49999... Same with last, it will only be picked in the range 9.5 - 9.9999..
Therefore you need the floor().

posted 2011-03-29T16:27:51-07:00 | edited 2011-03-29T16:28:05-07:00
JohnBlackburne

Market Level 3Community Level 10
2189 posts

I just cast the float result into an int, as that's presumably what you want to store discrete values such as dice rolls. Anyway, here's one from me:

[as3]

import flash.geom.ColorTransform;

 class Colourise extends ColorTransform {

    function Colourise(iTint:uint = 0xffffff, iTint2:uint = 0x000000, fAMult:Number = 1) {

        var fRed:Number, fGreen:Number, fBlue:Number;

        // white to iTint, black to iTint2

        fRed = ((iTint >>> 16) & 0xff) / 255;

        fGreen = ((iTint >>>  8) & 0xff) / 255;

        fBlue = (iTint          & 0xff) / 255;

        redOffset = (iTint2 >>> 16) & 0xff;

        greenOffset = (iTint2 >>>  8) & 0xff;

        blueOffset = iTint2          & 0xff

        redMultiplier = fRed   - redOffset   / 255;

        greenMultiplier = fGreen - greenOffset / 255;

        blueMultiplier = fBlue  - blueOffset  / 255;

        alphaMultiplier = fAMult;

        alphaOffset = 0;

    }

}

[/as3]

 

I use it like this

[as3]

    dat = datSource.clone();

    dat.colorTransform(dat.rect, new Colourise(Col.cLightGrey, Col.cRed));

[/as3]

datSource is a monochrome piece of art, i.e. one with only white, black and colours inbetween. It is copied and recoloured so white becomes light grey, black becomes red (both RGB values, e.g. 0xcfcfcf, 0xff0000). Or it can be assigned to a Bitmap's transform.colorTransform property, e.g.

[as3]

    bmp = new Bitmap(dataSource);

    bmp.transform.colorTransform = new Colourise(Col.cLightGrey, Col.cRed);

[/as3]

, which lets you change the colour in the future just by reusing the last line with different colours.

posted 2011-03-29T16:40:18-07:00 | edited 2011-03-29T17:13:38-07:00
pjbaron

Market Level 8Community Level 13
4001 posts

This is one I keep coming back to time & time again... turn to face a given angle in the shortest arc direction.

[as3]

/// @return: sign of _v, or zero if _v is zero

public static function sgn0(_v : Number):Number

{

    if (_v < 0) return -1;

    if (_v == 0) return 0;

    return 1;

}

 

/// turn one unit towards the desired facing angle in the shortest direction around a circle

/// @param: _current the current facing angle in degrees (integer)

/// @param: _desired the desired facing angle in degrees

/// @param: _total the total number of angles in a circle (optional, default 360)

public static function turnToFace(_current : int, _desired : int, _total : int = 360):int

{

    var t : int;

    var d : int = _desired - _current;

    if (Math.abs(d) <= _total * .5)

        t = _current + sgn0(d);

    else

        t = _current - sgn0(d);

    if (t >= _total)

        return t - _total;

    if (t < 0)

        return t + _total;

    return t;

}

[/as3]

posted 2011-03-30T05:30:22-07:00
Alekhine

Market Level 2Community Level 5
488 posts

Basic pathfinding with agro range

I thought, I would, for the first time since I joined this site, contribute with something useful.

The below code, is for basic pathfinding between two movieclips, it has smooth and changeable speed, rotation and agro range


public function doFollow(follower:MovieClip, target:MovieClip) {
    
    //calculate distance between follower and target
    var distanceX:Number = target.x-follower.x;
    var distanceY:Number = target.y-follower.y;
    
    //get total distance as one number
    var distanceTotal = Math.sqrt(distanceX*distanceX+distanceY*distanceY);
    
    //check if target is within agro range
    if(distanceTotal <= agroRange){
        //calculate how much to move
        var moveDistanceX:Number = turnRate*distanceX/distanceTotal;
        var moveDistanceY:Number = turnRate*distanceY/distanceTotal;
        
        //increase current speed
        moveX += moveDistanceX;
        moveY += moveDistanceY;
        
        //get total move distance
        var totalmove = Math.sqrt(moveX*moveX+moveY*moveY);
        
        //apply easing
        moveX = speed*moveX/totalmove;
        moveY = speed*moveY/totalmove;
        
        //move follower
        follower.x += moveX;
        follower.y += moveY;
        
        //rotate follower toward target
        follower.rotation = 180*Math.atan2(moveY, moveX)/Math.PI;
    }
}

Example of use:


function mainconstructor() {
var newmovieclip:LibraryMovieclip = new LibraryMovieclip
var secondnewmovieclip:LibraryMovieclip2 = new LibraryMovieclip2
//declaring 2 movieclips from the library

newmovieclip.x = 200
newmovieclip.y = 200
addChild(newmovieclip)
//place first mc on stage
secondnewmovieclip.x = 0
secondnewmovieclip.y = 0
addChild(secondnewmovieclip)
//place second mc on stage

doFollow(secondnewmovieclip, newmovieclip)
//order second mc to follow first mc,note: this command should ideally be placed in an enter frame function

}

posted 2011-03-30T15:55:16-07:00
Luiz

Market Level 4Community Level 7
287 posts

Here's some .jsfl that might come in handy when optimizing a file:

CountPoints.jsfl:

http://pastebin.com/bzU08bcW

It counts the total number of points in all shapes in the project file, and returns the shape with the largest number of points. It's .jsfl, so you should open and run it inside the IDE.

posted 2011-03-30T16:19:29-07:00
GroZZleR

Market Level 7Community Level 10
1594 posts

Table of contents updated.  Keep up the good work everyone.

posted 2011-03-30T19:25:13-07:00
Daniel Menezes

Market Level 1Community Level 4
408 posts

This is trivial, but often needed and being the "pocket-calculator-maths-guy" I am, I keep forgetting how to do it properly.

Get a value between 0 and 1 along the sine curve (e.g. for smoothly bobbing powerups or blinking effects):

Math.sin() returns a value between -1 and 1, so it's: 

[as3]
( 1 + Math.sin( getTimer() * animationSpeed ) ) / 2;[/as3]

Where animationSpeed is a custom variable.

posted 2011-04-04T10:55:38-07:00 | edited 2011-04-04T10:56:26-07:00
echeese

Market Level 0Community Level 6
180 posts

Clamp a number between two others

[as3]
function clamp(x:Number, min:Number, max:Number):Number
{
return x<min?min:x>max?max:x;
}

//For example, to constrain a number between 10 and 20
clamp(5, 10, 20) //returns 10
clamp(15, 10, 20) //returns 15
clamp(25, 10, 20) //returns 20[/as3]
posted 2011-04-05T08:56:05-07:00 | edited 2011-04-05T08:57:41-07:00
JohnBlackburne

Market Level 3Community Level 10
2189 posts

I would point out that a function like that can expensive: the function calling overhead in Flash is very high, so using short functions like that excessively can exact a real performance penalty. Accessors/getters/setters are the usual culprit but something like that is as problematic if it's overused. I would just inline it

You could instead use

[as3]Math.max(min, Math.min(max, x));[/as3]

I don't know whether it or 

[as3]x<min?min:x>max?max:x[/as3]

would be faster: the builtin math functions are usually pretty fast as they're optimised to have little overhead.

posted 2011-04-05T20:58:51-07:00
Isu the Mule

Market Level 0Community Level 4
340 posts

I did some quick performance tests. the clamp function is twice as fast.

posted 2011-04-05T21:31:21-07:00 | edited 2011-04-05T21:33:36-07:00
echeese

Market Level 0Community Level 6
180 posts

In haxe, you can set functions to be inlined. That is one of the functions I have inlined.

posted 2011-04-05T21:53:36-07:00
JohnBlackburne

Market Level 3Community Level 10
2189 posts

I did some tests to confirm my thoughts:

http://wonderfl.net/c/jY9M

Time for a million function calls: 112 ms.

Time for a million inline versions: 95 ms

This is less of an improvement than I'd expect; it may be the overhead of the ?: operations are high relative to the cost of the function calls. But it's still the case that it's slower calling a function, which in this case is equivalent to a line of code so the function saves no space either.

posted 2011-04-05T22:00:58-07:00