I would like to use identical .atlas file for multiple master texture files.
This can be easily achieved by having multiple almost identical .atlas files (with only difference being the first line with the texture file name), but it's not a nicest solution.
I was wondering if it's possible to provide the name of master texture file at runtime, during TextureAtlas object creation or later.
I took a quick look on the TextureAtlas code, but the API doesn't seem to allow that, at least not in an straightforward way.
You can pass an images directory to the TextureAtlas constructor. I haven't tried it, but it seems like you could have your single .atlas file, then have the separate texture files in different directories.
From TextureAtlas...
public TextureAtlas (FileHandle packFile, FileHandle imagesDir) {
this(packFile, imagesDir, false);
}
/** #param flip If true, all regions loaded will be flipped for use with a perspective where 0,0 is the upper left corner. */
public TextureAtlas (FileHandle packFile, FileHandle imagesDir, boolean flip) {
this(new TextureAtlasData(packFile, imagesDir, flip));
}
After some research it seems that the only way to achieve it is to extend TextureAtlas and then copy and modify the constructor code.
Currently the name of the texture file is obtained by simply reading the first line of the atlas file:
String line = reader.readLine();
if (line == null) break;
if (line.trim().length() == 0)
pageImage = null;
else if (pageImage == null) {
FileHandle file = imagesDir.child(line);
Instead of doing it this way the FileHandle would need to be created using a file name passed as an argument of a constructor.
In this situation I'm going to stick to the multiple atlas files :-)
Related
I have a variable area which stores a number.
When the app is restarted, it is reset back to it's original value. How can I keep area persistent after being closed?
I'm using Flash CS6 for Android
You'll have to save the variable. There's multiple ways to do this but using a SharedObject is the easiest IMO.
First thing is you don't actually create a new instance of the SharedObject class, you instead call the static function getLocal and this sets your variable. So somewhere near the start of your program you'll want something like this:
var gameSave:SharedObject = SharedObject.getLocal("gameSave");
This either creates a new locally persistent shared object if one does not exist or it grabs the one with the same initialized name ("gameSave") on your computer. This way you can access the saved variables across multiple playthroughs.
Now to save a variable you simply use the dataObject on the shared object and write values to it, then you call the function flush when you're done writing values to immediately save the shared object to your computer.
So saving your area value would look something like this:
gameSave.data.area = Main.area;
gameSave.flush();
After that you'll want to set the area value to whatever the saved value is when your game launches:
if (gameSave.data.area !== undefined) Main.area = gameSave.data.area;
We check if the value is undefined because it might not exist yet if you're playing the game for the first time and the area hasn't been saved yet.
Last thing in case you want to expand the scope of this and save more values: you can only write specific values to the shared object. The way I understand it is you can only write certain class types and primitives. If you try to write anything that's not a primitive or the exception classes, it'll automatically convert that item to an Object and it more or less becomes useless. The classes that it can accept that you'll probably use the most are: int, uint, Number, String, Boolean, Object, and Array. It has a few others like ByteArray and XML, but you'll either not use those at all or not use them very frequently. If you want to save any other class type you'll have to add that functionality yourself.
I asked similar question sometime ago, but I am making new one to be much more specific with my question with some example!
I´ve found this code snippet/tutorial from googling, but I cant seem to figure out how to modify it for my needs:
// open a local shared object called "myStuff", if there is no such object - create a new one
var savedstuff:SharedObject = SharedObject.getLocal("myStuff");
// manage buttons
btnSave.addEventListener(MouseEvent.CLICK, SaveData);
btnLoad.addEventListener(MouseEvent.CLICK, LoadData);
function SaveData(MouseEvent){
savedstuff.data.username = nameField.text // changes var username in sharedobject
savedstuff.flush(); // saves data on hard drive
}
function LoadData(MouseEvent){
if(savedstuff.size>0){ // checks if there is something saved
nameField.text = savedstuff.data.username} // change field text to username variable
}
// if something was saved before, show it on start
if(savedstuff.size>0){
nameField.text = savedstuff.data.username}
So what I am trying to figure out how to do, is to save users current frame to local hard drive, as my flash progress is based on frame location. yeah, so how do I modify it so that it stores data of current frame? and how about current frame inside movieclip, if that is makes things different?
help MUUUCH appreciated! thanks!
In your example it looks like it is already saving something to the shared object:
savedstuff.data.username = nameField.text;
Just replace it with the movie clip frame value instead (and probably under a different property name other then "username").
Then on load, there is another line where it loads the data:
nameField.text = savedstuff.data.username;
It would be the same way, except replace "username" with whatever property name you choose. Then you may have to parse into an int again and use it to restore progress however way you have it set up.
I am developing an online tool which edits images but I have a problem. In copy specific region of bitmap to another bitmap. What is the problem, can anyone help me out?
function enablepaste(event:MouseEvent)
{
tempShape.graphics.clear();
mv_temp.graphics.clear();
var rect = new Rectangle(tempstartX,tempstartY,endX,endY);
var pnt =new Point(tempstartX,tempstartY);
tempBMP_data=new BitmapData(rect.width,rect.height,false,0);
tempBMP_data.copyPixels(stageBMP.bitmapData,rect,pnt , null, null, true );
//tempBMP_data is destinagtion bitmap data object
tempBMP= new Bitmap(tempBMP_data);
mv_temp.addChild(tempBMP);
Paste_button.visible=true;
}
The problem that I am facing is that it shows only rectangle without copying graphics.
I see there are two potential flaws:
When you perform copyPixels, shouldn't the destination point (3rd parameter) be Point(0,0)?
If the above adjustment does not yield correct result, I would consider clone the stageBMP, and move the clone a few pixels in both x and y direction, that way you can make sure that stageBMP is properly generated.
I created this simple example
because I was using a more complex class, a menu item that I wanted to initialise all the settings in the Main class and then add it in in the Game class (and updating it) when needed (both classes are separate)
Class: Main (document class, is (ideally) where everything is initialised/created)
public class Main extends MovieClip
{
//testing passing on reference to Game
private var testBitmap:Bitmap;
private var testBitmapData:BitmapData;
private var testArray:Array;
public function Main():void
{
testBitmapData = new BitmapData(256, 256, false, 0xCCDDEE);
testBitmap = new Bitmap(testBitmapData);
testArray = [];
testArray.push(testBitmap); //Array for reference
game = new Game(540, 960, testArray);
//create Game class, pass reference to Object
game.x = 0;
game.y = 0;
}
}
Class: Game (created by document class, is (ideally) where everything runs)
public class Game extends MovieClip
{
private var testingArray:Array
public function Game(gameWidth:int, gameHeight:int, testArray:Array):void
{
this.testingArray = testArray; //assign to local Array and access
addChild(testingArray[0]);
//addChild to Game from an item intialised in Main, doesn't work >___<
}
}
.
.
.
the thing is, in my original Game class; it receives an initial bundle of cached BitmapData and a list Array that tells it which BitmapData it needs to cycle through
cut-down here (and that reference only for updating works (if I addedChild in Main already):
public function Game(gameWidth:int, gameHeight:int, cachedBitmapClipArray:Array)
{
this.cachedBitmapClipArray = cachedBitmapClipArray;
private function update():void
{
for each (tempCachedBitmapClip in cachedBitmapClipArray)
{
tempCachedBitmapClip.updateCurrentTile();
//but updating through the reference to an item initialised in Main works !!
}
}
}
.
how do I make the reference and passed in objects (or have access to) behave as in the original instance ?? (being able to addChild)
i.e. can objects cross 'scopes' (??) or should objects only be controlled (instantiated) in the class where they have been initialised
Well to answer the last question, yes objects can be passed from one object to another. I'm having a hard time understanding what exactly the problem is though. In generic programming terms Object or any other complex type are passed by reference, primitive types are also passed by reference but the internals of the AVM handle them in such a way as to treat them as passed by value. For a pretty clear (in my eyes at least) explanation of how arguments are passed via function/method calls, read here:
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f56.html
Check out other areas in the tree navigation on the left for more details on the language itself.
One thing to note though I think the compiler will work around this error, in the first bit of code you posted Game has a return value of :void for a constructor there should be no declared return type since it should be implicitly typed as whatever the class is.
To add some explanation in my own words regarding pass by reference or pass by value. Pass by value means that the value of the object, that is the bytes stored at the location pointed to by the variable are actually copied to a new memory location which is then used. What this means in practice is they are not the same bytes of memory but rather they are two separate memory locations each with the same value stored in them, modification of one value after the passing doesn't affect the original. Pass by reference is to say you pass the memory location therefore no new memory for the value is allocated, both values are actually pointing to the same memory location (the pointer to them itself may be different but that pointers both point to the same location in memory). In this case the objects are the same.
What you're doing is advisable, dividing the labor and enapsulating particular types of functionality in classes does make the code easier to work with. I think the only problem would be if the Game object itself is never added as a child to something in the display tree (something that is attached to the stage). It appears you're creating a new Game and setting it's position but never adding it as a child to the stage, then adding anything to Game is never a part of the display tree.
So for instance, I've got three .as files called 'Helicopter.as, Game.as, Blue.as'
and I also have a .fla file called Helicopter.fla (These files are all suppose to link together, to make the helicopter game) . In the Game.as file, I have the following;
if (blue1.hitTestObject(Helicopter))
{
trace("YOU HIT THE BLOCK!");
Helicopter.x = 76;
Helicopter.y = 217;
}
I have drawn the so called 'Helicopter'^ using API in a different file called Helicopter.as using this code;
graphics.beginFill(0x00FF00);
graphics.drawCircle(0, 60, 35);
graphics.endFill();
However, I originally had the "Helicopter' symbol drawn in the Helicopter.fla file (which I've now deleted), and now that I've drawn the 'Helicopter' using API, I get this error;
''1067: Implicit coercion of a value of type Class to an unrelated type flash.display:DisplayObject.''
Flash doesn't recognise the original Helicopter symbol (in the Helicopter.fla file, because I deleted it). But I want the system to detect the 'circle' drawn using API (In the Helicopter.as file). And I have no idea how to how to name the API drawn circle 'Helicopter', thus I'm getting an error. So how do I name the API circle to 'Helicopter', so the Game.as file recognises it. If you have no idea what I'm talking about, then don't worry, because I don't know too. Thank you. If you want, I can paste all the code I've done so far.
Helicopter is a class not a variable, therefore you cannot assign Helicopter.x. You need to create a variable var heli:Helicopter = new Helicopter(); and use heli.x
it also could be that you're not following the programming standards, and Helicopter is in fact a variable and not a Class, though the error seems to indicate otherwise.