Changing class properties in AS3 - actionscript-3

Okay, so I've recently been trying to get my head properly around OOP in AS3. Right now I have a really simple scenario where I've got a class, Paddle, which draws a rectangle. In my document class I create two instances of the Paddle class, paddle1 and paddle2.
I've also created a property for my Paddle class which I want to change the colour of the rectangle that it draws. I want to be able to adjust this property from the main class. I know I could do this by passing in attributes when instantiating the class but it seems like a property would be a better way, and now I want to know if this is the right way of thinking or not.
main class:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Engine extends Sprite
{
private var paddle1:Paddle = new Paddle();
private var paddle2:Paddle = new Paddle();
public function Engine()
{
paddle1.x = 30;
paddle1.color = 0xFF00FF;
stage.addChild(paddle1);
paddle2.x = stage.stageWidth - 45;
paddle2.color = 0xFF0000;
stage.addChild(paddle2);
}
}
}
Paddle class:
package
{
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Graphics;
import flash.events.Event;
public class Paddle extends MovieClip
{
public var color:uint = 0xFFFFFF;
public function Paddle()
{
var child:Shape = new Shape();
child.graphics.beginFill(color);
child.graphics.drawRect(0, 260, 15, 80);
child.graphics.endFill();
addChild(child);
}
}
}
If changing the properties in this way is not the best way of doing things then of course say so. Otherwise, what am I doing wrong that it doesn't work? Seems like it's something to do with the order (by the time the main class changes the colour attribute, it's already created the rectangle and it's too late to change it?)
Thanks :D
EDIT: realised it might help to say what happens when I execute this code. Basically changing the color attribute from the Engine class doesn't change the colour of the rectangle and they both just stay white (FFFFFF)

The issue you're having is that when you do:
new Paddle();
Your constructor code is run. What this means is that the Rectangle has already been drawn with the color defined at the top of the class. You're then changing the color property after this, which as you can see has no effect.
I suggest you make a draw() function for your Paddle. It could accept a color and be used to draw the Rectangle. It might look like this:
public class Paddle extends MovieClip
{
private var _child:Shape;
public function Paddle()
{
_child = new Shape();
addChild(_child);
}
public function draw(color:uint):void
{
_child.graphics.clear();
_child.graphics.beginFill(color);
_child.graphics.drawRect(0, 260, 15, 80);
_child.graphics.endFill();
}
}
This way provides an advantage which is that you can modify the arguments of draw() to accept dimensions for your Rectangle or other elements that will affect the visuals. This will be cleaner and faster than having to add more properties to the class itself if you decide you want to do this.
You're then able to do this:
var paddle1:Paddle = new Paddle();
var paddle2:Paddle = new Paddle();
paddle1.draw(0xFF00FF);
paddle2.draw(0xFF0000);

What you might do is to allow the constructor to assign a color in addition to creating a setter for the color, having both calls subsequently drawing the paddle (which, by the way, could also be a simple flash.display.Shape):
Paddle.as:
package
{
//Imports
import flash.display.Sprite;
//Class
public class Paddle extends Sprite
{
//Constants
private static const DEFAULT_COLOR:uint = 0xFF0000;
//Properties
private var mColor:uint;
//Constructor
public function Paddle(color:uint = DEFAULT_COLOR)
{
mColor = color;
draw();
}
//Draw
private function draw():void
{
graphics.clear();
graphics.beginFill(mColor);
graphics.drawRect(0, 0, 15, 80);
graphics.endFill();
}
//Set Color
public function set color(value:uint):void
{
mColor = value;
draw();
}
//Get Color
public function get color():uint
{
return mColor;
}
}
}
so now you can create and position as many Paddle instances as you want, each having their own color setter:
Red Instance:
var paddleRed:Paddle = new Paddle();
paddleRed.y = 10;
addChild(paddleRed);
Green Instance:
var paddleGreen:Paddle = new Paddle(0x00FF00);
paddleGreen.y = 126;
addChild(paddleGreen);
Blue Instance:
var paddleBlue:Paddle = new Paddle();
paddleBlue.color = 0x00FF00;
paddleBlue.y = 260;
addChild(paddleBlue);

Why not do both? :D
public class Paddle extends MovieClip
{
private var color:uint;
private var rec:Shape;
public function Paddle(newColor:uint = 0xFFFFFF) // default color
{
color = newColor;
rec = new Shape();
drawShape();
addChild(rec);
}
public function drawShape()
{
child.graphics.clear();
child.graphics.beginFill(color);
child.graphics.drawRect(0, 260, 15, 80);
child.graphics.endFill();
}
public function setColor(newColor:uint)
{
color = newColor;
drawShape();
}
}

Related

How to create irregular shape mask

I'm trying to make a mask with bitmaps, i.e. has such a shape below.
Here my image mask:
All, in above image, is not white is transparent. So applying a mask she cuts a rectangle instead of this form. Is there any way to implement it? Primitives will hardly make such a mask.
Here my source:
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
[SWF(width="960", height="640", frameRate="60", backgroundColor="0x4a4137")]
public class Main extends Sprite
{
[Embed(source="jack.jpg")]
private var PhotoImg:Class;
[Embed(source="faceArea.png")]
private var FaceAreaImg:Class;
private var _imageBox:Sprite;
public function Main()
{
createMask();
}
private function createMask():void
{
var img:Bitmap = new PhotoImg();
_imageBox = new Sprite();
_imageBox.x = 0;
_imageBox.y = 0;
_imageBox.addChild(img);
addChild(_imageBox);
var faceArea:Bitmap = new FaceAreaImg();
faceArea.x = 50;
faceArea.y = 50;
addChild(faceArea);
_imageBox.mask = faceArea;
}
}
}
Hi skyboyIf you want to make masking with transparent bitmaps, you have to make the cacheAsBitmap property of the two DisplayObjects to true.
try:
_imageBox.cacheAsBitmap = true;
faceArea.cacheAsBitmap = true;

AS3 MouseEvent.CLICK Interaction on Different Indexes

I'm currently working through a AS3 game tutorial on Lynda.com and am coming across a problem with the MouseEvent.CLICK and child indexes. The game is a simple point and shoot, where the player must shoot all of the approaching enemies before they get too close. It works initially, however the custom cursor I added displays behind the enemies. However when I try and adjust the index (I've used the addChildAt function and moving the addChild(cursor) line of code below the enemy container initializer) the on click interaction, which is supposed to remove the enemy when clicked on, doesn't work.
My document class:
package {
import flash.display.*;
import flash.utils.*;
import flash.events.*;
import flash.ui.*;
public class Game extends MovieClip {
public var cursor:Cursor;
public var enemy:Enemy;
public var numberOfEnemies:uint;
public var enemyContainer:MovieClip;
public var enemyTimer:Timer;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, init);
Mouse.hide();
}
public function init(event:Event):void {
cursor = new Cursor;
addChild(cursor);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
numberOfEnemies = 10;
enemyTimer = new Timer(1000, numberOfEnemies);
enemyContainer = new MovieClip();
addChild(enemyContainer);
enemyTimer.addEventListener(TimerEvent.TIMER, createEnemies);
enemyTimer.start();
}
public function dragCursor(event:MouseEvent) {
cursor.x = this.mouseX;
cursor.y = this.mouseY;
}
public function createEnemies(event:TimerEvent):void {
enemy = new Enemy();
enemy.x = 25 + Math.random() * (stage.stageWidth - 75);
enemy.y = 25 + Math.random() * (stage.stageHeight - 75);
enemyContainer.addChild(enemy);
enemy.timerStart();
}
}
}
My enemy class:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.events.*;
public class Enemy extends MovieClip {
public var scaleObj:Number = 0.50;
public var growTimer:Timer;
public function Enemy() {
scaleX = scaleObj;
scaleY = scaleObj;
addEventListener(MouseEvent.CLICK, shootEnemy);
}
public function timerStart() {
growTimer = new Timer(50);
growTimer.addEventListener(TimerEvent.TIMER, objectGrow);
growTimer.start();
}
public function objectGrow(event:TimerEvent):void {
if(scaleObj <= 1.0) {
scaleObj += 0.01;
scaleX = scaleObj;
scaleY = scaleObj;
}
else {
killEnemy();
}
}
public function killEnemy():void {
this.parent.removeChild(this);
growTimer.stop();
}
public function shootEnemy(event:MouseEvent):void {
killEnemy();
}
}
}
There also is a cursor class, however there is no code beyond the package and class definers. Please let me know of any questions or comments you might have, thanks.
Most likely the Cursor object is intercepting the mouse click since it is above the Enemy object.
You can stop the Cursor from intercepting mouse events by setting in the cursor class:
this.mouseEnabled = false;
this.mouseChildren = false;
Also, you should ideally be using a native mouse cursor instead of manually creating your own. Check out this Adobe tutorial for an example.
Set your Cursor instance to not receive mouse events itself as it would block the click events from getting to the objects behind it. Code would be something like
cursor = new Cursor;
cursor.mouseEnabled = false;
cursor.mouseChildren = false;

As3 magnify image

I want to create a image magnify application like following:
A masked small window showig big image area corresponding to the mouse X and Y on the small image. There are many magnifying image application exaples online such as:
http://www.flashandmath.com/intermediate/magglass/mag_glass.html
But here the mouse and mask moves with same X and Y. What i want is that masked window display only certain area corresponding to mouse X and Y on Small image.
Any help would be highly appreciated. thanks.
i wrote a recipe last year for exactly what you're looking for. i do not guarantee that's it's as refactored or efficient as it could be, but it works really well. change it up as much as you like. i post the code hear for anyone to freely use.
however, the photograph and loupe asset i do not permit anyone to use without prior request, please.
the class lets you alter your own magnification strength, even at runtime if you want. you can use your own loupe graphic, but one is also included in the source files (please ask me first if you want to use it in your project).
Description:
Magnifier: Creating A Customizable
Magnifier For Image Assets
The following code demonstrates the
solution for creating a customizable
magnifier for image assets using the
Magnifier class.
The Magnifier constructor receives 6
parameters. The first
loupeDisplayObject:DisplayObject
required parameter is a reference to a
display object that is used as the
virtual loupe. In order for the class
to function properly, the
loupeDisplayObject:DisplayObject must
contain a circular or elliptically
shaped void or alpha transparency at
its center.
The second imageURL:String required
parameter supplies the URLLoader’s
load function’s URLRequest with the
URL of the target image asset. The
image provides BitmapData for both
thumbSprite:Sprite and
magnificationSprite:Sprite objects,
which are scaled using the third
thumbScale:Number and fourth
magnificationScale:Number optional
parameters. The scale of the
thumbSprite:Sprite is exhibited on
stage, while the scale of the
magnificationSprite:Sprite is visible
during magnification.
The Magnifier class operates by
employing mouse events to toggle the
visibility of a virtual loupe over an
image asset. A maskSprite:Sprite
ellipse, both indexed below and based
on the size of the
loupeDisplayObject:DisplayObject, is
created to mask the
magnificationSprite:Sprite. However,
the fifth maskWidth:Number and sixth
maskHeight:Number optional parameters
can be set to manually size a
maskSprite:Sprite that is more
suitable for a
loupeDisplayObject:DisplayObject with
a complex shape.
Calling the public deallocate()
function of the Magnifier instance
prior to its nullification will mark
it as being available for garbage
collection.
Class FIle:
package
{
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.geom.Matrix;
import flash.net.URLRequest;
import flash.ui.Mouse;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.Regular;
public class Magnifier extends Sprite
{
//Class Variables
private var loupeDisplayObject:DisplayObject;
private var imageWidth:Number;
private var imageHeight:Number;
private var thumbScale:Number;
private var magnificationScale:Number;
private var maskWidth:Number;
private var maskHeight:Number;
private var imageBitmapData:BitmapData;
private var maskSprite:Sprite;
private var magnificationSprite:Sprite;
private var thumbSprite:Sprite;
private var loupeTween:Tween;
private var magnificationTween:Tween;
//Constructor
public function Magnifier (
loupeDisplayObject:DisplayObject,
imageURL:String,
thumbScale:Number = 0.5,
magnificationScale:Number = 1.0,
maskWidth:Number = NaN,
maskHeight:Number = NaN
)
{
this.loupeDisplayObject = loupeDisplayObject;
this.thumbScale = Math.max(0.1, Math.min(thumbScale, 1.0));
this.magnificationScale = Math.max(0.1, magnificationScale);
this.maskWidth = maskWidth;
this.maskHeight = maskHeight;
init(imageURL);
}
//Load And Handle Image
private function init(imageURL:String):void
{
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageHandler);
imageLoader.load(new URLRequest(imageURL));
}
private function errorHandler(evt:IOErrorEvent):void
{
throw(evt.text);
}
private function imageHandler(evt:Event):void
{
evt.target.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
evt.target.removeEventListener(Event.COMPLETE, imageHandler);
imageWidth = evt.target.content.width;
imageHeight = evt.target.content.height;
imageBitmapData = new BitmapData(imageWidth, imageHeight);
imageBitmapData.draw(evt.target.content);
createComponents();
}
//Create Components
private function createComponents():void
{
//Loupe Visibility
loupeDisplayObject.alpha = 0;
//Mask
if (isNaN(maskWidth)) maskWidth = loupeDisplayObject.width;
if (isNaN(maskHeight)) maskHeight = loupeDisplayObject.height;
maskSprite = new Sprite();
maskSprite.graphics.beginFill(0x00FF00, 0.5);
maskSprite.graphics.drawEllipse(0, 0, maskWidth, maskHeight);
maskSprite.graphics.endFill();
maskSprite.mouseEnabled = false;
//Magnification
magnificationSprite = scaleImage(new Matrix(magnificationScale, 0, 0, magnificationScale));
magnificationSprite.mouseEnabled = false;
magnificationSprite.alpha = 0;
magnificationSprite.mask = maskSprite;
//Thumb
thumbSprite = scaleImage(new Matrix(thumbScale, 0, 0, thumbScale));
thumbSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//Add Components To The Display List
addChild(thumbSprite);
addChild(magnificationSprite);
addChild(maskSprite);
addChild(loupeDisplayObject);
}
private function scaleImage(matrix:Matrix):Sprite
{
var scaledResult:Sprite = new Sprite();
scaledResult.graphics.beginBitmapFill(imageBitmapData, matrix, false, true);
scaledResult.graphics.drawRect(0, 0, imageWidth * matrix.a, imageHeight * matrix.d);
scaledResult.graphics.endFill();
return scaledResult;
}
//Mouse Event Handlers
private function mouseDownHandler(evt:MouseEvent):void
{
thumbSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
thumbSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
mouseMoveHandler(evt);
setLoupeAsVisible(true);
}
private function mouseMoveHandler(evt:MouseEvent):void
{
loupeDisplayObject.x = evt.localX - loupeDisplayObject.width / 2;
loupeDisplayObject.y = evt.localY - loupeDisplayObject.height / 2;
maskSprite.x = evt.localX - maskSprite.width / 2;
maskSprite.y = evt.localY - maskSprite.height / 2;
magnificationSprite.x = 0 - evt.localX / thumbSprite.width * (magnificationSprite.width - thumbSprite.width);
magnificationSprite.y = 0 - evt.localY / thumbSprite.height * (magnificationSprite.height - thumbSprite.height);
}
private function mouseOutHandler(evt:MouseEvent):void
{
thumbSprite.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
setLoupeAsVisible(false);
}
private function mouseOverHandler(evt:MouseEvent):void
{
thumbSprite.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
setLoupeAsVisible(true);
}
private function mouseUpHandler(evt:MouseEvent):void
{
if (thumbSprite.hasEventListener(MouseEvent.MOUSE_OVER)) thumbSprite.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
thumbSprite.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
thumbSprite.removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
setLoupeAsVisible(false);
}
//Loupe Tween And Visibility
private function setLoupeAsVisible(response:Boolean):void
{
var targetAlpha:Number;
if (response)
{
targetAlpha = 1.0;
Mouse.hide();
}
else
{
targetAlpha = 0.0;
Mouse.show();
}
loupeTween = new Tween(loupeDisplayObject, "alpha", Regular.easeIn, loupeDisplayObject.alpha, targetAlpha, 0.25, true);
magnificationTween = new Tween(magnificationSprite, "alpha", Regular.easeIn, magnificationSprite.alpha, targetAlpha, 0.25, true);
}
//Clean Up
public function deallocate():void
{
thumbSprite.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
}
}

How do I make a movieclip appear using as3?

I have a movieclip in my library. I want to be able to make it appear on stage and be moved to where I want it to be. I will need up to 18 instances of this single movieclip. How do I do this (using AS3)?
You seem to be asking a lot of questions lately.
First off, right click on the MovieClip in the Library, and click Properties. Be sure to enable "Export for Actionscript". Under linkage, give it a class name (remember, first letter should be capitalized). For example, I'll use MovieClipClass.
In your document class (I used Main.as, which is in the same folder as test.fla):
package
{
import flash.display.Sprite;
import MovieClipClass;
public class Main extends Sprite
{
private var _container:Sprite;
public function Main()
{
addContainer();
}
private function addContainer():void
{
_container = new Sprite();
addChild(_container);
//add "18" movieclips to _container
addMovieClips(18, _container);
}
private function addMovieClips(limit:int, container:Sprite):void
{
for(var i:int=0;i<limit;i++)
{
var mc:MovieClipClass = new MovieClipClass();
container.addChild(mc);
//random x and y generated by stage width and height
mc.x = Math.floor(Math.random() * stage.stageWidth);
mc.y = Math.floor(Math.random() * stage.stageHeight);
}
container.x = 0;
container.y = 0;
}
}
}

Actionscript: How do I rotate an external png image using a matrix?

Okay so I have two import pieces of code involved in this. This first tiny bit is what creates an object called OBJECT_arrow. It is located in the main function of my main class:
new OBJECT_arrow().CREATE(this,200,200);
It isn't really all that important. Now this next bit is the OBJECT_arrow class. What it does is loads an external png image and draws it.
package
{
import flash.net.URLRequest;
import flash.display.*;
import flash.system.*;
import flash.events.*;
import Math;
public class OBJECT_arrow extends Sprite
{
public var X:Number = 0; public var Y:Number = 0;
public var DEPTH:int = 0 ;
public var CONTAINER:Sprite = new Sprite();
public var imageLoader:Loader = new Loader();
public var image:URLRequest = new URLRequest ('ARROW.png');
public function CREATE(CONTAINER:Sprite,X:Number,Y:Number):void
{
this.X = X; imageLoader.x = this.X;
this.Y = Y; imageLoader.y = this.Y;
this.CONTAINER = CONTAINER;
CONTAINER.stage.addEventListener(Event.ENTER_FRAME,STEP);
imageLoader.load(image);
DRAW();
}
public function STEP(event:Event):void
{
DRAW();
}
public function DRAW():void
{
addChild (imageLoader);
(CONTAINER as MAIN).DRAW_LIST[(CONTAINER as MAIN).DRAW_LIST.length] = this;
(CONTAINER as MAIN).DRAW_LIST[(CONTAINER as MAIN).DRAW_LIST.length] = DEPTH;
}
}
}
Now I know the mathematics behind rotation and know to rotate before I translate and everything but I simply don't know how to apply the transformation to an external image in as3.
When you load an image with Loader it is stored as an object of type DisplayObject.
If you want it to be rotated, just set the rotation property.
To apply a matrix, you can use the transform() method of the DisplayObject.
You should also take a look at the BitmapData (raw image data) and Bitmap (DisplayObject to hold the BitmapData) classes. Depending on the complexity of what you're trying to do, they may serve you better. Specifically, BitmapData will allow you to lock() the image while you are fiddling with its bits. Flash won't render the BitmapData until you unlock() it, which can be a great performance improvement if you're doing a lot of fiddling.