Making a flash country map - actionscript-3

Hello I want to make a flash map of Europe where when you mouse over or out of each country something will happen, like changing the color of the country.
See this image
If I roll over Norway and then Sweden, Sweden will not be set to blue because Norway's bounding box is on top of Sweden, so I have to go a bit lower to roll over Sweden where it does not instersect with Norway.
Is there a better way to achieve the same functionality? Like using Bitmap pixels.
I have a sprite sheet of all cointries in png format. I embed this sprite sheet and than create Sprite AS3 class that uses copyPixels() to copy from the sprite sheet to innet variable BitmapData.
Here is my class
public class Country extends Sprite
{
private var newBitmap:Bitmap;
private var tintColor:Color = new Color();
public function Country(bitmapData:BitmapData)
{
newBitmap = new Bitmap(bitmapData);
tintColor.setTint (0x0000ff, 0.6);
this.useHandCursor = true;
this.buttonMode = true;
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
addChild(newBitmap);
addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
}
private function onMouseOver(e:MouseEvent = null):void
{
newBitmap.transform.colorTransform = tintColor;
}
private function onMouseOut(e:MouseEvent = null):void
{
newBitmap.transform.colorTransform = new ColorTransform();
}
}
bitmapData is created at runtime using copyPixels() like this
var countiresArray:Array = Resources.allCointriesJSON["frames"];
var newX:Number = countiresArray[i]["frame"]["x"];
var newY:Number = countiresArray[i]["frame"]["y"];
var newW:Number = countiresArray[i]["frame"]["w"];
var newH:Number = countiresArray[i]["frame"]["h"];
bitmapData .copyPixels(Resources.allCountries.bitmapData, new Rectangle(newX, newY, newW, newH), new Point(0, 0));
where newX,NewY, newW and newH are taken from exported JSON file that is created when using TexturePacker

Without converting your country images to vectors, you will need to check the alpha values of pixels under the mouse to get accurate interactions. Luckily, someone's already written and open sourced a utility that should do the job: InteractivePNG.
You'll just need to put your bitmaps inside an InteractivePNG instance instead of a Sprite.

I had a similar problem but with an interactive object. The solution was to have a image that acted as a map for the clicks. This is a technique used in OpenGL for detecting clicks on 3d objects and scenes.
For example in your case, you'd have an image with all the countries. This image would not be loaded in the display list. Each country would have an exact different color. for example Sweden would be 0xff0000, Norway 0x00ff00, etc. Let's call this image colored-map.jpg
Then after clicking on the Europe-map.jpg, the one that the user sees, you'd check the mouse coordinates, and then go look in the colored-map.jpg to know the color of the clicked pixel. Then you'd know which country the user clicked, and could overlay the Norway.png.
This technique is way better in performance terms that having lots of PNGs in the display list. At any time you would only have the Europe-map.jpg, maybe 1 PNG of the selected country, and then the colored-map.jpg loaded into a Bitmap object. If you are targeting mobile performance optimization is a must.
Check this function. It's just as an example to get you going... it's not a full implementation.
var countriesArray = [{color:0xff0000, image:"Norway.png"},{color:0x00ff00, image:"Sweden.png"}];
public function checkPoint(mouseX,mouseY):String {
var testPixel:uint = coloredMap.bitmapData.getPixel(mouseX,mouseY);
for (var country in countriesArray) {
if( country.color == testPixel ) {
return country.image;
}
}
return null;
}

Related

Flash AS3: Typewriter effect with copyPixels

I'm making a Flash AS3 based game, and I'm building a custom font system. It works like this: a BitmapData class takes a PNG file from the library (FontSource), loops between every character in a given string and then gets its x, y, width and height inside the image from a function (getOffset), and then it uses copyPixels to draw the custom-font text.
Here's the code:
public function draw(str) {
var png = new FontSource(480, 32);
var offsets;
var char;
var rect;
var x;
var y;
this.lock();
for (var i = 0; i < str.length; i++) {
char = str.substr(i, 1);
offsets = getOffsets(char);
rect = new Rectangle(offsets[0], offsets[1], offsets[2], offsets[3]);
this.copyPixels(png, rect, new Point(x, y));
x += offsets[2];
}
this.unlock();
}
Now, the question here is: I'm building a typewriter effect class based on the ENTER_FRAME event; each new frame, a new character is added to a string. So, I wanted to ask which one of these approaches would do better related in a matter of performance:
1) Call draw() to redraw the whole BitmapData each frame.
2) Making an alpha mask and expand its width each frame.
3) Making separate Objects and adding them to stage each frame.
Thank you for your time.
As an alternative, you don't need to redraw the entire string. You can just draw more characters at its end. I'd implement this as follows: You give your bitmapped textfield a string it should draw per frame, once. It clears, then at each enter frame event it just adds 1 to the length of the string drawn, and draws only one single character. Just save more data in your class for this. For example:
public class BTF extends Sprite {
private var str:String;
private var source:FontSource; // set once!
private var bd:BitmapData; // the one that'll get drawn
private var lastIndex:int;
private var lastX:int; // coords to draw next symbol to
// assuming Y is always 0 - adjust per font
public function BTF(source:FontSource,width:int,height:int) {
this.source=source;
bd=new BitmapData(width,height,0x00808080,true); // check if I didn't mix up parameters
addChild(new Bitmap(bd)); // make it be drawn on your BTF
}
... // rest of class skipped
public function onEnterFrame(e:Event):void {
if (lastIndex>=str.length) return; // drawn all text already
var c:char=str.charAt(lastIndex++); // get next char to draw
var r:Rectangle=source.getOffsets(c); // you need to specify source for that - it's font that gives you bounds
bd.copyPixels(source.fontBitmapData,r,new Point(lastX,0)); // draw that char
lastX+=r.width; // move "cursor"
}

AS3 tracking and using coordinates of a rotated object

How does one track and use the coordinates of an object that is rotated on initialization?
Let's say I have a sword that is put on the stage in Main init(); and rotated (adjusted) so that it would look ok together with the character perspective. In another class however, I am making the sword rotate some more on a keypress timer event so to create a 'swing' animation.
All this is done through flashdevelop. I only used CS6 to create the symbols. And as this 'swing' is happening, I want to add another symbol onto the tip of the sword which is a collision point object. It's being added to the stage when the swing starts and removed after every swing. I want this object to follow the very tip of the sword, yet it seems like I can only achieve that it follows the coordinates of the original sword object, as if I hadn't initially modified the rotation of the said sword. I tried to implement GlobalToLocal() and LocalToGlobal() methods, but I don't think I fully understand what is happening with that.
I hope I'm being clear enough of what I'm trying to do. Thank you. This is the relevant code in question. The code is as was before I tried the two mentioned methods and the issue currently is exactly as described before that. Do I want any of those methods or am I just doing something else wrong?
Main initialization:
sword = new Sword();
sword.x = 53;
sword.y = 90;
addChild(sword);
sword.rotationZ = -150;
sword.rotationY = 25;
sword.rotationX = -15;
Coll_Point = new coll_point();
The class that deals with the swing has a method like this:
private function SwingTime(event:Event):void
{
Main.Coll_Point.x = Main.sword.x + Main.sword.width;
Main.Coll_Point.y = Main.sword.y + Main.sword.height;
Main.MazeNr1.addChild(Main.Coll_Point);
if (Main.sword.rotationZ > -330)
Main.sword.rotationZ -= 20;
if (Main.sword.rotationX < 15)
Main.sword.rotationX += 10;
if ((Main.sword.rotationZ == -330) && (Main.sword.rotationX == 15))
{
SwingTimer.stop();
SwingBckTimer.start();
}
}
Edit:
A more holistic version of the code:
public class Main extends MovieClip
{
public static var from_point:Point = null;
public static var to_point:Point = new Point();
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
// Puts everything on the stage here.
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
PlayerInst = new Dorf();
PlayerInst.x = 45;
PlayerInst.y = 51;
addChild(PlayerInst);
sword = new Sword();
sword.x = 53;
sword.y = 90;
sword.rotationZ = -150;
sword.rotationY = 25;
sword.rotationX = -15;
from_point = new Point (Main.sword.width, Main.sword.height);
to_point = sword.localToGlobal(from_point);
addChild(sword);
swordBD = new BitmapData(32, 32, true, 0x0000000000);
swordBD.draw(sword);
Coll_Point = new coll_point();
Coll_PointBD = new BitmapData(2, 2, true, 0x0000000000);
Coll_PointBD.draw(Coll_Point);
}
}
This is how the Main looks like and literally every single object instantiation is added onto the stage this way. Including collision points, background, characters, gradient fills of line of sight radius, etc. And the relevant symbol class goes somewhat like this:
public class Creature extends MovieClip
{
protected var Swing:Boolean;
private var SwingTimer:Timer = new Timer (5, 0);
private var SwingBckTimer:Timer = new Timer (150, 1);
// Constructor.
public function Creature()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
// Initializer.
private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
SwingTimer.addEventListener(TimerEvent.TIMER, SwingTime);
SwingBckTimer.addEventListener(TimerEvent.TIMER, SwingBack);
}
private function SwingAction():void
{
if (Swing == true)
{
SwingTimer.start();
}
}
private function SwingTime(event:Event):void
{
Main.Coll_Point.x = Main.sword.localToGlobal(Main.from_point).x;
Main.Coll_Point.y = Main.sword.localToGlobal(Main.from_point).y;
Main.sword.addChild(Main.Coll_Point);
trace(Main.Coll_Point.x);
trace(Main.Coll_Point.y);
if (Main.sword.rotationZ > -330)
Main.sword.rotationZ -= 20;
if (Main.sword.rotationX < 15)
Main.sword.rotationX += 10;
if ((Main.sword.rotationZ == -330) && (Main.sword.rotationX == 15))
{
SwingTimer.stop();
SwingBckTimer.start();
}
}
private function SwingBack(event:Event):void
{
Main.sword.rotationZ = -150;
Main.sword.rotationX = -15;
//Main.MazeNr1.removeChild(Main.Coll_Point);
}
There is also a rather long update(); function that animates and moves every single object that needs moving.
I think your problem might be in
Main.Coll_Point.x = Main.sword.x + Main.sword.width;
Main.Coll_Point.y = Main.sword.y + Main.sword.height;
Coll_Point expects global coordinates.
The parts + Main.sword.width and + Main.sword.height only work as expected if the sword is not rotated so that height is aligned with the y-axis and width with the x-axis.
You should use localToGlobal() on the position that is local to Main.sword (
Main.sword.width, Main.sword.height) to get the global position that represents the swords rotated tip before you add it as a child.
There are two ways you can approach this (you seem to have somewhat combined both). You can either
Add the Coll_Point as a child to something above the sword in hierarchy (Stage, MazeNr1, ...) and update the position manually every timer callback. You would have to recalculate the position everytime, so take the localToGlobal() from init to your timer function. It won't update if it doesn't get called.
For that you should have this kind of code in the timer callback:
var local:Point = new Point(Main.sword.width, Main.sword.height);
var global:Point = Main.sword.localToGlobal(local);
Main.Coll_Point.x = global.x;
Main.Coll_Point.y = global.y;
Add the point as a child to the sword. This might be a better approach as then the position will be updated automatically. What I did not remember before was that you then give the coordinates in "local" form, so do not use localToGlobal()
Run this once where you create the Collision_Point:
Coll_Point.x = <your x offset>;
Coll_Point.y = <your y offset>;
Main.sword.attachChild(Coll_Point);
Instead of sword height and width you might want to try something like -height and width/2.
Here is a quick (and not the prettiest) picture to demonstrate the problem. Local space is rotated with the object:
The only thing I can imagine to help you with this problem is to have your collision object have the same registration point as the sword. What I mean is that the orientation points should match, and the collision graphic should be moved inside of the sprite so that it matches the position of the top of the sword.
This way you can put the collision object at the very same location of the sword and apply the very same rotation. This way it will move along with the top of the sword and still have hitTest working properly.
I cannot imagine any other way to figure this out as any code will get bounds and positions. But the real thing that matters is the registration point and the top of the sword, which is a graphic thing and cannot be dealt with coding.
I hope you can imagine what I mean - if now, just say and I will provide an image for you :)

The most lightweight button implementation in actionscript 3.0 [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Since button is one of the most popular GUI components this question becomes hot when we talk about memory usage. Especially when you have tons of buttons in your application.
So how you can implement a button that uses minimum CPU and memory resources and yes, acts like normal button with mouse up, down and hand pointer behavior implemented. Label text is also required.
If you want to have tonnes of buttons with text and graphics, using the least amount of RAM and processing power, you should be using Bitmaps.
This gets a lot more complicated and involves your own preparation of the following:
A font in the form of a sprite sheet.
Classes that manage rendering text onto a Bitmap using that sprite sheet.
Bitmaps don't respond to MouseEvents, so you'll need to architect your own system for managing mouse input on the Bitmaps.
Firstly, lets take a look at the base memory consumption for some of the DisplayObjects that you would think we would be best using. This is our testing method:
function ram(type:Class):void
{
trace(getSize(new type()));
}
And this is the test:
ram(Sprite); // 408
ram(Shape); // 236
ram(TextField); // 1316
In your case, drawing 1000 buttons would result in over 1,724,000 bytes of memory being used.
Now let's look at what we will be using:
1x Bitmap acting as a Canvas that holds all buttons: 236 bytes.
1x BitmapData representing the initial state of every button.
1x BitmapData representing the rollover state of every button.
1x BitmapData storing our text as a sprite sheet for use by all buttons.
Each BitmapData will be quite large in memory consumption, and varies greatly depending on its content. But the trick here is that we only use one and refer to its content for every button that we want to draw.
I've set up a small amount of code to get you started. You still need to implement a click manager which loops over all the buttons and works out which is most relevant to trigger a click, as well as rendering the text on the buttons.
Here's the Button class:
public class BitmapButton
{
private var _text:String;
private var _position:Point = new Point();
public function BitmapButton(text:String)
{
_text = text;
}
public function render(canvas:BitmapData, font:BitmapData, state:BitmapData):void
{
canvas.copyPixels(state, state.rect, _position);
// Use font argument to render text.
// For you to implement.
}
public function get position():Point{ return _position; }
}
And here's the class that will manage rendering those buttons:
public class ButtonCanvas extends Bitmap
{
private var _fontSprite:BitmapData;
private var _baseState:BitmapData = new BitmapData(100, 30, false, 0xFF0000);
private var _overState:BitmapData = new BitmapData(100, 30, false, 0x00FF00);
private var _buttons:Vector.<BitmapButton> = new <BitmapButton>[];
private var _checkRect:Rectangle = new Rectangle();
public function ButtonCanvas(width:int, height:int)
{
bitmapData = new BitmapData(width, height, true, 0x00000000);
// Replace with actual loaded sprite sheet.
_fontSprite = new BitmapData(1, 1);
}
public function add(button:BitmapButton):void
{
_buttons.push(button);
}
public function render():void
{
if(stage === null) return;
bitmapData.lock();
for each(var i:BitmapButton in _buttons)
{
_checkRect.x = i.position.x;
_checkRect.y = i.position.y;
_checkRect.width = _baseState.width;
_checkRect.height = _baseState.height;
if(_checkRect.contains(mouseX, mouseY))
{
// Use roll over style.
// Need to implement depth check so you can't roll over buttons
// that fall behind others.
i.render(bitmapData, _fontSprite, _overState);
}
else
{
i.render(bitmapData, _fontSprite, _baseState);
}
}
bitmapData.unlock();
}
public function get buttons():Vector.<BitmapButton>{ return _buttons; }
}
And a small test:
var canvas:ButtonCanvas = new ButtonCanvas(stage.stageWidth, stage.stageHeight);
addChild(canvas);
for(var i:int = 0; i < 20; i++)
{
var button:BitmapButton = new BitmapButton("Hello");
button.position.x = Math.random() * stage.stageWidth;
button.position.y = Math.random() * stage.stageHeight;
canvas.add(button);
}
stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
function update(e:MouseEvent):void
{
canvas.render();
}
canvas.render();
Now that you've read all of that, I'll point out that it's really unlikely you need to anywhere near this extreme, unless you have some type of game that revolves around buttons and buttons are actually particles that get generated every frame in the 100's. Using a standard Sprite + TextField is perfectly fine in almost all cases.
One of the traditional patterns is using Sprite + TextField
Adobe recommends using Shape instead of Sprite (when it makes sense):
a Sprite object is a display object container, whereas a Shape object is not. For this reason, Shape objects consume less memory than Sprite objects that contain the same graphics.
It would be great to use Shape, and we can do it, but we can not add TextField on it.
Now lets look at TextField inheritance chain:
TextField: InteractiveObject -> DisplayObject -> EventDispatcher -> Object
We can observe that a TextField object is much lighter than a Sprite object - wrong. Using only TextField will be lighter than using TextField + Sprite. I came up with this decision:
import flash.events.MouseEvent;
import flash.filters.BevelFilter;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.Mouse;
import flash.ui.MouseCursor;
public class Button extends TextField
{
private static const MOUSE_UP:Array =
[new BevelFilter(2, 45, 0xEEEEEE, .7, 0x444444, .7, 1, 1)];
private static const MOUSE_DOWN:Array =
[new BevelFilter(2, 225, 0xEEEEEE, .7, 0x444444, .7, 1, 1)];
private static const TEXT_FORMAT:TextFormat =
new TextFormat('Verdana', 12, 0xDDDDDD,
null, null, null, null, null, 'center');
public function Button(label:String, color:int = 0x166488)
{
width = 80;
height = 20;
background = true;
backgroundColor = color;
selectable = false;
defaultTextFormat = TEXT_FORMAT;
text = label;
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
addEventListener(MouseEvent.ROLL_OVER, onMouseRollOver);
addEventListener(MouseEvent.ROLL_OUT, onMouseRollOut);
onMouseUp();
}
private function onMouseRollOut(e:MouseEvent):void
{
Mouse.cursor = MouseCursor.AUTO;
}
private function onMouseRollOver(e:MouseEvent):void
{
Mouse.cursor = MouseCursor.BUTTON;
}
private function onMouseDown(e:MouseEvent):void
{
filters = MOUSE_DOWN;
}
private function onMouseUp(e:MouseEvent = null):void
{
filters = MOUSE_UP;
}
//kill method
}
This code draws nice lightweight button BUT I can not adjust vertical position of a text label so height of this button depends of font-size. Another issue is that I cann't move the text label a bit down-right when somebody clicks it.
Any ideas will be appreciated.
We can observe that a TextField object is much lighter than a Sprite object. That's completely incorrect. A Sprite uses 408 bytes in memory whereas a TextField uses 1316
Yes TextField will consume way more memory.
I would create the label text in a graphics program and create a sprite menu class.
TextField is not really lightweight but a pretty powerful class. If you want user input then TextField is the way to go.
Avoid any of the buttons built into the Flash library and just start simple and build functionality on the sprite class.
If you really want to optimize your interface, reduce the event handlers and any sort of transparency. This might just be good Flash advice in general but often overlooked.
Make a function that gets called every frame, tick();, think();, update(); something like this. Add a single event handler to the main class and within that call your update() function within the menu elements.
Adding a dozen event handlers to your menu elements is not only cumbersome but unsightly.
I would venture to say a sprite with the buttonMode property set to true for the "hand pointer" and then functions to handle the ROLL_OVER and ROLL_OUT MouseEvents.

AS3/FLEX - how to convert Sprite graphics into bytes

I wrote application that lets people paint together via internet (using Adobe cirrus). Everything works great but when for example I run my application and paint something before my friend connects, he dont see that what I have painted. So I'm looking for the method, that would let me convert my canvas into something(object) that it is possible to send by internet (I cant send whole Sprite, it's not possible to copy its graphics on the friend's application, it's null).
So let's get this clear. The main question is: How to convert graphic's of Sprite into object, that would let me convert it back to Sprite and copy its canvas.
ANSWER:
I used DisplayConverter library from "www.Flextras.com" post with his mod to convert Sprite to BitmapData and then to ByteArray and it works. I couldn't receive BitmapData on the friend's app, but It worked with ByteArray.
Sprite -> BitmapData -> ByteArray;
ByteArray -> BitmapData -> Sprite;
//TO SEND
var bitmapdata:BitmapData = DisplayConverter.spriteToBitmapData(palette);
var bytearr:ByteArray = bitmapdata.getPixels(bitmapdata.rect);
//TO RECEIVE
var bmd:BitmapData = new BitmapData(530,430);
bmd.setPixels(bmd.rect, bytearr);
mysprite.graphics.beginBitmapFill(bmd);
mysprite.graphics.drawRect(0,0,530,430);
mysprite.graphics.endFill();
Hope this will help someone
I think you want to convert your Canvas into a BitMap or BitMapData (and back). A Flex Canvas extends Sprite, so you can use a library like this one. To copy the relevant code, this will convert a Sprite to a BitMap:
public static function spriteToBitmap(sprite:Sprite, smoothing:Boolean = false):Bitmap
{
var bitmapData:BitmapData = new BitmapData(sprite.width, sprite.height, true, 0x00FFFFFF);
bitmapData.draw(sprite);
return new Bitmap(bitmapData, "auto", smoothing);
} // END FUNCTION spriteToBitmap
This will convert a Bit Map to a Sprite:
public static function bitmapToSprite(bitmap:Bitmap, smoothing:Boolean = false):Sprite
{
var sprite:Sprite = new Sprite();
sprite.addChild( new Bitmap(bitmap.bitmapData.clone(), "auto", smoothing) );
return sprite;
} // END FUNCTION bitmapToSprite
In my own development, I have a mod to this library, which allows me to get the BitMapData instead of an actual BitMap. So, this will turn a Sprite into BitMapData:
public static function spriteToBitmapData(sprite:Sprite):BitmapData
{
var bitmapData:BitmapData = new BitmapData(sprite.width, sprite.height, true, 0x00FFFFFF);
bitmapData.draw(sprite);
return bitmapData;
} // END FUNCTION spriteToBitmapData
This will take BitMapData and turn it back into a Sprite:
public static function bitmapDataToSprite(bitmapData:BitmapData, smoothing:Boolean = false):Sprite
{
var sprite:Sprite = new Sprite();
sprite.addChild( new Bitmap(bitmapData.clone(), "auto", smoothing) );
return sprite;
} // END FUNCTION bitmapToSprite
You do want to keep in mind that when converting the BitMap or BitMapData back into a Sprite you will probably not be able to cast it as a Canvas. For information on sending BitMapData to a server; look at this question.
A better approach is, instead of going directly to pixels, have the user gestures create data, then reflect that data as a drawing on your canvas. Transmit the same data to the other user and he/she will get the same drawing.

How to read data from shape/graphics object

I am wondering if it is possible to get the data that is stored in a shape/graphics object in flash using actionscript 3?
In my project I would like to be able to draw a shape and then read all the points in that shape into my script. The reason for that is that I need go generate lines from those points that I later can use to check if my characters velocity intersects with any of them.
You can read all parts of Shape.
New feature added to Flash Player 11.6 and AIR 3.6:
flash.display.Grapics.readGraphicsData()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html#readGraphicsData%28%29
Example:
var s :Shape = new Shape();
s.graphics.lineStyle(2, 0xFF0000);
s.graphics.drawCircle(0, 0, 50)
var gd:Vector.<IGraphicsData> = s.graphics.readGraphicsData(false);
var copy_of_s :Shape = new Shape();
copy_of_s.graphics.drawGraphicsData(gd);
addChild(copy_of_s);
To use the new version, you have to update playerglobal.swc
http://www.adobe.com/support/flashplayer/downloads.html
You cannot read the shape info once it's drawn. But if you are drawing it, you can store the info at the time of drawing itself and use it later.
OK, looks like its not possible then, to bad.
I am doing a 2d topdown racing game, and I wanted to generate lines along the walls of the track and check the players velocity against thouse lines. That way I would be able to implement some basic collision response by reflection the players velocity around the normal of the line that it collides with and make it bounce off walls. Does anyone have any good ideas about how to get the same type of collision behavior without the actual lines?
Is it possible to overload the graphics object in flash somehow so that when I draw something it is recorded? Or does the flash IDE not use the Graphics drawing api?
Regards
You can not instantiate or subclass Graphics class. But you can use you own custom graphics class.public class CustomGraphics extends Object{
private static const CLEAR = -1;
private static const MOVETO = 0;
private static const LINETO = 1;
...
...
private var _graphics:Graphics;
private var _actions:Array;
public function CustomGraphics(g:Graphics):void {
_graphics = g;
_actions = new Array();
}
private function recordAction(obj:Object):void {
if (obj.action == -1) {
_actions = null;
_actions = new Array();
return;
}
_actions.push(obj);
}
public function moveTo(x:number, y:Number):void {
g.moveTo(x, y);
recordAction({action:MOVETO, X:x, Y:y});
}
...
...
public function get actions():Array {
return _actions;
}
} Now whenever you want to draw something then you can use CustomGraphics. var cg:CustomGraphics = new CustomGraphics(someDisplacyObject.graphics);
cg.moveTo(0, 0);
cg.drawRect(0, 0, 10,, 200);
...
a:Array = cg.actions;