I've got 4 different types of markers on single map. Currently a slideshow rotates through each type, hiding the other 3. There is a MarkerClusterer object for each different type of marker so that they do not cluster together.
The issue I am having is that the heap snapshot in chrome shows I'm increasing the amount of memory in use by about 2mb every 5 minutes or so. This is my code currently:
function transitionMarkers() {
if (isSlideShowActive) {
for (var i = 0; i < markers.length; i++) {
if (nutrientsArray[slideShowCounter] === markers[i].address.SOURCE_GROUP) {
markers[i].setVisible(true);
} else {
markers[i].setVisible(false);
}
}
for (var n in types.NUTRIENTS) {
for (var sc in types.SOURCE_CODES) {
if (nutrientsArray[slideShowCounter] === n) {
markerClusters[n][sc].setMap(map);
} else {
markerClusters[n][sc].setMap(null);
}
}
}
}
incrementSlideShowCounter();
}
Markers have the ability to change their visibility, and since they will be re-rendered within a minute, I don't bother using setMap(null) on them. However, marker clusters do not have this option. When I examine the heap snapshot, I see thousands of objects that look like this:
[1076] :: pf #2451465 5 360 % 2 3360 %
b :: gi #2273271 2 120 % 170 5441 %
e :: function() #2454527 6 360 % 2 3000 %
proto :: pf #2338839 5 120 % 360 %
d :: "bounds_changed" #67519
It looks like there are thousands of these bounds_changed events sitting there accumulating...my map only hides or shows markers, it doesn't move around, zoom in or out, or anything like that.
Any thoughts?
These bounds_changed-events will be bound to the map when a ClusterIcon will be added(happens all the time when you call markerClusters[n][sc].setMap(map)).
When you call markerClusters[n][sc].setMap(null) the ClusterIcons will be removed, the onRemove-method also clears all listeners bound to the ClusterIcon-instances, but the onRemove-method does not remove the bounds_changed-events bound to the map(you may call it a bug).
So you may either fix the bug on your own and modify the markerclusterer.js so that it also removes the bounds_changed-event, or don't call setMap() at all, instead you may e.g. call the methods show() or hide() of the ClusterIcon-instances to show or hide them(should give a better performance).
Related
I have a 2.5D game (2D game that acts like a 3D game) where you constantly switch depths, where the player displays on top of an object when it walks in front of it and when it walks behind it, the object displays on top of the player. Like when the player's y is less than the object's y, the player would be going behind the object and vice versa.
I tried to use a code like this:
if (player.y < block.y)
{
setChildIndex(block, numChildren - 5);
}
else if (player.y > block.y)
{
setChildIndex(block, numChildren - 10);
}
However, I see if I do it this way with multiple times, I would need tons of codes and the display list would get mixed up and sort the wrong depths in the wrong orders. Would anyone please show an organized depth changer with minimal code?
Use a z-index stack sorting, (also refered as z-buffer in the 3D graphics literature) the same used to create the 3D depth effect using just 2D techniques.
In other words assign to each object a zIndex and at regular intervals (e.g onEnterFrame event) run a zsort routine which sorts (the order of) display objects based on their zIndex value. Or, alternatively, you can run zsort routine manualy each time a change of zIndex happens on objects.
Then in your code you simply assign zIndex values to display objects to simulate an object passing in-front or behind another object and zsort takes care of the rest.
A trick here is to have appropriate gaps (i.e not necessarily next zIndex+1) in the values of zIndex assigned on objects, so that objects can be placed between these gaps to simulate passing in front or behind other objects, without having to adjust more than one zIndex value each time, i.e you adjust only one zIndex value of the object passing in-front or behind another object, and not the zIndex of that other object.
The amount of gap between successive zIndexes can be estimated from the maximum number of (other) objects which at any given time might be between these objects (so for example, if, at maximum, 3 objects might at some time move between, in-front or behind any given object, then a gap value for successive zIndexes would be 3 so that all the objects can be accomodated)
here is a very simple zsorter routine which runs periodicaly onEnterFrame event and does the necessary depth sorting for you (from reference 1. below)
package {
import flash.display.*;
import flash.events.*;
public class DepthSortSpace extends MovieClip {
public function DepthSortSpace() {
super();
this.addEventListener( Event.ADDED_TO_STAGE, this.addedToStage, false, 0, true );
}
private function addedToStage( e:Event ) {
this.stage.addEventListener( Event.ENTER_FRAME, this.enterFrame, false, 0, true );
}
private function sortDisplayList():void {
var len:uint = numChildren;
var i,j;
for( i=0; i < len-1; i++ )
for (j=i+1; j < len; j++)
if ( getChildAt(i).y > getChildAt(j).y ) this.swapChildrenAt( i, j );
}
private function enterFrame(e:Event) {
this.sortDisplayList();
}
}
}
The zsorter above is in-fact a movieClip which acts as a scene container, in that you add your display objects to the zsorter movieClip and this takes care to sort them accordingly, but one can just take the zsort routine and apply it to any DisplayObjectContainer or Scene object instance.
Note, the zsorter above uses a bubbleSort sorting algorithm, which has a O(n^2) complexity, but one can use another sorting algorithm (e.g mergeSort with O(n lgn) complexity)
examples and references
http://nephilim.blogspot.gr/2010/06/easy-depth-sorting-in-actionscript-3.html
http://www.actionscript.org/forums/actionscript-3-0-a/169035-sorting-technique.html
http://www.simppa.fi/blog/the-fastest-way-to-z-sort-and-handle-objects-in-as3/
I'm making a 2d endless running game. I have a platform that is formed by many blocks. Every block has one of three color: red, blue, green. I don't know exactly how to random blocks with different color at runtime. I have used an array to store block rectangles like the example Drop(Simple game) on wiki page. In render class I have this code to change color of block at runtime:
public void drawBlock() {
TextureRegion region = new TextureRegion();
for (Rectangle rec : colorBlock.getBlocksRec()) {
if (colorBlock.isRed()) {
region = red;
}
if (colorBlock.isGreen())
region = green;
if (colorBlock.isBlue())
region = blue;
batch.draw(region, rec.x, rec.y, rec.width, rec.height);
}
}
But it seems to be failed because it changes all blocks on screen into one color at the same time.
I also have some problems in making blocks move continuously. They moved but they looked like hundred of blocks overlapped each other. I don't know how to control the blocks in the right way. I used TimeUtils for check when the next block should be created, but it was totally failed.
You can use an Array or your ground blocks that adds a new one when it about to appear on the screen, and removes the oldest entry when it will not be seen on the screen anymore. I had a similar question, check it out: HERE
For random colors you can use the MathUtils.random(float f) when you about to add a new block to the array.
For example something like this, or with switch :
float res = MathUtils.random(8f);
//this returns a random float between 0 (inclusive) and 8 (exclusive)
if(res <= 2) { //[0-2]
//add green
}
if(res > 2 && res <= 5){//(2-5]
//add blue
}
if(res>5){//(5-8)
//add red
}
Here is my javascript code, it is pretty simple:
console.profile();
var count = 1000;
var fn1 = function () {
for (var i = 0; i < count; i++) {
console.log("THIS IS FN1");
}
}
var fn2 = function () {
for (var i = 0; i < count; i++) {
console.log("THIS IS FN2");
}
fn1();
}
fn2();
console.profileEnd();
and this is my profile screenshot:
Why there are some gap in the image, just like my black rectangle marked?
What does this gap mean?
You see this non-uniform sequence of gaps between log calls on top of fn2 and fn1 because the profiler is sampling and gives you only statistical information. It will stop JS thread and capture current call stack roughly once per 1ms (100us in high res mode) and width of each bar is proportional to the number of consecutive samples where we've seen the same call stack.
The split of fn2 is a bug. Since we stop JS thread in random state it is not always possible to iterate JS call stack because e.g. top frame may be half-constructed. We do our best to determine current state of the VM and crawl call stack but sometimes our heuristics fail in which case we may end up capturing incomplete stack like in your case.
I have set of 6 movieclips as array_0 and another set of 6 movieclips as array_1. It is like two choices for different screens. Both these arrays are nested in another array as all_array. all 12 movieclips are positioned to a same x and y at initial load and that is outside the visible stage. I would like to use two different global variables for indexing. for example, cCat_Sel which ranges from 0-5 and another cScr_Sel ranges from 0-1. cCat_Sel will be changed on a click event of six buttons separate objects on stage (each button for each category).
so it will show the content for each category as per the value of cScr_Sel. if cScr_Sel is 0 then it will use all_array[0][cCat_Sel] to access the current target and similarly respective array for value of 1 as all_array[1][cCat_Sel]
I have done all the work including all tween animations to move current target and make it visible. But the tween does not bring the second set of mcs to visible area. I have two functions one for movein and one for move out by using tween animation for mc.x property. every relevant click event; I have to move current mc out and make alpha 0 and once that is finished, move in new current target and make alpha 1.
Somehow I have to combine these two tweens in one function. This is the part that I am stuck. or may be putting these mcs in two different arrays not a correct approach. I can easily achieve what I want on Enter Frame event of the root to check for cCat_Sel and cScr_Sel variables and do both animations one after the other but it seems like enter frame uses too much of cpu and makes it slower and probably not preferable.
willing to try anybody's suggestions or guidance. Thanks in advance.
I do not have any formal or informal programming education at all but I make things work by reading and trying out few things as per stackoverflow question and answers and sometime google. because most of my answers I have found from stack overflow.
Update:
function fnSlideInOut(cMc:Object, pMc:Object){
var HideX:Number =650;
var ShowX:Number = 0;
if(cMc != null){
if(cMc.x != ShowX){
//cMc.alpha = 1;
var SlideMcIn:Tween = new Tween(cMc, "x", Strong.easeOut, 650, ShowX, 0.5, true);
SlideMcIn.addEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
SlideMcIn.start();
}
}
if(pMc != null){
if(pMc.x != HideX){
//pMc.alpha = 1;
var SlideMcOut:Tween = new Tween(pMc, "x", Strong.easeOut, 0, HideX, 0.5, true);
SlideMcOut.addEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
SlideMcOut.start();
}
}
function fnSlideOutFinish(e:TweenEvent){
//SlideMcOut.obj.alpha = 0;
SlideMcOut.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
}
function fnSlideInFinish(e:TweenEvent){
//SlideMcIn.obj.alpha = 1;
SlideMcIn.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
}
}//End Function
fnSlideInOut(cScr_Sel, pScr_Sel);
I would like expert like you to comment on any kind of errors for the above code. It works 99 times but 1 time the movieclip either does not reach the destination or current and previous both targets showing and that too not where they are suppose to. This only happens when button click event happens in a quick succession. Thanks again
A option could be to use a third party library like TweenLite. It will then make it easy for you to run your second animation right after the first one is complete:
private function startAnimation():void
{
var mcToHide:MovieClip = all_array[cScr_Sel][cCat_Sel];
TweenLite.to(mcToHide, 1, {x: HIDDEN_X_POSITION, y:HIDDEN_Y_POSITION, alpha:0, onComplete:finishAnimation});
}
private function finishAnimation():void
{
var mcToShow:MovieClip = all_array[(cScr_Sel + 1) % 2][cCat_Sel];
TweenLite.to(mcToShow, 1, {x: VISIBLE_X_POSITION, y:VISIBLE_Y_POSITION, alpha:1});
}
You can then call startAnimation() on a relevant mouse click event and after having set cScr_Sel and cCat_Sel accordingly to your needs.
So, I'm working on the basics of Actionscript 3; making games and such.
I designed a little space where everything is based on location of boundaries, using pixel-by-pixel movement, etc.
So far, my guy can push a box around, and stops when running into the border, or when try to the push the box when it's against the border.
So, next, I wanted to make it so when I bumped into the other box, it shot forward; a small jump sideways.
I attempted to use this (foolishly) at first:
// When right and left borders collide.
if( (box1.x + box1.width/2) == (box2.x - box2.width/2) ) {
// Nine times through
for (var a:int = 1; a < 10; a++) {
// Adds 1, 2, 3, 4, 5, 4, 3, 2, 1.
if (a <= 5) {
box2.x += a; }
else {
box2.x += a - (a - 5)*2 } } }
Though, using this in the function I had for the movement (constantly checking for keys up, etc) does this all at once.
Where should I start going about a frame-by-frame movement like that? Further more, it's not actually frames in the scene, just in the movement.
This is a massive pile of garbage, I apologize, but any help would be appreciated.
try doing something like: (note ev.target is the box that you assigned the listener to)
var boxJumpDistance:Number = 0;
function jumpBox(ev:Event){
if (boxJumpDistance<= 5) {
ev.target.x += boxJumpDistance; }
else if(boxJumpDistance<=10){
ev.target.x += boxJumpDistance - (boxJumpDistance - 5)*2
}
else{
boxJumpDistance = 0;
ev.target.removeEventListener(Event.ENTER_FRAME, jumpBox);
}
}
then instead of running the loop, just add a listener:
box2.addEventListener(Event.ENTER_FRAME, jumpBox);
although this at the moment only works for a single box at a time (as it is only using one tracking variable for the speed), what you would really want to do is have that function internally to the box class, but im unsure how your structure goes. the other option would be to make an array for the boxes movement perhaps? loop through the array every frame. boxesMoveArray[1] >=5 for box 1, etc.