How to use cache on Movieclip with createJS and Flash CC - html

Hi all I want to ask something. I've made a game with Flash CC and createJS. it's a Drag and drop game (3 object for drag, and 3 object for drop) and a lot of vector movieclip object. But when I run it in mobile, the game looks like have a performance issues. I've read some article that talk about caching the object. But I'm really dont know anything about cache and don't know how to use it on an object like movieclip. Do you have any explanation or solution or maybe a tutorial how to use cache function? Thank you very much.

From the docs:
Draws the display object into a new canvas, which is then used for subsequent draws. For complex content that does not change frequently (ex. a Container with many children that do not move, or a complex vector Shape), this can provide for much faster rendering because the content does not need to be re-rendered each tick. The cached display object can be moved, rotated, faded, etc freely, however if its content changes, you must manually update the cache by calling updateCache() or cache() again. You must specify the cache area via the x, y, w, and h parameters. This defines the rectangle that will be rendered and cached using this display object's coordinates.
http://createjs.com/Docs/EaselJS/classes/DisplayObject.html#method_cache
So, you don't want to cache a playing MovieClip (you would have to update the cache every frame, which is slow). However, you could cache elements in the MC that are just being transformed.
For example, an animation of a walking character, with complex vector shapes for the arms, legs, head, and body that are being transformed (scaled, rotated, translated) to create the walk animation. You wouldn't cache the character MC, but you could cache the body parts themselves.

Related

How to zoom and pan a gameobject not the whole scene in unity

I have several images in my scene, I managed to make the zoom and pan work but the problem is, All of the images are zooming in at the same time. The scripts are place on each gameobject. I used gameobject for the images.
You need apply a filter so you just appli the transformations to one game object, since every one of them are GameObjects I recommend use raycast to sellect an object and then activate his Zoom.cs script just for this object.
I sugest to use just one Zoom.cs in the scene instead of every object having his own copy, then change your function to work with one game object as a paremeter and, when you touch your game object then that object will be the one to suffer the transformation.
If you doesn't want to implement a raycast or change your function at all, then you could set all the images inside a matrix, or use an index system, the central image, or the index you designed, will be the one to suffer the transformations. so you can scroll betwen your gaery and be sure that just the image that you designate in your matrix/index will be the choosen one. The trouble here is that you need to fully control the scroll animation so no one of the images will be in a wrong place like in between two index.

AS3: Disposing of cacheAsBitmap bitmaps?

I've got a large, detailed, interactive vector object with dynamic text that will frequently translate horizontally from off the screen onto the screen when the user needs to look at it, then back off the screen when the user is done. If I set myVector.cacheAsBitmap = true before translating it and myVector.cacheAsBitmap = false after translating it, what happens to all of those bitmaps that are generated each time? Do I have to dispose of them myself?
Adobe help about Bitmap caching:
Turning on bitmap caching for an animated object that contains complex
vector graphics (such as text or gradients) improves performance.
However, if bitmap caching is enabled on a display object such as a
movie clip that has its timeline playing, you get the opposite result.
On each frame, the runtime must update the cached bitmap and then
redraw it onscreen, which requires many CPU cycles. The bitmap caching
feature is an advantage only when the cached bitmap can be generated
once and then used without the need to update it.
If you turn on bitmap caching for a Sprite object, the object can be
moved without causing the runtime to regenerate the cached bitmap.
Changing the x and y properties of the object does not cause
regeneration. However, any attempt to rotate it, scale it, or change
its alpha value causes the runtime to regenerate the cached bitmap,
and as a result, hurts performance.
Conclusion
If you make a simple translational movement along the x or y axis, your bitmap is created only one time.
Do I have to dispose of them myself?
It seems that you can't touch the bitmap cache only used internally by Flash player.

Minimize memory usage with a multi-frame MovieClip

I have a MovieClip in Flash with 100 frames. Each frame contains a certain icon I need to use in a project. I create instances of this icon MovieClip wherever I need an icon to appear, and gotoAndStop to a certain frame to display that icon.
Will storing a 100 icons in a single movieclip cause every single icon to be created in memory whenever I create an instance of the MovieClip? If I stored each icon in the library and attached only the icon that is needed, would that consume less memory than creating this MovieClip that has all the icons in it?
To answer your question: When you go to a frame with an icon on it, Flash will create a new instance of that icon. When you leave that frame, Flash will make that icon eligible for garbage collection, unless you force it to hold the instance in memory somehow, such as using addEvenListener where the method that is the listener is the icon or somewhere inside it.
I think the memory usage is likely to be higher for the goToAndStop vs. the new instance. If you are not experiencing problems with goToAndStop(), you are unlikely to experience additional issues by instantiating a new icon each time you switch from one icon to another. The other people who have answered are quite right that you will use fewer CPU cycles by instantiating all the icons only once (by whatever method), and then simply using the same one every time you use that icon. However, your overall memory footprint will be higher, because you will have all of the icons (even ones you are not currently using) in memory all the time.
If you want to go the route of only instantiating each on once, I'd suggest you go with Lazy Loading, where you only instantiate each icon when it is first used. One way to do this is to use what you already have and visit the frame the first time you want to use a specific icon, then store the BitmapData or a reference to the icon itself after that and reuse it. Another way is to build a swc and use a similar pattern.
None of this requires a static variable BTW, since it sounds like you're not using tons of different copies of your icon MC. Even if you are, it's probably better to handle referencing the icons you have through dependency injection.
I think you are probably asking about file size, however, vs. actual memory usage. The answer to that questions is that all assets that are used by your fla get compiled into the swf, regardless of whether they are in a MovieClip, a SWC, or in the library with Export for Actionscript in Frame N checked.
I get it, I've got boobs, I'm guessing
Try this, to verify my "guess."
Create a swf that has a keyframe on frame 1.
Draw a circle there.
Put another keyframe on frame 10. Draw a square.
In Publish Settings, check "Generate size report."
Now, you know (or you should know) that this swf can display the circle on frame 1, even if the assets compiled on frame 10 have not yet been downloaded. So, is there any possible way that the square could be loaded into memory before Frame 10 has been downloaded? Hint: the answer is no.
Now ask yourself this: Do you think Macromedia wrote a special version of MC that is incapable of lazy loading that the MC that is the main Document Class that Flash generated for the movie you made above so obviously handles so well?
The Macromedia engineers did a lot of things that in hindsight look pretty stupid, but they're not that incompetent.
If each icon that goes into the 100 frames MovieClip is an image you can easily enough export that image for actionscript and access only the image you need.
Another idea is to create a static class that stores each icon frame as a symbol in a static array(if you want to access the icon by index) or Dictionary(if you want to retrieve it by name).
e.g.
package{
import flash.display.Bitmap;
public class Icons{
public static const assets:Vector.<Bitmap> = Vector.<Bitmap>([new Icon01ASExportName(),//instance bitmaps once
new Icon02ASExportName(),//reuse them later multiple times
...
new Icon99ASExportName()]);
}
}
Yet another is to generate a SpriteSheet, either once and save it as a file, either at runtime, then copyPixels() to paste the icon from the right rectangle of the main spritesheet. You've got multiple tools available for generating the spritesheet:
Zoƫ
SWFSheet
Flash CS6
TexturePacker (if you have movieclips, you can export them as an image sequence to drop into the software)
There are also ways to generate a spritesheet at runtime.
For some nicely explained video tutorials on spritesheets and BitmapData by Lee Brimelow: Sprite Sheets and Blitting - Part 1,2 and 3.
If your icons are Bitmaps then each movieclip will share the same data - the only memory increase will be due to more movieclips, rather than their contents (which shouldnt be a problem).
If your icons are not Bitmaps (other movieclips, shapes, buttons etc), then everything gets duplicated, so memory usage will increase a lot faster as more movieclips are added.
Another consideration is that lots of movieclips on screen will have more of an effect on FPS than simpler objects so you may want to consider adding the icon itself rather than the movieclip even if you are using Bitmaps.

Flash/AS3 Framerate in tile-based game is low, despite all tiles being converted to a single bitmap

I'm working on a small game in Flash (AS3) that generates levels using small tiles.
The location,width,height and other properties of the tile are stored in an array upon generation. Each tile is added to the same container movieclip. When all tiles have been generated, the container movieclip is converted to a bitmap, all tiles are removed from the stage, and the original container is removed from the stage and then deleted. The bitmap is the only remaining "graphic" on the stage, aside from the player.
This yields far better performance than allowing all 60,000+ tiles to be rendered individually during gameplay; however, the framerate still reduces as the number of tiles is increased. This makes no sense, as all the tiles are added to a single bitmap that is always the same size, regardless of the amount of tiles.
With 20,000 tiles during generation, the game runs at the full FPS, but with 60,000 it runs relatively choppy, probably around 4-5 FPS.
I've removed collision detection and any/every script that runs through the tile array to rule out the possibility that some other CPU intensive part of the script is lagging the framerate.
Any idea why, despite the fact that all tiles have been removed from the stage and their container is deleted, the game is still running slow even though the background bitmap contains the same amount of data regardless of the number of tiles generated?
Here is the last part of the level generation algorithm which converts the container movieclip to a bitmap and then removes all the tiles:
var temp_bitmap_data:BitmapData = new BitmapData(this.stage_background_mc.width,this.stage_background_mc.height);
temp_bitmap_data.draw(this.stage_background_mc);
this.stage_background_bitmap = new Bitmap(temp_bitmap_data);
main_class.main.stage.addChild(this.stage_background_bitmap);
for (var block in blocks_array)
{
//every block in blocks_array has a child that is the actual graphic of the tile
blocks_array[block]["block"].removeChild(blocks_array[block]["block"].getChildAt(0));
if (blocks_array[block]["type"] == "bg_block")
{
this.stage_background_mc.removeChild(blocks_array[block]["block"]);
blocks_array[block]["block"] = null;
}
if (blocks_array[block]["type"] == "path_block")
{
//path_blocks have a second child in addition to the first one that's already been removed. the second child is the only other child
blocks_array[block]["block"].removeChild(blocks_array[block]["block"].getChildAt(0));
this.stage_background_mc.removeChild(blocks_array[block]["block"]);
}
}
this.stage_background_mc = null;
[Edit]
Here is a picture of the game to give you a better idea of what's going on:
[Update:]
Even removing the final created bitmap from the stage, ending up with only 1 child on stage, and setting that removed bitmap to null doesn't improve the speed.
A couple of thoughts.
First, you're sorta half taking advantage of AS3's quick work with blitting. You've got the right idea about having only one single Bitmap on the stage, but the steps before (adding DisplayObjects to a MovieClip and the doing draw on that MovieClip) isn't the fastest process. For one thing, BitmapData.draw is slower than BitmapData.copyPixels (here is a post on that). One of the best ways to get speed is to pre-blit all of your graphics, and store them as BitmapData. Then, keep Object references (containing position, etc) for each graphic. In your render loop, run through each object, and use copyPixels to copy the graphic's pixel information to the appropriate positon in your single, on-stage Bitmap. This way, all slow BitmapData.draw commands have happened upfront, and now you are just pushing pixels, which Flash is really fast at.
That process isn't without its downsides, however. For instance, you can't do easy transforms with it. You'd have to pre-blit all frames of a rotation, for instance, in order to rotate the individual graphic (since you can't rotate a BitmapData, and you aren't using draw on a DisplayObject). Still, it is mighty fast if you can live with the limitations.
Here is a post that serves as a tutorial of the process I explained above. It is old, but informative none-the-less.
Finally, 60,000 is a very large number. Flash isn't exactly a "speed demon." No matter how optimized, eventually you'll hit a limit. Just something to keep in mind.
Oh, and this additional post gives some great tips on performance in Flash.

symbols placed on the timeline become undefined if stepping backwards

I am using the frames in the timeline of a .swf as pages in a flash app. The user can advance to the next page by clicking a button that takes her to the next frame. Similarly, it is possible to navigate to the previous frame/page as well.
Most of the content is placed on the stage (i.e. created by dragging an instance of a library symbol to the stage) but properties of those instances, such as .visible might be changed via actionscript. Also, some objects are loaded from external flash files and displayed programmatically with addChild / addChildAt.
The problem is, if I am on Frame N+1 and there is an object displayed on the stage programmatically (i.e. with addChild, not by having it placed on the stage) and navigate to Frame N where there is an object that is placed on the stage (i.e. dragged from the library),
then the instance of that object is undefined/null and throws an error if I try to set its properties (like .visible).
The error does not occur if I am moving to the NEXT frame, only if I am moving to the PREVIOUS one. Therefore I assume that some kind of initialization is not getting called while going one frame back.
I was also thinking that the objects would just not "live" to the next timeframe, that is, their value would be lost and re-initialized because of scope, but if there is no dynamically created object on the stage, I can navigate back and forth just fine.
Is there a way to ensure that the objects created on the stage do not disappear while navigating back to the previous frame?
The first, and more useful, part of the answer is this: timeline keyframes and scripts can give conflicting information about display objects - whether they should exist, where they should be, and so on. For example, when you add an item by playing into its frame, and then delete it with script, and then play into its frame again. When this happens, there's no unambiguously correct thing for Flash to do, so it tends to be unpredictable. I believe what generally happens is that once you fiddle with a given object via script, it's considered to no longer pay attention to the timeline - but your mileage will vary.
Having said that, the reason things are different when you play backwards is the second and more arcane part of the answer. Internally Flash functions differently when seeking forward and backwards on the timeline. Flash internally treats keyframes as changes to be applied in the forward direction, so as you play forward, it applies those changes in sequence. When you move backwards, however, from frame N+X to frame N, it doesn't scan through the intervening X frames reversing those changes - it jumps back to frame 1 and fast-forwards along to frame N. Normally, it amounts to the same thing and you don't need to worry about it, but when you get into the twitchy area where scripts and the timeline have a different idea of what should be on the stage, you're liable to see things behave differently depending on which way you jump (as you are now).
The super-short version is, for things to work predictably, try to ensure that any given object gets added, updated, and removed the same way - either all via script, or all via the timeline. When that seems impossible, fiddle with your content structure - usually, the best solution is to change your object into two nested ones, so that the things you want to do with script occur one level higher or lower than the things you want to do with the timeline.
I'm not sure I got your question right, but as3 does not instantiate elements on the timeline as soon as you gotoAndSomething, but later that frame.
That is, you can't
this.gotoAndPlay(10)
this.elementOnTimelineFrame10.DoSomething()
without errors.
I remember using this chunk of code in the past to work around this problem. It uses the Stage.Invalidate() function to wait for an Event.RENDER before trying to access and children, more info (although vague as hell) is here
private function init():void
{
stage.addEventListener(Event.RENDER, stage_renderHandler);
}
private function stage_renderHandler(evt:Event):void
{
// Run your code here
updateChildren();
}
private function enterFrameHandler(evt:Event):void
{
// triggers the RENDER event
stage.invalidate();
}
This also might me very costly (performance wise). I would strongly advise against dynamically adding/removing objects to an existing timeline, is there any way in which you can place an empty Sprite above the timeline animation and use that for all your dynamic content?
Hope this helps