Movieclips clashing with bitmap mask - actionscript-3

I am trying to reveal this movie clip image which is originally a bitmap but needs to be used as a bitmap for this purpose. for some reason it's not working ...
It's not throwing any errors... I need this image to be masked as the user presses on it... and later be compared with another bitmap to carry out a function. but for some reason as I mentioned before it's not working out. can somebody please help me?? this is the code for it...
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.BitmapData;
var mouseclick:Number=0;
var maskedbg_mc:maskedbg = new maskedbg ();
var masking:Sprite = new Sprite()
addChild (maskedbg_mc);
maskedbg_mc.x = 18;
maskedbg_mc.y = 343;
var bitmapDataCopy:BitmapData = new BitmapData(742,165,true,0x00FFFFFF);
var b:Bitmap = new Bitmap(bitmapDataCopy);
bitmapDataCopy.draw(maskedbg_mc);
b.mask = masking;
var Testing:BitmapData = new BitmapData(maskedbg_mc.width, maskedbg_mc.height, true, 0x00000000);
addChild(masking);
stage.addEventListener(MouseEvent.MOUSE_DOWN, Pressing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, Moving);
stage.addEventListener(MouseEvent.MOUSE_UP, Lifting);
function Pressing(event:MouseEvent):void {
mouseclick = 1;
}
function Moving(event:MouseEvent):void {
if (mouseclick == 1) {
masking.graphics.beginFill(0x000000);
masking.graphics.drawEllipse(mouseX, mouseY, 70, 60);
masking.graphics.endFill();
}
}
function Lifting(event:MouseEvent):void {
mouseclick = 0;
}
if ( bitmapDataCopy.compare(Testing) ==0 )
{
trace ("Awesomness")
}

Overlooking your code, I notice you are not adding "b" (the masked DisplayObject) to the display list, while you are adding "maskedbg_mc" which actually isn't being masked in your code. Do you have a reason for having these 2 display objects?
I would recommend you following actionscript coding conventions:
http://sourceforge.net/adobe/flexsdk/wiki/Coding%20Conventions/
Your code looks quite confusing when you have both variables and functions with initial letter in uppercase, they look like classes.

Related

Creating Top Down Shooter in Adobe Flash CS4 using ActionScript 3 but bullets behaving weirdly

I am making a TDS in Flash CS4 using AS3 but there seems to be a problem. It's hard to explain so I'm gonna link the flash file. Click this.
This is the first time uploading a file for sharing so for those who can't or are unable to download the file, this is what happens:
Player has mouse rotation that is, Player looks at where the mouse is. On Mouse down I've put the script for creating bullets. The bullets are being created alright. But when the bullets move that's when the problem arises. Say that at position and rotation X, I shot 5 bullets and they are moving in X direction. Now if I shoot a bullet in Y position and rotation, the bullet that was created there goes in Y direction but so do all the other bullets that were created in the X position and direction. They change their course.
Here is the code for the game.
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Mouse;
import flash.events.TimerEvent;
public class Main extends MovieClip {
var player : Player = new Player();
//Customizable Weapon Settings
var bulletNumber:Number;//number of bullets per shot
var bulletOffset:Number;//bigger number = less acurate
var bulletSpeed:Number;//pixels per frame
var bulletMaxAge:Number;//1000 = 1 second
var reloadSpeed:Number;//1000 = 1 second
var randomNum:Number;
public static var xSpeed:Number;
public static var ySpeed:Number;
var bulletAngle:Number;
var timer:Number=0;
var flag:Boolean;
//other variables (do not edit)
var mouseClicked:Boolean=false;
var radians:Number=Math.PI/180;
public function Main() {
player.x=stage.stageWidth/2;
player.y=stage.stageHeight/2;
stage.addChild(player);
player.gotoAndStop(5);
loadWeapon("Machine Gun");
addEventListener(Event.ENTER_FRAME,on_enter_frame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
public function onMouseDownHandler(event:MouseEvent) {
//trace("Mouse Down");
mouseClicked=true;
flag=true;
}
public function onMouseUpHandler(event:MouseEvent) {
//trace("Mouse Up");
mouseClicked=false;
flag=false;
timer=0;
}
public function loadWeapon(weaponType:String) {
switch (weaponType) {
case "Machine Gun" :
//bulletNumber = 100;
bulletOffset=10;
bulletSpeed=10;
bulletMaxAge=1000;
break;
}
}
function on_enter_frame(e:Event) {
trace("Click: "+ mouseClicked);
fireWeapon();
}
function fireWeapon() {
//check if mouse is clicked
//if true, create bullet
if (mouseClicked) {
createBullet();
player.gotoAndStop(10);
} else {
player.gotoAndStop(1);
}
}
public function createBullet() {
var bullet : Bullet2= new Bullet2();
bullet.x=player.x;
bullet.y=player.y;
if (flag) {
timer++;
if (timer==10) {
trace("lol");
//calculate random bullet offset.
randomNum = Math.random() * (bulletOffset);
//set bullet firing angle
bulletAngle = (player.rotation + randomNum) * radians;
//set bullet speed based on angle
xSpeed=Math.cos(bulletAngle)*bulletSpeed;
ySpeed=Math.sin(bulletAngle)*bulletSpeed;
//trace (bulletAngle);
stage.addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, runForest);
//mouseClicked = false;
timer=0;
}
}
function runForest(e:Event) {
bullet.x+=xSpeed;
bullet.y+=ySpeed;
}
}
}
}
Things that I've tried:
1) I put the "runForest()" funtion outside of "createbullet()" function which give me a "1120: Access of undefined property bullet." Error. (Which doesn't make sense since I am giving it a enter frame event listener.)
2) For solving this, I made the bullet variable global and declared it inside the "createbullet()" function like this- "var bullet : Bullet2;" And inside createbullet()- "bullet = new Bullet2();" That gives me a completely different output.
3) I put the "runForest()" function in its own class file. But the same thing is happening.
I was referring to a Tutorial that used AS2. This is the link.
Help me solve this please.
Thanks!
Review this code:
//set bullet speed based on angle
xSpeed=Math.cos(bulletAngle)*bulletSpeed;
ySpeed=Math.sin(bulletAngle)*bulletSpeed;
then take a look at how these variables for speed are created:
public static var xSpeed:Number;
public static var ySpeed:Number;
You have 1 variable for the x direction of the speed. If there is only one variable, there can only be 1 value for speed.
that's why all your bullets are moving in the same direction, because they all share that one single value for speed, which causes them to go into the same direction.
Your Main class is doing everything at the moment and you should really refactor some of that code into several other classes.
Even your own understanding of the code you are writing is not reflected by the code, your comment says:
//set bullet speed based on angle
Now why is that bullet speed a variable of Main? Object oriented programming is made exactly for that. You can literally turn your plain English description of the desired behaviour into code.
When you say that you "want to have Bullets", then create a Bullet class.
When you say "each Bullet object should have its own speed", then add a property to that class that is the speed.
You will encounter the same problem with your weapons and the same solution applies.

AS3 Fill Color inside line by pen

I was trying to make a flash app with AS3 where I can draw line with pen tool with different colors , also fill the shapes on an image with different colors, now I have went through various tutorials and achieved it, however in the end I am faced with 2 problems that I am unable to solve even after 3 days of efforts:
How can I fill color inside the shapes formed by using the pen tool,
say if I draw a rough circle using pen tool and then I try and fill
it with green, how can I detect MovieClips which I need to fill.
When I draw lines over shapes and then try and fill the shapes, the
shapes gets filled but the lines still appear on top of the shapes
filled with color.
You can get a better idea of what I have achieved by visiting this link, click the pen symbol and paint bucket symbol to see how it works.
Below is my code for pen tool and fill color:
I draw a sprite add an image and then use the property to detect color to draw a line of color I choose, followed by code to fill color where I divide the image in various MovieClips and then make then into one and detect if mouse is clicked on which clip and fill it with selected color.
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
bucbut.addEventListener(MouseEvent.CLICK,nClick0PC);
/////////////pentool code --------
convertToBMD();
pbut.addEventListener(MouseEvent.CLICK,nClick0P);
function nClick0P(event:MouseEvent):void{
spBoard.addEventListener(MouseEvent.ROLL_OUT,boardOut);
spBoard.addEventListener(MouseEvent.MOUSE_MOVE,boardMove);
spBoard.addEventListener(MouseEvent.MOUSE_DOWN,boardDown);
spBoard.addEventListener(MouseEvent.MOUSE_UP,boardUp);
}
var spBoard:Sprite=new Sprite();
this.addChildAt(spBoard,0);
spBoard.x=20;
spBoard.y=100;
var owl2:owl;
owl2 = new owl();
owl2.name="owl1";
spBoard.addChildAt(owl2,0);
owl2.x=315;
owl2.y=180;
var shDrawing:MovieClip = new MovieClip();
//var shDrawing:Shape=new Shape();
spBoard.addChild(shDrawing);
//spBoard.addChildAt(shDrawing,1);
function nClick0PC(event:MouseEvent):void{
owl2.addEventListener(MouseEvent.CLICK,on_owl_click);
}
var doDraw:Boolean=false;
var lineSize:Number=10;
var currentColor:Number;
spBoard.graphics.lineStyle(1,0x000000);
spBoard.graphics.beginFill(0xFFFFFF);
spBoard.graphics.drawRect(0,0,602,330);
spBoard.graphics.endFill();
spBoard.filters = [ new DropShadowFilter() ];
function boardOut(e:MouseEvent):void {
doDraw=false;
}
function boardDown(e:MouseEvent):void {
doDraw=true;
trace(activeColor);
shDrawing.graphics.lineStyle(lineSize,activeColor);
shDrawing.graphics.endFill();
shDrawing.graphics.moveTo(shDrawing.mouseX,shDrawing.mouseY);
}
function boardUp(e:MouseEvent):void {
doDraw=false;
}
function boardMove(e:MouseEvent):void {
var curX:Number=shDrawing.mouseX;
var curY:Number=shDrawing.mouseY;
if(doDraw && checkCoords(curX,curY)){
shDrawing.graphics.lineTo(curX,curY);
e.updateAfterEvent();
}
}
function checkCoords(a:Number,b:Number):Boolean {
if(a>=605-lineSize/2 || a<=lineSize/2 || b>=311-lineSize/2 || b<=lineSize/2){
return false;
}
else {
return true;
}
}
/////////////---------------------color picker
colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor);
var pixelValue:uint;
var activeColor:uint = 0x000000;
var ct:ColorTransform = new ColorTransform();
var colorsBmd:BitmapData;
function convertToBMD():void
{
colorsBmd = new BitmapData(colors.width,colors.height);
colorsBmd.draw(colors);
}
function chooseColor(e:MouseEvent):void
{
pixelValue = colorsBmd.getPixel(colors.mouseX,colors.mouseY);
activeColor = pixelValue;//uint can be RGB!
ct.color = activeColor;
//shapeSize.transform.colorTransform = ct;
}
////////////////////========================================Fill color
function on_owl_click(e:MouseEvent):void {
for (var i:int = 0; i < owl2.numChildren; i++) {
if (owl2.getChildAt(i).hitTestPoint(mouseX,mouseY,true)) {
trace(owl2.getChildAt(i).name);
owl2.getChildAt(i).transform.colorTransform= ct;
}
}
}
I deleted a lot of your code and left this:
convertToBMD();
colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor);
var activeColor: uint = 0x000000;
var colorsBmd: BitmapData;
function convertToBMD(): void
{
colorsBmd = new BitmapData(colors.width, colors.height);
colorsBmd.draw(colors);
}
function chooseColor(e: MouseEvent): void
{
var pixelValue:uint = colorsBmd.getPixel(colors.mouseX, colors.mouseY);
activeColor = pixelValue; //uint can be RGB!
}
Also I removed an owl at the stage. Download my FLA to see changes.
Next. I added two canvases.
var canvasData:BitmapData = new BitmapData(650, 437, false, 0xEFEFEF);
var canvas:Bitmap = new Bitmap(canvasData);
canvas.x = 0;
canvas.y = 102;
addChild(canvas);
var penCanvas:Shape = new Shape();
penCanvas.x = canvas.x;
penCanvas.y = canvas.y;
You can read about Bitmap and BitmapData here.
First canvas it's a raster image. Second canvas it's a Shape, so you can use moveTo and lineTo methods to draw with a pencil.
Next. In library i found an owl image and export it to code.
If not understand, I can explain more detailed.
Next. Registration event handlers.
bucbut.addEventListener(MouseEvent.CLICK, clickBucket);
pbut.addEventListener(MouseEvent.CLICK, clickPen);
function clickBucket(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_DOWN, canvasDown);
stage.addEventListener(MouseEvent.CLICK, clickOnCanvas);
}
function clickPen(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, canvasDown);
stage.removeEventListener(MouseEvent.CLICK, clickOnCanvas);
}
Let's see at clickOnCanvas method:
function clickOnCanvas(event:MouseEvent):void
{
// If we click at the canvas
if (canvas.hitTestPoint(mouseX,mouseY))
{
canvasData.floodFill(canvas.mouseX, canvas.mouseY,activeColor);
}
}
About floodFill you can read here.
And the last three methods used to draw by pen.
function canvasDown(event:MouseEvent):void
{
penCanvas.graphics.lineStyle(10, activeColor);
penCanvas.graphics.moveTo(penCanvas.mouseX, penCanvas.mouseY);
// only when mouse button is down we register two handlers, one for move and another for mouse up
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function mouseMove(event:MouseEvent):void
{
// when mouse is moving we are drawing line
penCanvas.graphics.lineTo(penCanvas.mouseX, penCanvas.mouseY);
// As I said earlier canvasData it's a raster image. So we copy penCanvas and paste to canvasData.
canvasData.draw(penCanvas);
// For a smoother drawing
event.updateAfterEvent();
}
function mouseUp(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
That's all!
Here you can download sources.

How to get symbols to revert back to starting position in AS3 flash

Hi im trying to create a very simple drag and drop game in flash and I the scene to just loop round itself so say, if ( user does this) then go back to the beginning of the scene. but when I try this the symbols that the user has moved stay to where they have moved them too rather than returning to the position they were in at the start of the scene.
Can anyone explain a way to get the symbols to return to where they were at the begining of the scene once the if statement has completed?
The following example will traverse the display list, storing symbols along with their initial positions in a Dictionary. When it's time to reset, just call the resetToOriginalPositions method, passing it the Dictionary that was created.
import flash.utils.Dictionary;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.MovieClip;
var originalPositions:Dictionary;
if(!originalPositions)
{
originalPositions = collectPositions(this);
}
function collectPositions(container:DisplayObjectContainer):Dictionary
{
var positions:Dictionary = new Dictionary(true);
for(var i:int = 0; i < container.numChildren; i++)
{
var currentSymbol:DisplayObject = container.getChildAt(i);
positions[currentSymbol] = new Point(currentSymbol.x, currentSymbol.y);
// this will allow the symbols to be dragged/dropped
currentSymbol.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler);
currentSymbol.addEventListener(MouseEvent.MOUSE_UP, clickHandler);
}
return positions;
}
function clickHandler(e:MouseEvent):void
{
var target:MovieClip = e.target as MovieClip;
if(e.type == MouseEvent.MOUSE_DOWN)
{
target.startDrag();
}
else
{
target.stopDrag();
}
}
function resetToOriginalPositions(positions:Dictionary):void
{
for(var currentSymbol:Object in positions)
{
var position:Point = positions[currentSymbol];
DisplayObject(currentSymbol).x = position.x;
DisplayObject(currentSymbol).y = position.y;
}
}
// this line should be called in your if statement that you already have set up
resetToOriginalPositions(originalPositions);
Marcela's answer may work for you, but just in case you would like something a little simpler...you can store the original positions on a dynamic property of each object. When the condition you require is met to go back to the original positions you can call a function that resets the current x and y positions to the original ones.
//place in frame 1
dragObject1.originalY = dragObject1.y;
dragObject1.originalX = dragObject1.x;
dragObject2.originalY = dragObject2.y;
dragObject2.originalX = dragObject2.x;
//...rest of object posisitions
function resetObjectPositions()
{
dragObject1.y = dragObject1.originalY;
dragObject1.x = dragObject1.originalX;
dragObject2.y = dragObject2.originalY;
dragObject2.x = dragObject2.originalX;
//...rest of object positions
}
//later in scene
if(condition)
{
resetObjectPositions();//make sure to run this code before going back to frame one in the scene to use the original values;
}

HitTest for objects not yet on Stage

I need to add a MovieClip to stage, the limitation being that it should only be added to an empty area on the stage. The stage itself either contains complex shapes or is manipulable by the user i.e. he can drag/move objects to change the empty area. The hitTest and hitTestObject methods need DisplayObject already available on the stage. What is the right way to go - the only solution I can imagine is having added my object on the stage and then repeatedly doing hit tests?
[Imagine it to something like adding sprites in a video game - they must spawn in empty regions; if they pop out from inside of each other, then it'll look really odd.]
Well, when you create a new class, just turn it off with a variable and set the visibility to false, then loop until there is no hitTest.
A silly example:
public class someClass extends Sprite
{
private var objectsOnStage:Array;
public function someClass(objectsArray:Array) {
objectsOnStage = objectsArray;
visible = false;
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event){
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.ENTER_FRAME, SEARCH);
}
private function SEARCH(e:Event) {
var doesHit:Boolean = false;
x = Math.round(Math.random() * (550 - 0)) + 0;
y = Math.round(Math.random() * (400 - 0)) + 0;
for (var i:int = 0; i < objectsOnStage; i++) {
if (doesHit) break;
if (this.hitTestObject(objectsOnStage[i])) {
doesHit = true;
}
}
if (doesHit) return;
placedInit();
}
private function placedInit() {
visible = true;
removeEventListener(Event.ENTER_FRAME, SEARCH);
//now init the stuff you want.
}
}
You just check if bounding boxes of both clips overlaps. Like this:
import flash.geom.Rectangle;
import flash.display.MovieClip;
// create simple movie clips that has a rectangle shape inside
var sym1 : MovieClip = new Sym1();
var sym2 : MovieClip = new Sym2();
// get a rectanle of both clipt
var boundingBox1 : Rectangle = sym1.getBounds(this);
var boundingBox2 : Rectangle = sym2.getBounds(this);
// check if bounding boxes of both movie clips overlaps
// so it works like hitTestObject() method
trace( boundingBox1.intersects( boundingBox2) )
I know this post is super old, but in case it helps anybody --
If you need to do a hit test on a movieclip that isn't on the stage. A workaround is to rasterize it to a bitmap first.
var bitmapData:BitmapData = new BitmapData(mc.width, mc.height, true, 0x0000000);
bitmapData.draw(mc);
if (bitmapData.getPixel32(x, y) > 0) {
// Hit true.
}

Finding (loaded) image size in AS3 (Action Script 3.0)

Im currently using the following function to load an image, however i could not figure out a way to find the width of the loaded image, which i intend to use before placing the next image using the same function.
Note that q is a a variable (a number) which is used to load differant images.
=X i need help obtainning the loaded image width...
function LoadImage(q)
{
var imageLoader:Loader = new Loader();
var image:URLRequest = new URLRequest("GalleryImages/Album1/"+q+".jpg");
imageLoader.load(image);
addChild (imageLoader);
imageLoader.x = 0 + CurrentXLength;
imageLoader.y = 0;
imageLoader.name = "image"+q;
trace(imageLoader.x)
}
You can't know the width of the bitmap until it's actually loaded:
function LoadImage(q)
{
var imageLoader:Loader = new Loader();
var image:URLRequest = new URLRequest("GalleryImages/Album1/"+q+".jpg");
imageLoader.contentLoader.addEventListener(Event.COMPLETE, ImageLoaded);
imageLoader.load(image);
addChild (imageLoader);
...
private function ImageLoaded(e:Event):void
{
var imageLoader:Loader = Loader(e.target.loader);
var bm:Bitmap = Bitmap(imageLoader.content);
var CurrentXLength = bm.width;
....
Alternativly this link might be helpful? Haven't tried it myself ...
I just asked for de width property of loader object:
var loader:Loader;
function loadImage(dir:String):void {
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, placeImage);
var urlReq:URLRequest = new URLRequest(direccion);
loader.load(urlReq);
}
function placeImage(o:Event):void {
loader.x = (1360 - loader.width)/2;
loader.y = (768 - loader.height)/2;
addChild(loader);
}
Where 1360 and 768 are the canvas dimensions...
To access the width you must do it within the function assigned to handle Event.COMPLETE.
"You will want an array containing the items you wish to load. You should probably load this data in with XML so it is dynamic and scalable. Once the xml data is loaded it should be assigned to an array in whatever fashion you like. The reason that we must use an array in this situation, rather then just using the XML object, which is essentially an array, is because you need the know an objects width so that you can base the next objects X position off of the last objects X position plus its WIDTH.
With XML it is common to use a for loop and just iterate through "x" amount of times. We do not want this, in this case. To obtain the "WIDTH" property of the loaded asset, it must be accessed from within the function assigned to fire when the loader fires Event.COMPLETE. Once the image has completed it will remove the item from the array, set a variable as to the lastX and lastWidth, and then get the next item in the array and start all over. Eventually the array is empty and the process is complete.
-Note: I will skip loading the XML and just inject the data into the array myself.
package
{
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
public class DocumentClass extends Sprite
{
private var _array:Array;
private var _lastX:Number;
private var _lastWidth:Number;
public function DocumentClass():void
{
_array = new Array();
//Add Items to an array however you wish. I did it
//this way to make it easier to read on this site.
_array.push({name: "image1", path: "path/to/image1"});
_array.push({name: "image2", path: "path/to/image2"});
_array.push({name: "image3", path: "path/to/image3"});
loadImage();
}
private function loadImage():void
{
if(_array.length > 0)
{
var loader:Loader = new Loader();
addChild(loader);
var request:URLRequest = new URLRequest(_array[0].path); //Loads first item in the array each time.
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
loader.x = _lastX + _lastWidth;
laoder.load(request);
_lastX = loader.x; //We set after so we are ready for the next.
_array.shift(); //Remove the first item from the array.
}
}
function onImageLoaded(e:Event):void
{
_lastWidth = e.target.width;
loadImage(); //Attempt to load another image if the array isn't empty.
}
}
}
I hope this helps, the code isn't tested, but the concept seems valid.
Yeah I used scott's answer but it's worth noting that 'imageLoader.contentLoader' should be 'imageLoader.contentLoaderInfo' in the LoadImage() function. Solved the width prob for me-- thanks mang