ActionScript - Problem moving scrollRect with cacheAsBitmap - actionscript-3

in order to increase performance of a scrollRect i must cache the vector as a bitmap, otherwise the scrollRect will be simply a less performant mask (info source).
however, i can't seem to move an object/scrollRect once i've applied cacheAsBitmap. why?
package
{
//Imports
import flash.display.Screen;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
//Class
[SWF(width = "800", height = "500", backgroundColor = "0x444444")]
public class ScrollRectTest extends Sprite
{
//Variables
private var background:Sprite;
private var ball:Sprite;
private var newScrollRect:Rectangle;
//Constructor
public function ScrollRectTest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 60;
init();
}
//Initialize
private function init():void
{
background = new Sprite();
background.graphics.beginFill(0x000000, 1.0);
background.graphics.drawRect(0, 0, 200, 400);
background.graphics.endFill();
ball = new Sprite();
ball.graphics.beginFill(0xFF0000, 1.0);
ball.graphics.drawCircle(0, 0, 100);
ball.graphics.endFill();
//ball.cacheAsBitmap = true; //<-- uncomment this
ball.scrollRect = new Rectangle(background.x, background.y, background.width, background.height);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
addChild(background);
addChild(ball);
}
//Mouse Down Event Handler
private function mouseDownEventHandler(evt:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
//Mouse Up Event Handler
private function mouseUpEventHandler(evt:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
//Enter Frame Event Handler
private function enterFrameEventHandler(evt:Event):void
{
newScrollRect = ball.scrollRect;
newScrollRect.y -= 10;
newScrollRect.x -= 5;
ball.scrollRect = newScrollRect;
}
}
}

Even more funny:
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
[SWF(width = "800", height = "500", backgroundColor = "0x444444")]
public class ScrollRectTest extends Sprite
{
//Variables
private var background:Sprite;
private var ball:Sprite;
private var newScrollRect:Rectangle;
//Constructor
public function ScrollRectTest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 60;
init();
}
//Initialize
private function init():void
{
background = new Sprite();
background.graphics.beginFill(0x000000, 1.0);
background.graphics.drawRect(0, 0, 200, 400);
background.graphics.endFill();
ball = new Sprite();
ball.graphics.beginFill(0xFFFF00, 1.0);
ball.graphics.drawCircle(0, 0, 100);
ball.graphics.endFill();
var foo:Sprite = new Sprite();
var g:Graphics = foo.graphics;
g.beginFill(0xFF0000, 0.2);
g.drawRect(0, 0, 100, 100);
g.endFill();
ball.addChild(foo);
ball.cacheAsBitmap = true; //<-- uncomment this
ball.scrollRect = new Rectangle(background.x, background.y, background.width, background.height);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
addChild(background);
addChild(ball);
}
//Mouse Down Event Handler
private function mouseDownEventHandler(evt:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
//Mouse Up Event Handler
private function mouseUpEventHandler(evt:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
//Enter Frame Event Handler
private function enterFrameEventHandler(evt:Event):void
{
newScrollRect = ball.scrollRect;
newScrollRect.y -= 1;
newScrollRect.x -= 1;
ball.scrollRect = newScrollRect;
// ball.scaleX = 1 + Math.random() * 0.01;// uncomment this to force redraw
}
}
}
So I assume it's some kind of bug.

Related

AS3 - Space Shooter Enemy Shots

I'm very new to AS3 and programming in general and I've been developing a space shooter game in AS3 and have run into trouble regarding the enemy shots. The enemies fly vertically down from the top of the screen and should fire two shots (one going left and one going right) once their y coordinates equal that of the player. This works fine, except after anything from 30 seconds to 2 minutes, the following errors occur.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at EnemyShip2/fireWeapon()[G:\Games Related\1942\src\EnemyShip2.as:78]
at EnemyShip2/loop2()[G:\Games Related\1942\src\EnemyShip2.as:65]
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at EnemyShot/removeSelf()[G:\Games Related\1942\src\EnemyShot.as:43]
at EnemyShot/loop()[G:\Games Related\1942\src\EnemyShot.as:36]
Below is the relevant code, for the enemy ship class as well as the enemy shot class.
Enemy Ship
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* ...
* #author D Nelson
*/
[Embed(source = "../assets/enemyship2.png")]
//This enemy moves relatively slowly and fires horizontal shots
public class EnemyShip2 extends Bitmap
{
private var vy:Number = 3;
//private var ay:Number = .2;
private var target:HeroShip;
private var enemyShip2:EnemyShip2;
private var enemyfireTimer:Timer;
private var enemycanFire:Boolean = true;
public function EnemyShip2(target:HeroShip):void
{
this.target = target;
scaleX = 0.3;
scaleY = 0.3;
x = Math.floor(Math.random() * 550);
y = -105;
addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
enemyfireTimer = new Timer(1000, 1);
enemyfireTimer.addEventListener(TimerEvent.TIMER, handleenemyfireTimer, false, 0, true);
}
private function handleenemyfireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
enemycanFire = true;
}
private function removeSelf2():void
{
removeEventListener(Event.ENTER_FRAME, loop2);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
private function loop2 (e:Event):void
{
//vy += ay;
y += vy;
if (y > stage.stageHeight)
{
removeSelf2();
}
if (y >= target.y && (enemycanFire))
{
fireWeapon();
enemycanFire = false;
enemyfireTimer.start();
}
if (this.x > 540 || this.x < 10)
{
removeSelf2();
}
}
private function fireWeapon():void
{
stage.addChild(new EnemyShot(target, x, y, -4));
stage.addChild(new EnemyShot(target, x, y, +4));
}
}
}
Enemy Shot
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.display.Stage;
/**
* ...
* #author D Nelson
*/
[Embed(source="../assets/enemyshot.png")]
public class EnemyShot extends Bitmap
{
private var speed:Number;
private var target:HeroShip;
private var vx:Number;
public function EnemyShot(target:HeroShip, x:Number, y:Number, vx:Number)
{
this.target = target;
this.x = x;
this.y = y;
this.vx = vx;
scaleX = 0.3;
scaleY = 0.3;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
x += vx;
if (x >= 600 || x <= -50)
{
removeSelf();
}
}
private function removeSelf():void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
}
}
Also provided is the main class, in case that is of any help.
package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.*;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.utils.*;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.text.*;
import flash.media.Sound;
import flash.media.SoundChannel;
/**
* ...
* #author D Nelson
*/
public class Main extends MovieClip
{
[Embed(source = "snd/gamemusic2.mp3")]
private var MySound : Class;
private var mainsound : Sound;
private var shootsound: Sound = new ShootSound;
private var sndChannel:SoundChannel = new SoundChannel;
public var heroShip:HeroShip;
public var enemyShip1:EnemyShip1
public var enemyShip2:EnemyShip2
public var enemyShip3:EnemyShip3
public var enemyShip4:EnemyShip4
public var bossShip: BossShip
public var enemyShot: EnemyShot;
public var playerShot: PlayerShot;
private var background1:Background1;
private var background2:Background2;
public static const scrollspeed:Number = 2;
public var playerShotArray:Array = new Array()
public var enemyShotArray:Array = new Array()
public var enemies1Array:Array = new Array()
public var enemies2Array:Array = new Array()
private var fireTimer:Timer; //this creates a delay between each shot
private var canFire:Boolean = true; //this checks if a shot can be fired
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
mainsound = (new MySound) as Sound;
shootsound = (new ShootSound) as Sound;
mainsound.play();
background1 = new Background1();
background2 = new Background2();
//setting the backgrounds one below another
background1.y = 0;
background2.y = background1.height;
//add background at the lowest depth level
stage.addChildAt(background1,0);
stage.addChildAt(background2, 0);
//sets up the timer and its listener
fireTimer = new Timer(250, 1);
fireTimer.addEventListener(TimerEvent.TIMER, handlefireTimer, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_DOWN, handleCharacterShoot);
//background scrolling effect
stage.addEventListener(Event.ENTER_FRAME, backgroundScroll);
//loop for enemy1 variety
stage.addEventListener(Event.ENTER_FRAME, loop1, false, 0, true);
//loop for enemy2 variety
stage.addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
//speed of player shots
setInterval(playerShootMovement, 10);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//entry point
heroShip = new HeroShip();
stage.addChild(heroShip);
//test values for enemies
/*enemyShip1 = new EnemyShip1();
stage.addChildAt(enemyShip1, 2);
enemyShip1.y = stage.stageWidth * 0.3;
enemyShip1.x = 300;
enemyShip2 = new EnemyShip2();
stage.addChildAt(enemyShip2, 2);
enemyShip2.y = stage.stageWidth * 0.3;
enemyShip2.x = 200;
enemyShip3 = new EnemyShip3();
stage.addChildAt(enemyShip3, 2);
enemyShip3.y = stage.stageWidth * 0.3;
enemyShip3.x = 100;
enemyShip4 = new EnemyShip4();
stage.addChildAt(enemyShip4, 2);
enemyShip4.y = stage.stageWidth * 0.3;
enemyShip4.x = 400;
bossShip = new BossShip();
stage.addChildAt(bossShip, 1);
bossShip.y = 10;
bossShip.x = 130;*/
Mouse.hide();
}
private function handlefireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
canFire = true;
}
public function playerShoot():void
{
//if canFire is true, allow a shot to be fired, then set canFire to false and start the timer again
//else, do nothing
if (canFire)
{
//Add new line to the array
playerShotArray.push(playerShot = new PlayerShot);
//Spawn missile in ship
playerShot.y = heroShip.y;
playerShot.x = heroShip.x+11;
addChild(playerShot);
canFire = false;
fireTimer.start();
sndChannel = shootsound.play();
}
}
public function playerShootMovement():void
{
//code adapted from the Pie Throw tutorial
for (var i:int = 0; i < playerShotArray.length; i++)
{
playerShotArray[i].y -= 10;
if (playerShotArray[i].y == 850)
{
playerShotArray.shift();
}
}
}
public function handleCharacterShoot(e:KeyboardEvent):void
{
/**
* SpaceBar = 32
*/
if (e.keyCode == 32)
{
playerShoot();
}
}
public function backgroundScroll (evt:Event):void
{
background1.y += scrollspeed;
background2.y += scrollspeed;
if (background1.y >= stage.stageHeight)
{
//the background is below the visible stage area, put it above the other background
background1.y = background2.y - background2.height;
}
else if (background2.y >= stage.stageHeight)
{
background2.y = background1.y - background2.height;
}
}
//EnemyShip 1 spawning
private function loop1(e:Event):void
{
//generates probability for the ship to spawn (lower number to increase odds, decrease it to decrease odds)
if (Math.floor(Math.random() * 55) == 5)
{
var enemyShip1:EnemyShip1 = new EnemyShip1(heroShip);
enemyShip1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy1, false, 0, true);
enemies1Array.push(enemyShip1);
stage.addChild(enemyShip1);
}
}
private function removeEnemy1(e:Event):void
{
//removes the enemy that most recently left the screen from the array
enemies1Array.splice(enemies1Array.indexOf(e.currentTarget), 1);
}
//EnemyShip2 spawning
private function loop2(e:Event):void
{
if (Math.floor(Math.random() * 40) == 5)
{
var enemyShip2:EnemyShip2 = new EnemyShip2(heroShip);
enemyShip2.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy2, false, 0, true);
enemies2Array.push(enemyShip2);
stage.addChild(enemyShip2);
}
}
private function removeEnemy2(e:Event):void
{
enemies2Array.splice(enemies2Array.indexOf(e.currentTarget), 1);
}
}
}
Initially I thought it was to do with enemies firing shots while being too far to either side of the screen, but that doesn't seem to be the case. Any help would be greatly appreciated.
You need to make sure you remove the ENTER_FRAME listeners whenever you remove the object.
Actually, my advise is to not add ENTER_FRAME handlers throughout your game objects. This gets hard to manage and leads to bugs like you've encountered. Instead, add a single ENTER_FRAME as your core game loop, and update objects by calling an update() function on a list of game objects you maintain in your main game class. When you remove an object you simply won't call update() anymore. It also becomes easy to pause the game by just removing the ENTER_FRAME handler.
For example, here's a pattern I like to use for simple games:
interface IGameObject {
update():void;
}
class Enemy extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Player extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Bullet extends Bitmap implements IGameObject {
public update():void {
// move, collide, etc
}
}
class Main extends Sprite {
private objects:Vector.<IGameObject> = new <IGameObject>[];
public start():void {
addEventListener(Event.ENTER_FRAME, update);
}
public stopGame():void {
removeEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void {
for each (var object:IGameObject in objects) {
object.update();
}
}
public addObject(object:IGameObject):void {
objects.push(object);
addChild(object as DisplayObject);
}
public removeObject(object:IGameObject):void {
objects.splice(objects.indexOf(object), 1);
removeChild(object as DisplayObject);
}
}
Add and remove objects using addObject and removeObject. You can invoke them through a reference to Main or through event handlers you dispatch from your objects.

AS3. How can a global var take a value which appears in a listener Event.COMPLETE

This is my code:
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.LoaderInfo;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.GradientType;
import flash.sampler.getSize;
public class Miniaturka extends MovieClip {
private var id:String;
public static var miniWidth:Number = 0;
private var tween:Tween;
private var tryb:Boolean;
private var button:Sprite;
private var index:Number;
private var aktywna:Boolean = false;
public var bLoad:Boolean = false;
public function Miniaturka(id:String,index:Number):void {
this.id = id;
this.index = index;
tryb = false;
var loader:Loader = new Loader();
loader.load(new URLRequest("images/"+id+"m.jpg"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,nLoadComplete);
this.alpha = 1;
button = new Sprite();
button.graphics.beginFill(0x000000,0);
button.graphics.drawRect(0,0,889,500);
button.graphics.endFill();
button.buttonMode = true;
addChild(button);
button.addEventListener(MouseEvent.MOUSE_OVER,onOver);
button.addEventListener(MouseEvent.MOUSE_OUT,onOut);
button.addEventListener(MouseEvent.CLICK,onClick);
}
private function nLoadComplete(event:Event):void {
var loader:Loader = new Loader();
loader = LoaderInfo(event.target).loader;
pusty.addChild(loader);
ladowanie.visible = false;
tween = new Tween(pusty,"alpha",Regular.easeOut,0,0.6,2,true);
bLoad = true;
setStan(false);
miniWidth = loader.width;
pusty.alpha = 0;
}
private function onOver(event:MouseEvent):void {
if (!aktywna) {
setStan(true);
}
}
private function onOut(event:MouseEvent):void {
if (!aktywna) {
setStan(false);
}
}
private function onClick(event:MouseEvent):void {
aktywuj();
}
public function deaktywuj():void {
setStan(false);
aktywna = false;
}
public function aktywuj():void {
MovieClip(parent).deaktywuj();
aktywna = true;
setStan(true);
MovieClip(parent.parent).loadBig(id,index);
}
private function setStan(tryb:Boolean):void {
this.tryb = tryb;
if (tryb) {
pusty.alpha = 1;
} else {
pusty.alpha = 0.6;
}
}
}
}
I want to create a gallery, and this is a code of a class which loads jpg. files with different widths, but the same height.
My problem is that I want to make the public static var miniWidth which takes the value: loader.width in function: nLoadComplete, take that value as a global var, and put it in the line: button.graphics.drawRect(0,0,889,500); so it would look like button.graphics.drawRect(0,0,miniWidth ,500);
This will create a button(rectangle) the same height and width as the loaded jpg. but i can't figure it out... How can I do that?
Wait for the image to load before drawing your shape. In the example below, I've only reprinted the affected functions.
private function Miniaturka(id:String, index:Number):void {
this.id = id;
this.index = index;
tryb = false;
var loader:Loader = new Loader();
loader.load(new URLRequest("images/" + id + "m.jpg"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, nLoadComplete);
this.alpha = 1;
}
private function nLoadComplete(event:Event):void {
var loader:Loader = new Loader();
loader = LoaderInfo(event.target).loader;
pusty.addChild(loader);
ladowanie.visible = false;
tween = new Tween(pusty, "alpha", Regular.easeOut, 0, 0.6, 2, true);
bLoad = true;
setStan(false);
miniWidth = loader.width;
pusty.alpha = 0;
createBtn();
}
private function createBtn():void {
button = new Sprite();
button.graphics.beginFill(0x000000, 0);
button.graphics.drawRect(0, 0, miniWidth, 500);
button.graphics.endFill();
button.buttonMode = true;
addChild(button);
button.addEventListener(MouseEvent.MOUSE_OVER, onOver);
button.addEventListener(MouseEvent.MOUSE_OUT, onOut);
button.addEventListener(MouseEvent.CLICK, onClick);
}

Move the circle in as3

I already have the graphic with image on the screen and I wanted to it to move when I pressed the arrows on keyboard.
But it seems the listener is not running and there is no error.
Here is the code:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.display.BitmapData;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.net.URLRequest;
/**.
* ....
* #author Kaoru
*/
[SWF(width = '800', height = '600', backgroundColor = '#000000', frameRate = '24')]
public class GameManager extends Sprite
{
var myBitmap:BitmapData;
var imgLoader:Loader;
var circle:Sprite;
public function GameManager():void
{
circle = new Sprite();
imgLoader = new Loader();
imgLoader.load(new URLRequest("../lib/fira_front.png"));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, drawImage);
addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private function drawImage(e:Event):void
{
myBitmap = new BitmapData(imgLoader.width, imgLoader.height, false);
myBitmap.draw(imgLoader);
circle.graphics.beginBitmapFill(myBitmap, null, true);
circle.graphics.drawCircle(50, 50, 10);
circle.graphics.endFill();
addChild(circle);
}
private function onKeyDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.LEFT)
{
circle.x += 5;
}
else if (e.keyCode == Keyboard.RIGHT)
{
circle.x -= 5;
}
if (e.keyCode == Keyboard.UP)
{
circle.y += 5;
}
else if (e.keyCode == Keyboard.DOWN)
{
circle.y -= 5;
}
}
}
}
You need to add it to stage like so,
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
I have modified your code like so:
Always check for ADDED_TO_STAGE first and then proceed,
public function GameManager():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
circle = new Sprite();
imgLoader = new Loader();
imgLoader.load(new URLRequest("../lib/fira_front.png"));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, drawImage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); //This line is modified
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
Have you tried to add your listener on the stage directly ?
So that this
public function GameManager():void
{
circle = new Sprite();
imgLoader = new Loader();
imgLoader.load(new URLRequest("../lib/fira_front.png"));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, drawImage);
addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
Becomes this
public function GameManager():void
{
circle = new Sprite();
imgLoader = new Loader();
imgLoader.load(new URLRequest("../lib/fira_front.png"));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, drawImage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}

as3 hitTestPoint detecting alpha

I am trying to make maze where the user draws with mouse and if they hit the wall it erases the line they just drew. I have a png file with alpha that creates the walls of the maze.
I need the user to draw on the alpha but when they hit a non alpha it will trigger an action and erase the line.
Here is the line I am having issues with:
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
Here is the full code:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theBall:Ball = new Ball();
//alreadyDrawn = new Shape();
public function MazeClass()
{
if (stage)
{
myshape = new Shape();
myshape.graphics.lineStyle(12,0x000000);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
addChild(theBall);
}
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
drawing = true;
}
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
{
trace("Hit A WALL!");
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0xFFFFFF);
myshape.graphics.moveTo(mouseX,mouseY);
}
}
}
public function stopDrawing(event:MouseEvent)
{
drawing = false;
}
}
}
Another option is to test the colour of the map bitmapdata pixel that corresponds to the "player's position" (the end of the drawn line, in this case):
var testPixel:uint = _myBitmapData.getPixel(xPosition, yPosition);
Or you can use .getPixel32 which includes alpha in the returned uint.
I FOUND A WORKING SOLUTION:
I found a working solution thanks to fsbmain. Thank you. I am posting my full code in hopes that this can help someone else.
In the end I had to use another movieClip rather than the mouse, but this worked for me. Now instead of drawing anywhere in the maze they have to drag a little character named Beau thru the maze. This works better for me.
It would be nice to know how to also detect if the mouse or the actual line I am drawing hit the wall as well. Maybe someone can make a suggestion. Nevertheless, thanks for helping me get this far.
The short and essential code to make my movieClip detect the alpha can be found here. It really is very short compared to other complicated options I found. Here is the link: http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.desktop.NativeApplication;
import flash.system.Capabilities;
import flash.display.*;
import flash.geom.*;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theMap:*;
public var swiper:Swiper = new Swiper();
public var Beau:littleBeau = new littleBeau();
//alreadyDrawn = new Shape();
public var currentGalleryItem:Number = 1;
public var totalGalleryItems:Number = 4;
public var redClipBmpData:BitmapData;
public var blueClipBmpData:BitmapData;
public var redRect:Rectangle;
public var blueRect:Rectangle;
public function MazeClass()
{
if (stage)
{
theMap = new MapOne();
myshape = new Shape();
myshape.graphics.lineStyle(33,0x0aa6df);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
stage.addEventListener(KeyboardEvent.KEY_UP, fl_OptionsMenuHandler);
Multitouch.inputMode = MultitouchInputMode.GESTURE;
addChild(theMap);
//theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(swiper);
swiper.y = stage.stageHeight - swiper.height;
swiper.addEventListener(TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrame);
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
Beau.addEventListener(MouseEvent.MOUSE_DOWN, BeauStartDrag);
Beau.addEventListener(MouseEvent.MOUSE_UP, BeauStopDrag);
redRect = theMap.getBounds(this);
redClipBmpData = new BitmapData(redRect.width,redRect.height,true,0);
redClipBmpData.draw(theMap);
blueRect = Beau.getBounds(this);
blueClipBmpData = new BitmapData(blueRect.width,blueRect.height,true,0);
blueClipBmpData.draw(Beau);
//blueClipBmpData.x = theMap.theStart.x;
//blueClipBmpData.y = theMap.theStart.y - swiper.height;
stage.addEventListener(Event.ENTER_FRAME, enterFrame);
}
}
public function enterFrame(e:Event):void
{
//Beau.x = mouseX;
//Beau.y = mouseY;
if (redClipBmpData.hitTest(new Point(theMap.x, theMap.y),
255,
blueClipBmpData,
new Point(Beau.x, Beau.y),
255
))
{
trace("hit");
clearAll();
//redClip.filters = [new GlowFilter()];
}
else
{
trace("No Hit");
}
}
public function BeauStartDrag(event:MouseEvent):void
{
Beau.startDrag();
drawing = true;
}
public function BeauStopDrag(event:MouseEvent):void
{
drawing = false;
Beau.stopDrag();
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
}
//drawing = true;
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
}
}
public function stopDrawing(event:MouseEvent)
{
//drawing = false;
}
public function fl_OptionsMenuHandler(event:KeyboardEvent):void
{
if ((event.keyCode == 95) || (event.keyCode == Keyboard.MENU))
{
NativeApplication.nativeApplication.exit(0);
}
}
public function clearAll()
{
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0x0aa6df);
myshape.graphics.moveTo(mouseX,mouseY);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
drawing = false;
Beau.stopDrag();
}
public function fl_SwipeToGoToNextPreviousFrame(event:TransformGestureEvent):void
{
if (event.offsetX == 1)
{
if (currentGalleryItem > 1)
{
currentGalleryItem--;
trace("swipe Right");
clearAll();
removeChild(theMap);
theMap = new MapOne();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
else if (event.offsetX == -1)
{
if (currentGalleryItem < totalGalleryItems)
{
currentGalleryItem++;
trace("swipe Left");
clearAll();
removeChild(theMap);
theMap = new MapTwo();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
}
}
}

How to call one of the function from this class?

I wanna call the function "nextMenu" & "prevMenu" from this class from Main.as
But I get the error 1136: Incorrect number of arguments. Expected 1.
Can help me see what I've left out on the codes?
CategoryScroller.as
package com.theflashfactor.carouselStackGallery.categoryMenu
{
import com.greensock.TweenMax;
import com.greensock.easing.Quint;
import com.theflashfactor.utils.Ref;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
/**
* Scroller to switch view for category item if there are more than visibleItem available
* #author Rimmon Trieu
*/
public class CategoryScroller extends Sprite
{
private var trackLength:int = 400;
private var scrubber:Sprite;
private var track:Shape;
private var categoryMenu:CategoryMenu;
private var trans:Sprite;
private var center:Number;
public function CategoryScroller(categoryMenu:CategoryMenu)
{
this.categoryMenu = categoryMenu;
buttonMode = true;
initialize();
}
/**
* Draw elemnt scrubber and track
*/
private function initialize():void
{
trans = new Sprite();
trans.graphics.beginFill(0, 0);
trans.graphics.drawRect(0, 0, trackLength, 13);
trans.graphics.endFill();
trans.addEventListener(MouseEvent.MOUSE_DOWN, transMouseDown, false, 0, true);
addChild(trans);
// Draw track
var color:uint = uint(Ref.getInstance().getRef("categoryCircleColor"));
track = new Shape();
track.graphics.lineStyle(1, color);
track.graphics.lineTo(trackLength, 0);
track.y = 6;
addChild(track);
// Draw scrubber
scrubber = new Sprite();
scrubber.graphics.beginFill(color);
scrubber.graphics.drawRect(0, 0, 80, 13);
scrubber.graphics.endFill();
center = (trackLength - scrubber.width) >> 1;
scrubber.x = center;
addChild(scrubber);
// Add dragging functionality
scrubber.addEventListener(MouseEvent.MOUSE_DOWN, scrubberMouseDown,false,0,true);
}
private function transMouseDown(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler,false,0,true);
TweenMax.killTweensOf(scrubber);
categoryMenu.preTransition();
if (mouseX > width - scrubber.width) scrubber.x = (width - scrubber.width); else scrubber.x = mouseX;
}
/*private function transMouseUp(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
checkPosition();
}*/
private function scrubberMouseDown(event:MouseEvent):void
{
event.stopImmediatePropagation();
TweenMax.killTweensOf(scrubber);
scrubber.startDrag(false, new Rectangle(0, 0, trackLength - scrubber.width, 0));
stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler,false,0,true);
categoryMenu.preTransition();
}
private function stageMouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
scrubber.stopDrag();
checkPosition();
}
private function checkPosition():void
{
var targetX:Number = (trackLength - scrubber.width) >> 1;
if (scrubber.x > (center + 20)) categoryMenu.postTransition(1);
else
if (scrubber.x < (center - 20)) categoryMenu.postTransition(-1);
else
categoryMenu.postTransition(0);
TweenMax.to(scrubber, .5, {x:targetX, ease:Quint.easeOut, overwrite:1});
}
public function nextMenu():void
{
categoryMenu.postTransition(1);
}
public function prevMenu():void
{
categoryMenu.postTransition(-1);
}
}
}
I've inserted the code below in my Main.as to call the function which I can't get it success.
import com.theflashfactor.carouselStackGallery.categoryMenu.CategoryScroller;
private var categoryScroller:CategoryScroller = new CategoryScroller();
categoryScroller.nextMenu();
Main.as
package
{
import com.theflashfactor.carouselStackGallery.CarouselStackGallery;
import com.theflashfactor.carouselStackGallery.categoryMenu.CategoryMenu;
import com.theflashfactor.carouselStackGallery.categoryMenu.CategoryScroller;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import org.casalib.events.LoadEvent;
import org.casalib.load.DataLoad;
/**
* Main document class
* #author Rimmon Trieu
*/
[SWF(frameRate="60", backgroundColor="0", pageTitle="3D Carousel Stack Gallery")]
public class Main extends Sprite
{
private var xmlPath:String = "../xml/Main.xml";
private var ts3:Sprite = new Sprite;
private var categoryMenu:CategoryMenu = new CategoryMenu();
private var categoryScroller:CategoryScroller = new CategoryScroller();
public function Main()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addEventListener(Event.ADDED_TO_STAGE, addToStage);
}
private function addToStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addToStage);
var xmlLoad:DataLoad = new DataLoad(xmlPath);
xmlLoad.addEventListener(LoadEvent.COMPLETE, xmlLoaded);
xmlLoad.start();
ts3.graphics.beginFill(0x555555,1);
ts3.graphics.drawCircle(0, 0, 50);
ts3.graphics.endFill();
}
private function xmlLoaded(event:LoadEvent):void
{
event.target.removeEventListener(LoadEvent.COMPLETE, xmlLoaded);
opaqueBackground = uint(event.target.dataAsXml.settings.#backgroundColor);
var gallery:CarouselStackGallery = new CarouselStackGallery(event.target.dataAsXml);
addChild(gallery);
addChild(ts3);
ts3.addEventListener(MouseEvent.MOUSE_DOWN, ts3MouseDown,false,0,true);
}
private function ts3MouseDown(event:MouseEvent):void
{
categoryScroller.nextMenu();
}
}
}
As defined:
public function CategoryScroller(categoryMenu:CategoryMenu)
{
...
Shouldn't the class constructor be expecting an argument??
private var categoryScroller:CategoryScroller = new CategoryScroller();