ActionScript3 issues - actionscript-3

So I'm having some issues with ActionScript. I'm creating a project where you are able to click on a penny and drag it to a scratch card, where you then scratch off the coating and text is revealed.
Everything is composed of two layers. The bottom layer is an image of the card with the text on it( I turned it into a bitmap). The top layer is a rectangle (scratch off coating) with a solid fill that I turned into a movie clip with a property name of maskee3. So far I was successful.
Where I ran into problems is when I tried adding another scratch card to the stage. I did the same process, turned the card into a bitmap and the rectangle scratch off coating (top layer) into a movie clip with a property name of maskee4. When I hit preview movie it still only scratches off the initial card. I honestly don't know what to do and how to fix this to make it scratch all of them.
Below is the coding I did, I have just been shooting in the dark at this point. Any help would be appreciated. Thanks!
/* Drag and Drop
Makes the specified symbol instance moveable with drag and drop.
*/
penny.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
penny.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
penny.stopDrag();
}
//start code for scratch off//
/*************************
MASKING
**************************/
/*
Initial variables
*/
// Change lineSize to control size of your eraser
var lineSize:Number=4;
// doDraw is true when user's mouse is down
var doDraw:Boolean=false;
// resumeDrawing is true when user drags their mouse off stage while drawing
var resumeDrawing:Boolean=false;
/*
Create a bitmap to act as our image mask
Add it to stage & cache as bitmap
*/
var erasableBitmapData:BitmapData = new BitmapData(400, 400, true, 0xFFFFFFFF);
var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
erasableBitmap.cacheAsBitmap = true;
addChild(erasableBitmap);
/*
Set the erasable bitmap as a mask of our image & cache image as bitmap
*/
maskee3.cacheAsBitmap = true;
maskee3.mask = erasableBitmap;
maskee4.cacheAsBitmap = true;
maskee4.mask = erasableBitmap;
/*************************
ERASER
**************************/
/*
Create a sprite for drawing the eraser lines onto
Set its lineStyle, and move the line to the current mouse x,y
*/
var eraserClip:Sprite = new Sprite();
initEraser();
function initEraser():void{
eraserClip.graphics.lineStyle(lineSize,0xff0000);
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
/*
Create a bitmap to copy the erased lines to.
This is required to ensure a smooth erase effect (applying eraserClip
directly to erasableBitmapData leaves jaggy edges around alpha areas.
If anyone knows why, I'd love to know!)
*/
var drawnBitmapData:BitmapData = new BitmapData(400, 400, true, 0x00000000);
var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);
/*************************
MOUSE EVENTS
**************************/
/*
Add event listeners for mouse movements
*/
stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
stage.addEventListener(MouseEvent.ROLL_OUT, maskOut);
stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
/*
Mouse down handler
Begin drawing
*/
function startDrawing(e:MouseEvent):void {
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
doDraw=true;
}
/*
Mouse up handler
Stop drawing
*/
function stopDrawing(e:MouseEvent):void {
doDraw=false;
resumeDrawing = false;
}
/*
Mouse out handler
If user was drawing when they moved mouse off stage, we will need
to resume drawing when they move back onto stage.
*/
function maskOut(e:Event):void {
if (doDraw){
resumeDrawing = true;
}
}
/*
Mouse over handler
If user's mouse if still down, continue drawing from the point where
the mouse re-entered the stage.
*/
function maskOver(e:MouseEvent):void {
if (resumeDrawing){
resumeDrawing = false;
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
}
/*
Mouse move handler
*/
function maskMove(e:MouseEvent):void {
if (doDraw && !resumeDrawing){
// Draw a line to current mouse position
eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
// Clear the drawn bitmap by filling it with a transparent color
drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000);
// Copy our eraser drawing into the erasable bitmap
// (This is required to ensure the smooth alpha edges on our eraser are retained)
drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
// Fill the erasable bitmap with a solid color
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
// Copy the scribble bitmap to our main bitmap, with blendmode set to ERASE
// This erases the portion of the mask that has been drawn.
erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
}
// Update after event to ensure no lag
e.updateAfterEvent();
}
/************************RESET BUTTON
**************************/
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event):void {
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
}

One "masker" has single "maskee" only.You can merge maskee if you prefer keep it single masker.
Simply replace this.
maskee3.cacheAsBitmap = true;
maskee3.mask = erasableBitmap;
maskee4.cacheAsBitmap = true;
maskee4.mask = erasableBitmap;
by this:
var container:Sprite = new Sprite();
container.addChild(maskee3);
container.addChild(maskee4);
container.cacheAsBitmap=true;
container.mask = erasableBitmap;
addChild(container);

Related

Stretch and rotate a Movieclip without distortion

i'm building a flash desktop app, where the user needs to link two Movieclips on stage (a computer and a router) using a line (or whatever can do the job), i want to achieve this same exact effect: image1. I searched and found this solution, i tried the code and did some modifications:
link.addEventListener(MouseEvent.CLICK, linkOnClick);
function linkOnClick(e:MouseEvent){
this.addEventListener(Event.ENTER_FRAME, enterFrame);
var linkPoint:Point = new Point(link.x, link.y);
var mousePoint:Point = new Point();
var distance:Number;
var radians:Number;
function enterFrame(e:Event):void {
//Distance
mousePoint.x = stage.mouseX;
mousePoint.y = stage.mouseY;
distance = Point.distance(linkPoint, mousePoint);
link.width = distance;
//Rotation
radians = Math.atan2(stage.mouseY - link.y, stage.mouseX - link.x);
link.rotation = radians * (180/ Math.PI);
if(link.hitTestObject(router)){trace("Success");}
}
When i compiled the code i got this: image2, so as you may remark, the problems i found are:
1-the edge of the line follows the direction of the mouse, but sometimes it goes beyond the cursor, i want the cursor to drag the edge of the line.
2-the line changes it's width, if it's 90° degrees the line width is so remarkable, i want the line to have a constant width.
how can i acheive the same exact effect shown in image1 ?
// First, lets create mouse-transparent container for drawing.
var DrawingLayer:Shape = new Shape;
addChild(DrawingLayer);
// Hook the event for starting.
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
// Define a storage for keeping the initial coordinates.
var mouseOrigin:Point = new Point;
function onDown(e:MouseEvent):void
{
// Save the initial coordinates.
mouseOrigin.x = DrawingLayer.mouseX;
mouseOrigin.y = DrawingLayer.mouseY;
// Hook the events for drawing and finishing.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onDraw);
}
function onDraw(e:MouseEvent):void
{
// Remove the previous line.
DrawingLayer.graphics.clear();
// Draw a new line.
DrawingLayer.graphics.lineStyle(5, 0xFF6600);
DrawingLayer.graphics.moveTo(mouseOrigin.x, mouseOrigin.y);
DrawingLayer.graphics.lineTo(DrawingLayer.mouseX, DrawingLayer.mouseY);
}
function onUp(e:MouseEvent):void
{
// Unhook the events for drawing and finishing.
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDraw);
}
It's because of that the actionscript is trying to stretch the line thickness by changing its container MovieClip's scale. But you can prevent this by setting the line Scale option to None.
To do that, select your line and open the properties menu and then select None from the drop down menu of the Scale option.
But,
I recommend you to draw a line by a code: Draw line from object to Mouse (AS3)
Write below code:
this.graphic.clear ();
this.graphic.lineStyle(0x000000);
this.moveTo(startPoint.x,startPoint.y);
this.lineTo(endpoint.X,endpoint.y);

Preventing the bounding box of transparent Bitmap Sprite from triggering mouse events

I thought I had solved my mouseEvent problem for Sprites containing a Bitmap with an alpha channel but I've encountered a new issue shown in the image below: the bounding box of the "Eurasia" map Sprite is triggering a `MouseEvent.Roll_Out" for the "Africa" Sprite.
My setup: Each map piece is a Sprite with a child Bitmap (PNG with alpha) and a "hitArea" Sprite derived from the Bitmap. The relevant code is below. This works great – except in the case where there are bounding box overlaps. The eventListeners I attach to each Sprite use MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT but I have also tried MouseEvent.MOUSE_OVER and MouseEvent.MOUSE_OUT.
I've tried attaching eventlisteners to the "hitArea" Sprite and various other things but I can't get the bounding box to be ignored. Are there any settings I may have missed – or a workaround?
Code:
buttonImage = new Bitmap(upImageData);
buttonImage.smoothing = true;
this.addChild(buttonImage);
hitSprite = createHitArea(upImageData, 4);
this.addChild(hitSprite);
hitSprite.visible = false;
hitSprite.mouseEnabled = false;
this.hitArea = hitSprite;
public function createHitArea(bitmapData:BitmapData, grainSize:uint=1):Sprite
{
var _hitarea:Sprite = new Sprite();
_hitarea.graphics.beginFill(0x000000, 1.0);
for(var x:uint=0;x<bitmapData.width;x+=grainSize) {
for(var y:uint=grainSize;y<bitmapData.height;y+=grainSize) {
if(x<=bitmapData.width && y<=bitmapData.height && bitmapData.getPixel(x,y)!=0) {
_hitarea.graphics.drawRect(x,y,grainSize,grainSize);
}
}
}
_hitarea.graphics.endFill();
_hitarea.cacheAsBitmap = true;
return _hitarea;
}
If using a vector mask is not a viable option (it should work if you changed your hitSpite into a Shape and then made it the mask of the map piece sprite - also you'd have to add it as a sibling of the map piece and not a child), then the way most people do this is checking if the pixel under the mouse is transparent or not.
Here is an example:
Let's say all your map pieces are the sole children of a Sprite referenced in a var called container. Let's also make the assumption for the example, that your map pieces are all Sprites that have the png Bitmap as the bottom most child.
You need to add the click listener to the container (instead of each individual map piece):
container.addEventListener(MouseEvent.CLICK,click);
function click(e:MouseEvent):void {
var child:Sprite; //a helper var to store the current iterations child below in the while loop
var target:Sprite; //the item that we determined was clicked
//iterate through all children of container (backwards, so we process the top most layer first)
var i:int = container.numChildren;
while(i--){
child = container.getChildAt(i) as Sprite; //populate the child var
//now we check if the mouse is over this child by a simple hit test point
//we also then check if the pixel under the mouse is transparent (a value of 0)
if(child.hitTestPoint(e.stageX, e.stageY) && Bitmap(child.getChildAt(0)).bitmapData.getPixel32(child.x + e.localX,child.y + e.localY)){
target = child;
break; //break out of the loop since we found a child that meets the criteria
}
}
trace(target);
//now do something with target
}

Flash AS3: Error with stop button for game?

I am making a small game from a tutorial where you hit small tofu's with your cursor and gather up points and accuracy - I have implemented a start button that works and goes to frame(2), where the game starts.
I would like to create a stop button but when i make a button in the scene - the button does not function (cant click on it) and when i hit a tofu it gets the 1009 error? (Cannot access a property or method of a null object reference.)
The game works when i have no stop button but i can't exit the game.
How can i create a stop button or a menu inside the game that allows the user to go back to a previous scene or stop the game?
// define some global variables which let you track the player's statistics.
var hits:int = 0;
var misses:int = 0;
var shots:int = 0;
var cDepth:int = 100;
var level:int = 1;
// define some runtime variables which are used in calculations.
var xSpeed:Number = 3;
var stageWidth:Number = 480;
var stageHeight:Number = 580;
/* attach the crosshair_mc movie clip instance from the Library onto the Stage.
This clip is used as a custom mouse cursor. */
var crosshairClip:MovieClip = new crosshair_mc();
crosshairClip.mouseEnabled = false;
addChild(crosshairClip);
// hide the mouse cursor
Mouse.hide();
/* every time the mouse cursor moves within the SWF file,
update the position of the crosshair movie clip instance on the Stage. */
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
function mouseMoveHandler(event:MouseEvent):void {
crosshairClip.x = event.stageX;
crosshairClip.y = event.stageY;
};
/* when the mouse button is clicked, check to see if the cursor is within the boundaries of the Stage.
If so, increment the number of shots taken. */
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(event:MouseEvent):void {
if (bg_mc.hitTestPoint(event.stageX, event.stageY, false)) {
shots++;
updateStats();
}
};
// define a TextFormat which is used to format the stats_txt text field.
var my_fmt:TextFormat = new TextFormat();
my_fmt.bold = true;
my_fmt.font = "Arial";
my_fmt.size = 12;
my_fmt.color = 0xFFFFFF;
// create a text field to display the player's statistics.
var stats_txt:TextField = new TextField();
stats_txt.x = 10;
stats_txt.y = 0;
stats_txt.width = 530;
stats_txt.height = 22;
addChild(stats_txt);
// apply the TextFormat to the text field.
stats_txt.defaultTextFormat = my_fmt;
stats_txt.selectable = false;
updateStats();
// add an onEnterFrame event to the main timeline so new tofu is constantly added to the game.
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler(event:Event):void {
// randomly add new target's to the Stage.
if (randRange(0, 20) == 0) {
var thisMC:MovieClip;
// attach a new instance of the tofu instance from the library onto the Stage, and give it a unique depth.
var randomTofu:Number = randRange(1, 3);
switch (randomTofu) {
case 1:
thisMC = new tofu1_mc();
break;
case 2:
thisMC = new tofu2_mc();
break;
case 3:
thisMC = new tofu3_mc();
break;
default:
return;
break;
}
cDepth++;
// set the starting postition of the current target movie clip so it is just off to the left of the Stage.
thisMC.x = -thisMC.width;
/* create a random number between 80 and 100.
This is used to set the current movie clip's scale,
alpha and speed that it moves across the Stage. */
var scale:int = randRange(80, 100);
/* set the _xscale and _yscale properties of the current movie clip.
This allows for some minor variations of the targets within the game. */
thisMC.scaleX = scale / 100;
thisMC.scaleY = scale / 100;
thisMC.alpha = scale / 100;
thisMC.speed = xSpeed + randRange(0, 3) + level;
/* set a random _y value for the target.
Now, instead of all targets flying along the same path,
they vary their vertical position slightly. */
thisMC.y = Math.round(Math.random() * 350) + 65;
thisMC.name = "tofu" + cDepth;
/* create an onEnterFrame handler that executes a couple dozen times per second.
Update the target's position on the Stage. */
thisMC.addEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler);
thisMC.addEventListener(MouseEvent.CLICK, tofuClickHandler);
addChild(thisMC);
// swap the custom cursor to the higher depth
swapChildren(thisMC, crosshairClip);
}
};
/* create a function to update the player's statistics on the Stage.
You're displaying number of shots taken, number of targets "hit",
number of targets "missed", the percentage of hits vs misses,
overall accuracy (number of shots taken vs number of hit targets). */
function updateStats() {
var targetsHit:Number = Math.round(hits/(hits+misses)*100);
var accuracy:Number = Math.round((hits/shots)*100);
if (isNaN(targetsHit)) {
targetsHit = 0;
}
if (isNaN(accuracy)) {
accuracy = 0;
}
stats_txt.text = "shots:"+shots+"\t"+"hits: "+hits+"\t"+"misses: "+misses+"\t"+"targets hit: "+targetsHit+"%"+"\t"+"accuracy: "+accuracy+"%"+"\t"+"level:"+level;
}
/* create a function that returns a random integer between two specified numbers.
This allows you to add some subtle differences in size and speed for the movie clips on the Stage. */
function randRange(minNum:Number, maxNum:Number):Number {
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
function tofuEnterFrameHandler(event:Event):void {
var tofuMC:MovieClip = event.currentTarget as MovieClip;
/* move the target horizontally along the Stage.
Currently all targets will move from left to right. */
tofuMC.x += tofuMC.speed;
/* slightly decrement the _y position of the current target movie clip.
This makes it appear like the targets are flying slightly higher as they move across the Stage. */
tofuMC.y -= 0.4;
/* if the current position of the target is no longer on the Stage,
count the target as a "miss" and delete the instance.
If the instance wasn't deleted from the Stage,
the user's computer would eventually slow to a crawl. */
if (tofuMC.x > stageWidth) {
misses++;
updateStats();
removeChild(tofuMC);
tofuMC.removeEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler);
}
}
// when the target movie clip instance is pressed, count it as a "hit".
function tofuClickHandler(event:MouseEvent):void {
var tofuMC:MovieClip = event.currentTarget as MovieClip
// update the player's stats
hits++;
if ((hits%40) == 0) {
level++;
}
updateStats();
/* go to the movie clip's label named "hit"
(which allows you to show a clever animation when the instance is hit.) */
tofuMC.gotoAndPlay("hit");
// create an onEnterFrame event for the current movie clip instance.
tofuMC.addEventListener(Event.ENTER_FRAME, tofuHitEnterFrameHandler);
/* delete the onPress event handler.
This makes it so the target cannot continually be clicked while it is falling from the sky. */
tofuMC.removeEventListener(MouseEvent.CLICK, tofuClickHandler);
tofuMC.removeEventListener(Event.ENTER_FRAME, tofuEnterFrameHandler);
}
function tofuHitEnterFrameHandler(event:Event):void {
var tofuMC:MovieClip = event.currentTarget as MovieClip;
// set some local variables that you'll use to animate the target falling from the sky.
var gravity:int = 20;
var ymov:int = tofuMC.y + gravity;
// ***** xmov *= 0.5;
// increment the rotation of the current movie clip clock-wise by 5 degrees.
tofuMC.rotation += 5;
/* set the _x and _y properties of the movie clip on the Stage,
this allows us to make the target look like it is semi-realistically
falling from the sky instead of just dropping straight down. */
tofuMC.x += xSpeed;
tofuMC.y = ymov;
/* after the _y position is off of the Stage,
remove the movie clip so that the coordinates aren't continually calculated */
if (tofuMC.y > stageHeight) {
removeChild(tofuMC);
tofuMC.removeEventListener(Event.ENTER_FRAME, tofuHitEnterFrameHandler);
}
}
The stage is confused, because some objects don't exist when you change frames, so you have to remove all of your events from the stage:
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
And then you can call the gotoAndStop() function to whatever frame you want...

unselect sprite clicking somewhere else on stage or other movieclips

In my scenario I have a sprite "imgSprite" with dynamically loaded image. I have drawn a small box near bottom left corner inside this sprite named "rectangle". The imageSprite is also drag/drop able. When I click on the image I set it to show rectangle but I can not figure out how to hide it clicking somewhere outside imgSpirte.
var imgSprite:Sprite = new Sprite();
imgSprite.addChild(image);
MovieClip(root).addChild(imgSprite);
/* DELETE BUTTON */
var rectangle:Sprite = new Sprite();
rectangle.graphics.beginFill(0xFF0000);
rectangle.graphics.drawRect(0, 0, 20,20);
rectangle.graphics.endFill();
rectangle.y=imgSprite.y+imgSprite.height;
rectangle.x=imgSprite.x-20;
imgSprite.addChild(rectangle);
rectangle.addEventListener(MouseEvent.CLICK, function() {
rectangle.parent.parent.removeChild(imgSprite);
});
imgSprite.addEventListener("mouseDown", function() {
imgSprite.startDrag();
rectangle.visible = true;
});
stage.addEventListener("mouseUp", function() {
imgSprite.stopDrag();
});
/*
imgSprite.addEventListener("mouseOut", function() {
var timer = setInterval(deSelect,3000);
function deSelect(){
rectangle.visible = false;
clearInterval(timer);
}
});
*/
You can try a temporary listener for stage. Say, like this:
if (rectangle) rectangle.visible=false; // or it won't trigger
imgSprite.addEventListener("mouseDown",onMouseDown);
function onMouseDown(e:MouseEvent):void {
if (rectangle) if (!rectangle.visible)
stage.addEventListener("mouseDown",removeRectangle);
imgSprite.startDrag();
rectangle.visible=true;
e.stopPropagation(); // this is needed to not get the rectangle removed as soon as you click on imgSprite
}
function removeRectangle(e:MouseEvent):void {
if (rectangle) rectangle.visible=false;
stage.removeEventListener("mouseDown",removeRectangle);
}
It works like this: As soon as you click on the imgSprite, a listener gets assigned to stage and the rectangle is made visible. If you click on imgSprite again, the rectangle is already visible, so no extra listeners are added. Also e.stopPropagation() prevents an existing listener to get triggered and get the rectangle hidden. And as soon as you click elsewhere but on imgSprite, the listener gets triggered, removes itself from stage, and hides rectangle.

Actionscript Image with clickable spots

Can any one help in suggesting a solution for the following:
i have a large image, consider it as a map, i want to put this image in a viewer that is smaller than the image and i have to be able to scroll the image by clicking and dragging it.
and i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots.
when clicking any spot in the image, the image will be changed with a new spots.. and so on..
can you help in suggesting what is the best object to load the image in and be able to do all the mentioned points.
Thanks in advance.
This is easier than you think. You have a few goals to consider:
"i want to put this image in a viewer that is smaller than the image": You dont need anything special to do this. The concept of this is simply that you have a mask overlay where you want the large image visible.
var viewer:Sprite = new Sprite; //200x200
var imageMask:Sprite = new Sprite; //200x200
var imageContainer:Sprite = new Sprite; //400x500
imageContainer.mask = imageMask;
viewer.addChild(imageContainer);
//this will allow you to visibly see only 200x200 of the
//imageContainer at any time
"i have to be able to scroll the image by clicking and dragging it": This is a little more logic as the imageContainer will have to move in the -(negative) direction of the mouse. Add some listeners to check for mouse actions, and drag as required.
var allowDrag:Boolean = false;
imageContainer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
imageContainer.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
imageContainer.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
function onMouseDown(e:Event):void{
allowDrag = true;
}
function onMouseUp(e:Event):void{
allowDrag = false;
}
function onMouseMove(e:Event):void{
//return if not dragging
if(!allowDrag) return;
//move the imageContainer in a -(negative) direction of the mouse
//use an index relative to the size of the viewer and imageContainer
var speed:Number = 0.5;
imageContainer.x -= (viewer.width/imageContainer.width)*speed;
imageContainer.y -= (viewer.height/imageContainer.height)*speed;
//clean the positions so the image remains within the viewer
if(imageContainer.x > 0) imageContainer.x = 0;
if(imageContainer.x < -viewer.width) imageContainer.x = -viewer.width;
if(imageContainer.y > 0) imageContainer.y = 0;
if(imageContainer.y < -viewer.height) imageContainer.y = -viewer.height;
}
"i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots": This also requires a little more thinking. In this case what you want to do is create [hotspots] on the image that are clickable, when clicked = do actions.
//USAGE
//define the click area coords
var clickCoords:Rectangle = new Rectangle();
clickCoords.x = 10; //starts at x 10
clickCoords.y = 10; //starts at y 10
clickCoords.width = 100; //100 wide
clickCoords.height = 100; //100 tall
//add the click listener
var clickArea:Sprite = hotSpot(imageContainer,clickCoords);
clickArea.addEventListener(MouseEvent.CLICK, onHotSoptClick);
//hot spot factory
function hotSpot(target:Sprite,coords:Rectangle):Sprite{
//create the hotspot
var hs:Sprite = new Sprite;
hs.graphics.beginFill(0,0);
hs.graphics.drawRect(0,0,coords.width,coords.height);
hs.graphics.endFill();
//add the hotspot to the target
hs.x = coords.x;
hs.y = coords.y;
target.addChild(hs);
}
function onHotSoptClick(e:MouseEvent):void{
//do something
}
IMPORTANT:
You may want to keep a list of hot spots you create so you can do garbage cleanup, and you plan on dynamically generating hotspots per image... then YOU MUST keep an active list of hot spots and remove when not in use.
You can catch the events MouseDown, MouseUp, MouseMove, MouseOut, on your viewing window, this way you can control exactly what do you want to do.
Here is the pseudo-code:
reset()
{
isDown=false;
downPointX=0;
downPointY=0;
distanceX=0;
distanceY=0;
}
onMouseDown()
{
isDown=true;
downPointX=mouseX;
downPointY=mouseY;
}
onMouseUp()
{
if(distanceX+distanceY==0 and isDown)
click(downPointX,downPointY);
reset();
}
onMouseMove()
{
if isDown then
distanceX=mouseX-downPointX;
distanceY=mouseY-downPointY;
drag(distanceX,distanceY);
endif;
}
onMouseOut()
{
reset();
}
drag(distanceX,distanceY)
{
change your map coordinates
}
click(downPointX,downPointY)
{
if(inSpot(downPointX,downPointY)==true)
changeMap();
endif;
}
changeMap()
{
change your maps and spots
}
avoid implementing any event for your spots sprites or you can get unexpected results.
You can check these for more information
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Sprite.html#eventSummary