Issue with sharedObject usage / loading data - actionscript-3

The main goal of my code is to create a 3x3 grid and when you click a cell from that grid you cant click it again even if you close the fla and load it again.
Something like a shop where the 1st row is level1 of the upgrade and the columns are the other levels.
There are also 2-3 other things that it does -> every cell of the grid has 4 mouseStates.
Also at the 1st load of the FLA you create the 3x3 grid and you can click only on the elements in the 1st row.(you cant get Speed 2 if you didnt have Speed1 before that.)
So you can click the 2nd element of a column only if the 1st element of the same column has been clicked before.
The same goes for the 3rd element of the column -> it can be clicked only if the 2nd was clicked before.
But im having trouble with the logic after loading the fla for the 2nd time.
To be more specific :
It is changing the mouseOver/out states on the elements that were clicked before(which is good (cause i want to see that)), but it is leting me click only the 1st row.And since Im loading the clickedBefore buttons and removing the mouseEvent.CLICK from them, I cant click some of them if i haven`t clicked them at the 1st load of the fla.
I have 2 classes: Main
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.getDefinitionByName;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.Bitmap;
import flash.display.SimpleButton;
import flash.net.SharedObject;
public class Main extends Sprite
{
private var elementRow:int = 0;
private var elementCol:int = 0;
private var myClassImage_Arr:Array = new Array();//this contains the different mouseState Images in Class data.
private var myBitmapNames_Arr:Array = ["speed1_", "speed2_", "speed3_",
"time1_", "time2_", "time3_",
"turbo1_", "turbo2_", "turbo3_",];
//------------------------------------------
private var index:int = 0;
private var col:int = 3;
private var row:int = 3;
//------------------------------------------
private var savedData:SharedObject = SharedObject.getLocal("ZZZ_newWAY_nextButton+imageChange_7");
private var buttonThatHaveBeenClicked_Arr:Array = [];
private var myButtons_Arr:Array = [];
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
for (var i:int = 0; i < col; i++)
{
var lastRowElement:BitmapButton = null;
for (var j:int = 0; j < row; j++)
{
for (var k:int = 0; k < 4; k++)//4states of mouse
{
var cls:Class = Class(getDefinitionByName(myBitmapNames_Arr[index] + k));
myClassImage_Arr.push(cls);
}
var myImage_mc = new BitmapButton(myClassImage_Arr[0 + (index * 4)],
myClassImage_Arr[1 + (index * 4)],
myClassImage_Arr[2 + (index * 4)],
myClassImage_Arr[3 + (index * 4)], i, j);
myImage_mc.x = 100 + i * (myImage_mc.width + 10);
myImage_mc.y = 100 + j * (myImage_mc.height + 10);
myImage_mc.name = "myImage_mc" + index;
this.addChild(myImage_mc);
myButtons_Arr.push(myImage_mc)
myImage_mc.mouseEnabled = false;
myImage_mc.mouseChildren = false;
myImage_mc.buttonMode = false;
myImage_mc.addEventListener("send_SOS", onCustomClick);
if ( lastRowElement == null )
{
myImage_mc.mouseEnabled = true;
myImage_mc.mouseChildren = true;
myImage_mc.buttonMode = true;
}
else
{
lastRowElement.next_1 = myImage_mc;
}
lastRowElement = myImage_mc;
index++;
}
}
if(savedData.data.myArray == undefined) trace(" 1st time loading this game\n")
else if(savedData.data.myArray != undefined)
{
trace(" Game was played before\n")
buttonThatHaveBeenClicked_Arr = savedData.data.myArray;
var savedData_length:int = savedData.data.myArray.length;
trace("Buttons that have been clicked before: " + buttonThatHaveBeenClicked_Arr + "\n");
for (var m:int = 0; m < myButtons_Arr.length; m++)
{
var myButtons_ArrName:String = myButtons_Arr[m].name
for (var p:int = 0; p < savedData_length; p++)
{
if(myButtons_ArrName == savedData.data.myArray[p])
{
myButtons_Arr[m].alpha = 0.9
myButtons_Arr[m].buttonMode = false;
myButtons_Arr[m].removeEventListener("send_SOS", onCustomClick);
myButtons_Arr[m].myInsideBtn.upState = myButtons_Arr[m].image3
myButtons_Arr[m].myInsideBtn.overState = myButtons_Arr[m].image4
}
}
}
}
}
private function onCustomClick(ev:Event):void
{
trace(ev.target.name);
if (ev.target is BitmapButton)
{
var btn:BitmapButton = ev.currentTarget as BitmapButton;
if (btn.next_1 != null)
{
btn.next_1.mouseEnabled = true;
btn.next_1.mouseChildren = true;
btn.next_1.buttonMode = true;
}
btn.mouseChildren = false;
btn.buttonMode = false;
btn.removeEventListener("send_SOS", onCustomClick);
buttonThatHaveBeenClicked_Arr.push( btn.name );
savedData.data.myArray = buttonThatHaveBeenClicked_Arr;
savedData.flush();
savedData.close();
}
}
}
}
and BitmapButton
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.events.Event;
public class BitmapButton extends Sprite
{
public var next_1:BitmapButton = null;
//-----------------------------------
public var myInsideBtn:SimpleButton = new SimpleButton();
private var image1:Bitmap;
private var image2:Bitmap;
public var image3:Bitmap;
public var image4:Bitmap;
public var imageIsInRow:int;
public var imageIsInCol:int;
public function BitmapButton(active_OutState:Class, active_OverState:Class, notActive_OutState:Class, notActive_OverState:Class,col:int,row:int)
{
image1 = new Bitmap (new active_OutState() );
image2 = new Bitmap (new active_OverState() );
image3 = new Bitmap (new notActive_OutState() );
image4 = new Bitmap (new notActive_OverState() );
imageIsInRow = row;
imageIsInCol = col;
myInsideBtn.upState = image1;
myInsideBtn.overState = image2;
myInsideBtn.downState = myInsideBtn.upState;
myInsideBtn.hitTestState = myInsideBtn.overState;
addChild( myInsideBtn );
myInsideBtn.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(ev:MouseEvent):void
{
myInsideBtn.upState = image3;
myInsideBtn.overState = image4;
var myNewEvent:Event = new Event("send_SOS");
this.dispatchEvent(myNewEvent);
trace("CLICK from inside the button");
}
}
}
ill also upload it to this link Grid_with_sharedObject with a zip.
and upload also Grod_before_Using_sharedObject if someone decides that he would help but the code is to messed up

If I'm reading your code correctly, I'd honestly say your problem is sequential. For whatever reason, the setting of the active and inactive rows is occurring BEFORE the data is actually being interpreted into the button states. As a result, the computer sees all buttons as off when it decides whether to make other rows clickable, and THEN updates the state of the buttons.
The easiest way to fix this, I think, would be to split the Main() function into a few sub functions, such as updateButtons() for the function that changes whether a row/button is clickable, and loadData() for the function the loads from the SharedObject. In Main(), put the calls to those functions. This will make Main() easier to work with, and you can call a function multiple times if necessary.
To solve your particular issue, you'd need to get the data for the buttons using the SharedObject FIRST (which obviously is working), and THEN update whether the other buttons are clickable.
A "soft-skills" tip for programming: when you run into a problem, grab a piece of paper, a pencil, and read through your code the way your computer would. Be the computer. Write down variables and their values when they change. Mark when functions are called. You'll spot a lot of errors this way.

Related

Access of undefined propety and other errors (AS3)

ok so I am trying to work on making my scripts external .as files.
I had them on the timeline and they worked fine but when I put them in the as file they don't work at all.
This is my code as of right now
so I got the script working externally thank you very much :)
I just need to addchild to the stage. I use
import Scripts.resources.main;
var Main:main = new main;
addChild(Main);
In my external script I addchild in the main function now.
package Scripts.resources
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoader;
import flash.net.URLRequestMethod;
import flash.events.OutputProgressEvent;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.EventDispatcher;
public class main extends EventDispatcher{
private var _stage:Stage;
var url:String = "php/data_user.php";
//declare our graphic vars
var stmBar:resourceBar;
var tenBar:resourceBar;
var potBar:resourceBar;
var spdBar:resourceBar;
var crtBar:resourceBar;
var awrBar:resourceBar;
var resBar:resourceBar;
var statUp:Sprite;
//This Returns the number of milliseconds since midnight January 1, 1970
//Tacking the time variable at the end of your php file locations will ensure their is no caching
var now:Date = new Date();
var time:Number = now.getTime();
/*
* These should point to your PHP files. I recommend NOT using an http path because accessing
* the site via 'www.yoursite.com' versus 'yoursite.com' makes a difference and will cause undefined
* issues. Instead use a relative path like: var registerLocation:String = "membership/php/register.php";
*/
var registerLocation:String = "php/register.php" + "?" + time;
var loginLocation:String = "php/login.php" + "?" + time;
var editProfileLocation:String = "php/editprofile.php" + "?" + time;
var forgotPWLocation:String = "php/forgotpw.php" + "?" + time;
var statsLocation:String = "php/user_stats.php" + "?" + time;
var statsGylph:String = "php/data_user.php" + "?" + time;
//userInfo is the Object that gets populated that stores all of the users information.
var userInfo:Object = new Object();
//The minimum length of a password.
var passwordLength:Number = 4;
/*
* var cookie refers to swfObjects addVariable. If you look at membership.php, where swf
* object is defined, addVariable shows a var called usercookie.
* This help decide if the program should remember the users username or not.
*/
//cookieUserName would be the username that gets put into the user field if the cookie has been set
public function main(stage:Stage)
{
_stage = stage;
var _loader:URLLoader = new URLLoader();
var _request:URLRequest = new URLRequest(url + "?id=" + userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
_stage.addChild(stmBar);
stmBar.x = -50;
stmBar.y = 200;
}
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
function onLoadData(e:Event):void {
var str:String = e.target.data;
var array:Array =str.split("-");
for(var i:int;i < array.length; i++)
output(i+1,array[i]);
}
public function output(field:Number,i:int):void
{
if (field == 5)
{
stmBar = new resourceBar(0, 0, i, "Stamina", 0x990000);
stmBar.x = -200;
stmBar.y = 50;
}
else if (field == 6)
{
tenBar = new resourceBar(0, 0, i, "Tenacity", 0xFF9900);
tenBar.x = 200;
tenBar.y = 50;
}
else if (field == 7)
{
potBar = new resourceBar(0, 0, i, "Potency", 0xCC3399);
potBar.x = -200;
potBar.y = 100;
}
else if (field == 8)
{
spdBar = new resourceBar(0, 0, i, "Speed", 0x00CC00);
spdBar.x = 200;
spdBar.y = 100;
}
else if (field == 9)
{
crtBar = new resourceBar(0, 0, i, "Crit", 0x009999);
crtBar.x = -200;
crtBar.y = 150;
}
else if (field == 10)
{
awrBar = new resourceBar(0, 0, i, "Awareness", 0x3399CC);
awrBar.x = 200;
awrBar.y = 150;
}
else if (field == 11)
{
resBar = new resourceBar(0, 0, i, "Resistance", 0x999999);
resBar.x = -200;
resBar.y = 200;
addEventListener(Event.ENTER_FRAME, onLoop);
}
function onLoop(e:Event):void
{
stmBar.change(1);
tenBar.change(1);
potBar.change(1);
spdBar.change(1);
crtBar.change(1);
awrBar.change(1);
resBar.change(1);
}
}
}
}
my problem is it won't add the children in the main function when I addchild of main. am I able to add a child with children inside it?
In class files, all code needs to be wrapped in a function. So where you have:
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
You need to place it in a function for the code to be valid. If you want that bit of code to run right away, then you can place it in a constructor (that is the function in class that runs when you instantiate with the new keyword, eg new main(). If main is your document class, then the constructor is the very first code to run in the application.
Constructors are public functions that have the exact name of your Class.
public function main(){
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
}
Something to keep in mind, is that in the constructor of display objects, the stage/parent/root keywords will NOT have any value, as those are populated once the display object has been added to the display. So, it's common to use this approach:
package MyClass extends Sprite {
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
}
Also, a tip now that you are writing class files - follow the convention of making class names start with an Uppercase letter, and instances of classes start with lowercase letters.

How to run an external action script file at a specify frame?

Sorry for the vague question. The point is I would like to run an external actionscript(.as) file at a specify frame so that it won't run unless I clicked start button from the main menu. This is to make sure the game sprites won't appear on the main menu. I have tried "Export classes in frame" option but it won't work. The actionscript is already set to document class. I have no code placed on timeline.
The external actionscript code to my game:
package
{
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.media.*;
import com.greensock.*;
public class image_match extends MovieClip
{
private var first_tile:images;
private var second_tile:images;
private var pause_timer:Timer;
var imagedeck:Array = new
Array(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12);
var theFirstCardSound:FirstCardSound = new FirstCardSound();
var theMissSound:MissSound = new MissSound();
var theMatchSound:MatchSound = new MatchSound();
var playerScore:Number = 0;
public function image_match()
{
trace(this.currentFrame);
for (x = 1; x <= 6; x++)
{
for (y = 1; y <= 4; y++)
{
var random_card = Math.floor(Math.random() *
imagedeck.length);
var tile:images = new images ;
tile.col = imagedeck[random_card];
imagedeck.splice(random_card,1);
tile.gotoAndStop(13);
tile.x = 95;
tile.y = 145;
tile.x += (x - 1) * 122;
tile.y += (y - 1) * 132;
tile.addEventListener(MouseEvent.CLICK,tile_clicked);
tile.addEventListener(MouseEvent.MOUSE_OVER, glow);
tile.addEventListener(MouseEvent.MOUSE_OUT, noGlow);
tile.buttonMode = true;
addChild(tile);
}
}
}
//Function to create glow effect.
function glow(event:MouseEvent):void
{
TweenMax.to(event.currentTarget, 0.3, {glowFilter:{color:0x0000ff,
alpha:1, blurX:10, blurY:10,strength:0.7}});
}
//Function to remove glow effect.
function noGlow(event:MouseEvent):void
{
TweenMax.to(event.currentTarget, 0.5, {glowFilter:{alpha:0}});
}
public function tile_clicked(event:MouseEvent)
{
var clicked:images = event.currentTarget as images;
if ((first_tile == null))
{
first_tile = clicked;
theFirstCardSound.play();
first_tile.gotoAndStop(clicked.col);
}
else if (((second_tile == null) && first_tile != clicked))
{
second_tile = clicked;
second_tile.gotoAndStop(clicked.col);
if (first_tile.col == second_tile.col)
{
theMatchSound.play();
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
pause_timer.start();
playerScore += 200;
}
else
{
theMissSound.play();
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
pause_timer.start();
playerScore -= 20;
}
}
updateScore();
}
public function updateScore():void
{
scoreText.text = playerScore.toString();
trace("Score: " + scoreText.text);
}
public function reset_tiles(event:TimerEvent)
{
first_tile.gotoAndStop(13);
second_tile.gotoAndStop(13);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
}
public function remove_tiles(event:TimerEvent)
{
removeChild(first_tile);
removeChild(second_tile);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
}
}
}
The external code you posted is a class. That means the code in it will not run before you create an instance of it. Move the instance creation to the frame where you wish the code to be executed and you should be getting the behaviour you asked for.
If you don't know what an instance is, look for a line that contains something like:
...=new match_it();
addChild(...);
Those 2 lines create an instance of the match_it class and add it to the display hierachy. Move them to the frame in question. There might be more code that is required to be moved, but since you didn't paste the actual instantiation, that's something that I can't really tell.
I also would suggest taking a look at the basics of as3 classes, it will make your life a lot easier, here's an tutorial:
http://www.untoldentertainment.com/blog/2009/08/25/tutorial-understanding-classes-in-as3-part-1/

ScrollPane and ScrollBar not working

I have an application I'm trying to build where it will display a large map image (1920x1040 which is set as the base layer of frame one, then all my AS is on the layer above on the first frame too), then draw lines to it by reading in their coordinates from an external file (lines.txt) and associate a particular image with each line.
When a user clicks on a line, a ScrollPane should open, showing the image associated with the line they clicked on. These images are 1040 in height, and at least 4000px wide, so I want the image to fill the screen height, and then allow the user to use a scroll bar along the bottom to scroll left and right to see the full image.
Right now, I have it working where it reads in my lines.txt file, and draws the lines correctly. Then when I click on a line, it will load the corresponding image in the ScrollPane (along with a button to click that will remove the scroll pane and allow them to select a new line).
However, I can't get a horizontal scroll bar to work. I have it so that the space shows up at the bottom where a scroll bar should be, but there's no bar to drag left/right, and no way to scroll around.
I saw that it's possible to use dragging to scroll, which would be nice, but that hasn't worked either (it' now commented out), and when I have it turned on, when I click my Back Button and attempt to click another line, it throws an error saying,
"TypeError: Error #1009: Cannot access a property or method of a null object reference.
at fl.containers::ScrollPane/endDrag()"
Anybody able to help me clean this up and get it figured out what's going wrong here?
My code:
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import fl.containers.ScrollPane;
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy;
import fl.controls.DataGrid;
import fl.data.DataProvider;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import fl.controls.UIScrollBar;
import flash.events.Event;
import fl.controls.ScrollBar;
var worldLines:Array = new Array();
var lineSprites:Array = new Array();
var lineSpritesLength:int;
var basicColorTransform:ColorTransform = new ColorTransform();
basicColorTransform.color = 0x00FF00;
var hoverColorTransform:ColorTransform = new ColorTransform();
hoverColorTransform.color = 0xFFFF00;
populateWorldLines();
function populateWorldLines():void
{
var textFile:File = File.applicationDirectory.resolvePath("lines.txt");
var fileContents:String = getFileData(textFile);
var contentsLength:int = fileContents.split("$").length;
for(var i:int = 0; i < contentsLength; i++)
{
trace(i);
worldLines[i] = new Object();
worldLines[i]["x1"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["y1"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["x2"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["y2"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["image"] = fileContents.slice(0, fileContents.indexOf(";"));
fileContents = fileContents.slice(fileContents.indexOf("$") + 1, fileContents.length);
}
drawLines(worldLines);
}
function drawLines(lines:Array):void
{
for(var i:int = 0; i < lines.length; i++)
{
var line:Sprite = new Sprite;
line.graphics.moveTo(lines[i]["x1"], lines[i]["y1"]);
line.graphics.lineStyle(3, basicColorTransform.color);
line.graphics.lineTo(lines[i]["x2"], lines[i]["y2"]);
lineSprites.push(line);
addChild(line);
}
lineSpritesLength = lineSprites.length;
this.addEventListener(MouseEvent.MOUSE_OVER, checkLines);
}
function checkLines(e:MouseEvent):void
{
var targetSprite:* = e.target;
for(var i:int = 0; i < lineSpritesLength; i++)
{
if(targetSprite == lineSprites[i])
{
targetSprite.transform.colorTransform = hoverColorTransform;
targetSprite.addEventListener(MouseEvent.CLICK, lineClicked);
targetSprite.addEventListener(MouseEvent.MOUSE_OUT, resetColorTransform);
}
}
}
function lineClicked(e:MouseEvent):void
{
var targetSprite:* = e.target;
for(var i:int = 0; i < lineSpritesLength; i++)
{
if(targetSprite == lineSprites[i])
{
showImage(worldLines[i]["x1"], worldLines[i]["y1"], worldLines[i]["image"]);
}
}
//e.target.removeEventListener(e.type, lineClicked);
}
function showImage(xPos:int, yPos:int, imageName:String):void
{
var aSp:ScrollPane = new ScrollPane();
var aBox:MovieClip = new MovieClip();
drawBox(aBox, imageName);
aSp.source = aBox;
aSp.setSize(1920, 1040);
aSp.move(0, 0);
aSp.name = "scrollyPaneThing";
//aSp.scrollDrag = true;
aSp.horizontalScrollPolicy=ScrollPolicy.ON;
aSp.addEventListener(ScrollEvent.SCROLL, scrollListener);
addChild(aSp);
}
function scrollListener(event:ScrollEvent):void {
var mySP:ScrollPane = event.currentTarget as ScrollPane;
trace("scrolling");
trace("\t" + "direction:", event.direction);
trace("\t" + "position:", event.position);
trace("\t" + "horizontalScrollPosition:", mySP.horizontalScrollPosition, "of", mySP.maxHorizontalScrollPosition);
trace("\t" + "verticalScrollPosition:", mySP.verticalScrollPosition, "of", mySP.maxVerticalScrollPosition);
};
function drawBox(box:MovieClip,imageName:String):void {
trace(imageName + ":imageName");
var file:File = File.applicationDirectory.resolvePath("dataImages/"+imageName);
var imageLoader:Loader = new Loader();
var image:URLRequest = new URLRequest(file.url);
imageLoader.load(image);
imageLoader.x = 1;
imageLoader.y = 1;
box.addChild (imageLoader);
trace("backButton.png:imageName");
var file2:File = File.applicationDirectory.resolvePath("backButton.png");
var imageLoader2:Loader = new Loader();
var image2:URLRequest = new URLRequest(file2.url);
imageLoader2.load(image2);
imageLoader2.x = 10;
imageLoader2.y = 950;
box.addChild (imageLoader2);
imageLoader2.addEventListener(MouseEvent.CLICK, removeScrollyPaneThing);
}
function removeScrollyPaneThing(MouseEvent):void
{
removeChild(getChildByName("scrollyPaneThing"));
}
function resetColorTransform(e:MouseEvent):void
{
e.target.transform.colorTransform = basicColorTransform;
e.target.removeEventListener(e.type, resetColorTransform);
}
function getFileData(file:File):String
{
var fDataStream:FileStream;
var sContent:String;
fDataStream = new FileStream();
fDataStream.open(file, FileMode.READ);
sContent = fDataStream.readUTFBytes(fDataStream.bytesAvailable);
fDataStream.close();
return sContent;
}
Your Loader Object has a scrollRect property that is built in.
It is MUCH easier to use a simple ScrollBar than a ScrollPane,
but mouse dragging is much cleaner:
see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#scrollRect
To mouse drag:
private var scrollyThingy:Rectangle;
private var map:Loader;
// holders for the location of the view
//(to allow for cancelling the drag):
private var _cx:int = 0;
private var _cy:int = 0;
private var downpoint:Point = null;
public function init():void{
// Load your image:
/* I prefer to use embeded png files
or draw simple line images, but
Loader objects also have a scrollRect property
From this point I will assume your main image ('map') is loaded,
and 'scrollyThingy' is the part you want diplayed
I could not follow the code once you added the
loader to the stage very well...
*/
// to enable mouse dragging:
map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
var w:int = 100;
var h:int = 100;
scrollyThingy = new Rectangle(_cx, _cy, w, h);
map.scrollRect = scrollyThingy;
AddChild(map);
}
private function onMouseDown(event:MouseEvent):void{
_downpoint = new Point(event.stageX, event.stageY);
map.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
map.addEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
map.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
map.addEventListener(MouseEvent.RELEASE_OUTSIDE , onReleaseOutside);
}
private function onMouseDrag(event:MouseEvent):void{
if (_downpoint == null)
return;
// the movement delta:
_dx = int((event.stageX - _downpoint.x));
_dy = int((event.stageY - _downpoint.y));
// (if the movement is backwards, use scrollyThingy.x -= _dx)
scrollyThingy.x += _dx;
scrollyThingy.y += _dy;
Loader.scrollRect = scrollyThingy;
}
private function onMouseUp(event:MouseEvent):void{
if (_downpoint == null)
return;
// new corner coords
_cx += int((event.stageX - _downpoint.x));
_cy += int((event.stageY - _downpoint.y));
resetListeners();
}
private function onReleaseOutside(event:MouseEvent):void{
// put it back where it was
resetListeners();
}
private function resetListeners():void{
scrollyThingy.x = _cx;
scrollyThingy.y = _cy;
Loader.scrollRect = scrollyThingy;
_downpoint = null;
if(!map.hasEventListener(MouseEvent.MOUSE_DOWN)
map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
//(if it has one, it has them all!)
if(map.hasEventListener(MouseEvent.MOUSE_DRAG){
map.removeEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
map.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
map.removeEventListener(MouseEvent.RELEASE_OUTSIDE , onReleaseOutside);
}
}
if you still want a ScrollBar, just scale it to your Loader dimensions less the
size of the viewport (xScrollBar.maximum = loader.content.width - scrollyThingy.width,
yScrollbar.maximum = loader.content.height - scrollyThingy.height) then you can use the
same listener for both bars:
function onScrollBarChange(e:event):void{
scrollyThingy.x = xScrollBar.value;
scrollyThingy.y = yScrollBar.value;
}
listen for a change Event and set the Loader.scrollRect.x and Loader.scrollRect.y
properties to the scrollBarx.value & scrollBary.value.
Note also that I did not include any value checking.
You should check the values before moving the scrollRect
to avoid rangeErrors
i.e. if (_cx > loader.width - loader.scrollRect.width)
_cx = Loader.width - Loader.scrollRect.width;

ActionScript - how to put 10 different dishes (loaders) in a random sequence?

Hello im with a doubt and need your help if its possible.
I have a class dish and i load 1 file ".swf", and i have a little game that works like this:
The dish moves in the x and y axis and i when i click in the dish it falls down.
But i want to have not only 1 dish i want have 10 different dishes with diferent images.
And i want that they appear in a random sequence.
But i dont have ideia how i cant do that...someone can give me "light"?
I use this variables to load my dish to the stage in my game project.
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest("dish.swf");
Here's an example of what you could do to get a random dish each time :
// whenever you need to create a new dish
var dishFilenames:Array = ['dish1.swf', 'dish2.swf', 'dish3.swf']; // etc etc
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
thank for the answer!
so i cant have all the dishes in the same "swf"?
I need to create swf as many as i need?
My class dish is like this until now:
I dont have other way to do that?(with only a swf that contains all the dishes)
package {
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class Dishe {
var velX: int;
var velY: int ;
var game:Game; //i have also a class game to control everyting
var broken_dish:URLRequest = new URLRequest("broken_dish.swf");
var gravity:int = 2;
var dishFilenames:Array = [ 'dish.swf','second_dish.swf'];
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
public function Dishe(e:Game, vX:int, vY:int)
{
velX = vX;
velY = vY;
load_dish.x = -180;
load_dish.y = randomBetween(250,-5);
load_dish.load(caminho);
game = e;
game.myStage.addChild(load_dishe);
load_dish.addEventListener(MouseEvent.CLICK, _shoot);
}
public function broken_dish(e:Event)
{
velY += gravity;
load_dish.y +=velY ;
if(load_dish.y >= game.myStage.stageHeight)
{
game.game_states(Game.state_playing);
}
}
public function _enterFrame(e:Event):void
{
if(load_dish.content!=null)
{
load_dish.x += velX;
load_dish.y += velY *(1 - (load_dish.x / game.myStage.stageWidth) * 2 );
if(load_dish.x > game.myStage.stageWidth)
{
load_dish.y = randomBetween(250,-5);
load_dish.x = -180;
}
}
}
public function _shoot(e:MouseEvent):void
{
trace("nice!!");
game.game_states(Game.state_stop);
load_dishe.load(broken_dish);
}
function randomBetween(a:int, b:int) : int {
return a + int(Math.round( (b-a)*Math.random() ));
}
}
}

Actionscript3: Countdown number of ducks

Clouds,
ducks,
score
display
and
waves
should
each
have
a
class
to
govern
their
movement
and
behavior.
When
ducks
are
clicked
on
they
are
“shot”
and
the
duck
is
removed
from
the
array
as
well
as
from
the
stage
(use
arrayName.splice()
for
this).
The
score
display
should
count
down
as
this
occurs.
The
number
of
ducks
left
should
be
a
property
within
the
Score
Display’s
class
and
adjusted
by
Main
when
the
ducks
are
shot.
When
all
the
ducks
are
“shot”
the
game
should
animate
the
“you
win”
message.
This
can
be
done
by
adding
and
removing
event
listeners
that
associate
an
ENTER
FRAME
event
with
an
animating
function.
(This
is
worth
only,
so
leave
it
for
last).
When
the
ducks
are
“shot”
the
waves
and
clouds
should
also
be
removed
from
view
AND
from
their
respective
arrays.
Game
should
reset
after
player
has
won
or
lost
many
times.
(not
just
once)
I have most of this done, I'm just having trouble with the scoreboard. Any tips on how to reset everything, and code the you win sign would help too.
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
[SWF(width="800", height="600", backgroundColor="#E6FCFF")]
public class Main extends Sprite
{
private var _sittingDucks:Array = []; //always set your arrays with [] at the top
public var _scoreDisplay:TextField
public function Main()
{
//adding the background, and positioning it
var background:Background = new Background();
this.addChild(background);
background.x = 30;
background.y = 100;
for(var i:uint = 0; i < 5; i++)
{
//adding the first cloud, and positioning it
var clouds:Clouds = new Clouds();
this.addChild(clouds);
clouds.x = 130 + Math.random() * 600; //130 to 730
clouds.y = 230;
clouds.speedX = Math.random() * 3;
clouds.width = clouds.height = 200 * Math.random()//randomly changes the clouds demensions
}
var waves:Waves = new Waves();
this.addChild(waves);
waves.x = 0;
waves.y = 510;
waves.speedX = Math.random() * 3;
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
var waves2:Waves = new Waves();
this.addChild(waves2);
waves2.x = 0;
waves2.y = 520;
waves2.speedX = Math.random() * 3;
var setting:ForeGround = new ForeGround();
this.addChild(setting);
setting.x = 0;
setting.y = 50;
setting.width = 920;
var board:ScoreDisplay = new ScoreDisplay();
this.addChild(board);
board.x = 570;
board.y = 35;
}
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import ScoreDisplayBase; // always import the classes you are using
public class ScoreDisplay extends ScoreDisplayBase
{
private var txt:TextField; // where is it initialized?
private var score:uint = 0;
public function ScoreDisplay()
{
super(); // do you init txt here?
}
public function scoreUpdate():void
{
score += 10; // ok, so I suppose that your score does not represent the remaining ducks as you said, just only a score
txt.text = score.toString();
}
}
Aaaalrighty:
You do want to create the TextField txt in ScoreDisplay's constructor. Instantiate it, set its text to initial score (0), and addChild(txt).
In order to set the score later, we'll need a way to reference the display.
//you want a reference to the ScoreDisplay, not this
public var _scoreDisplay:TextField //no
public var _scoreDisplay:ScoreDisplay //yes
and when you create it in the Main constructor, we need to keep a reference.
_scoreDisplay = :ScoreDisplay = new ScoreDisplay();
this.addChild(_scoreDisplay );
_scoreDisplay .x = 570;
_scoreDisplay .y = 35;
If you want to be able to reset the game, I would recommend taking the duck creation and placing it in a method outside the Main class' constructor. You should also create a 'reset' function that sets the score (and the display) to 0 in ScoreDisplay.
private function spawnDucks() {
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
}
and then you call it in the constructor, and can call it again when you need to reset the game.
ducksDestroy(event:MouseEvent) is going to be where you want to recalculate the score, check if you've won, show a message, and reset the game. You'll need some kind of popup to display, here is a decent one if you don't know where to get started at with that.
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
//update the score
_scoreDisplay.scoreUpdate();
//Check if all the ducks are gone
if (_sittingDucks.length == 0) {
//All the ducks are dead, we've won the game!
//create some kind of popup to display.
//add it to the screen, have some form
//of button (or a timer) take it away
//whatever takes the popup away, have it call 'reset'
}
}
private function reset():void
{
//write a reset method to clear the score
_scoreDisplay.reset();
//create some ducks and you're ready to go!
spawnDucks();
}