CAAT
CAAT copied to clipboard
behavior listener events not launched if setVisible false
Not sure if this issue represents a feature or a bug, i.e., not sure if you intended to switch off listeners for invisible objects. To me, it makes sense if behavior listeners are active, even if an actor is not visible.
The goal of the sample code below is for the actor to become visible and perform relevant behaviour once the mouse is clicked.
Code that works:
Using this code, "something happens" is output on the console log when I click the button
this.oMyActor.setVisible( false );
this.oMyBehavior.addListener( {
behaviorStarted : function( behavior, time, actor ) {
console.log( "Something happened" );
}
} );
this.oMyButton.mouseClick.mouseClick = function( mouseEvent ) {
that.oMyActor.setVisible( true );
that.oMyBehavior.setFrameTime( that.scene.time, 2000 );
};
this.oMyActor.addBehavior( oMyBehavior );
Code I would prefer:
Using this code, nothing happens when I click the button
this.oMyActor.setVisible( false );
this.oMyBehavior.addListener( {
behaviorStarted : function( behavior, time, actor ) {
actor.setVisible( true );
console.log( "Something happened" );
}
} );
this.oMyButton.mouseClick = function( mouseEvent ) {
that.oMyBehavior.setFrameTime( that.scene.time, 2000 );
};
this.oMyActor.addBehavior( oMyBehavior );
This is the intended behavior. Something invisible, or out of the timeline, should not spend any system resource, and if it is a Container instance, none of its children either. It is a big deal having one single actor:
- animation -> affine transformation, behavior processing, etc. If dirty rects are on, rects composition/optimization...
- paint -> save/restore, paint method, etc.
Could you think of any other way of achieving your expected results ?
thanks.
Similar issue here, I have a main ActorContainer called TilesGrid with many Tiles (actors) inside. TilesGrid is biggest than canvas size, so I need a dragging functionality to offer an "explore" mode to the user.
I need a mouseClick listener (tile selection) and a mouseDrag listener (tiles exploration), so the two listeners are attached to the single tile (CAAT.Tile).
CAAT.Tile.prototype.mouseUp = function (mouseEvent) {
console.log('hex up', this.Id);
// trying to reattach listeners to the "new" tiles on mouseUp - didn't work
for (var i in this.parent.Hexes) {
this.parent.Hexes[i].enableEvents(true);
this.parent.Hexes[i].mouseUp = CAAT.Tile.prototype.mouseUp;
this.parent.Hexes[i].mouseDrag = CAAT.Tile.prototype.mouseDrag;
this.parent.Hexes[i].mouseClick = CAAT.Tile.prototype.mouseClick;
}
};
CAAT.Tile.prototype.mouseClick = function (mouseEvent) {
console.log('hex click', this.Id);
this.selected = !this.selected;
};
CAAT.Tile.prototype.mouseDrag = function (mouseEvent) {
if (!this.oldDragX || !this.oldDragY) {
this.oldDragX = mouseEvent.screenPoint.x;
this.oldDragY = mouseEvent.screenPoint.y;
} else {
var speedX = parseInt(this.oldDragX - mouseEvent.screenPoint.x, 10),
speedY = parseInt(this.oldDragY - mouseEvent.screenPoint.y, 10);
if (speedX < 0) {
speedX *= -1;
}
if (speedY < 0) {
speedY *= -1;
}
if (this.oldDragX < mouseEvent.screenPoint.x) {
this.parent.x += speedX;
} else if (this.oldDragX > mouseEvent.screenPoint.x) {
this.parent.x -= speedX;
}
if (this.oldDragY < mouseEvent.screenPoint.y) {
this.parent.y += speedY;
} else if (this.oldDragY > mouseEvent.screenPoint.y) {
this.parent.y -= speedY;
}
this.oldDragX = mouseEvent.screenPoint.x;
this.oldDragY = mouseEvent.screenPoint.y;
}
};
Now, all works fine, clicking and dragging, but when I drag the tiles grid, new tiles are shown, and the listeners on these "new" tiles didn't work.
How can I force the listeners for the new tiles shown?
If i get the question right, you'd expect an invisible actor to have input sent ? like a 'ghost' element on screen ? or Francesco, do you think this is a bug ? could you post some code i could take a look at ?
thanks.
2013/4/6 Francesco Casula [email protected]
Similar issue here, I have a main ActorContainer called TilesGrid with many Tiles (actors) inside. TilesGrid is biggest than canvas size, so I need a dragging functionality to offer an "explore" mode to the user.
I need a mouseClick listener (tile selection) and a mouseDrag listener (tiles exploration), so the two listeners are attached to the single tile (CAAT.Tile).
CAAT.Tile.prototype.mouseUp = function (mouseEvent) { console.log('hex up', this.Id);
// trying to reattach listeners to the "new" tiles on mouseUp - didn't work for (var i in this.parent.Hexes) { this.parent.Hexes[i].enableEvents(true); this.parent.Hexes[i].mouseUp = CAAT.Tile.prototype.mouseUp; this.parent.Hexes[i].mouseDrag = CAAT.Tile.prototype.mouseDrag; this.parent.Hexes[i].mouseClick = CAAT.Tile.prototype.mouseClick; }
};
CAAT.Tile.prototype.mouseClick = function (mouseEvent) { console.log('hex click', this.Id); this.selected = !this.selected; };
CAAT.Tile.prototype.mouseDrag = function (mouseEvent) { if (!this.oldDragX || !this.oldDragY) { this.oldDragX = mouseEvent.screenPoint.x; this.oldDragY = mouseEvent.screenPoint.y; } else { var speedX = parseInt(this.oldDragX - mouseEvent.screenPoint.x, 10), speedY = parseInt(this.oldDragY - mouseEvent.screenPoint.y, 10);
if (speedX < 0) { speedX *= -1; } if (speedY < 0) { speedY *= -1; } if (this.oldDragX < mouseEvent.screenPoint.x) { this.parent.x += speedX; } else if (this.oldDragX > mouseEvent.screenPoint.x) { this.parent.x -= speedX; } if (this.oldDragY < mouseEvent.screenPoint.y) { this.parent.y += speedY; } else if (this.oldDragY > mouseEvent.screenPoint.y) { this.parent.y -= speedY; } this.oldDragX = mouseEvent.screenPoint.x; this.oldDragY = mouseEvent.screenPoint.y; }
};
Now, all works fine, clicking and dragging, but when I drag the tiles grid, new tiles are shown, and the listeners on these "new" tiles didn't work.
— Reply to this email directly or view it on GitHubhttps://github.com/hyperandroid/CAAT/issues/126#issuecomment-15997733 .
In my opinion this can be considered as a bug because, after the dragging operation, the new tiles are shown and visible (but aren't clickable/draggable). In the first screenshot you can see the starting screen. In the lower right-hand corner there is the L30 tile.
Screenshot 1:
If the user clicks on this tile and drag in the "top-left" direction, new tiles are shown and visible (screenshot 2). The new visible tiles (screenshot 2) aren't clickable and draggable (except for the L30 in the higher left-hand corner).
Screenshot 2:
You can find all the code involved in this issue in my first comment (above):
- on mouseDrag, I move the parent (tiles grid) showing the new tiles
- on mouseUp, I try to force/reattach the listeners on the new visible tiles
Thanks in advance and congrats for CAAT :+1:
I see. The problem may be, that your container is the size of the screen (scene or director), but not the size of a bounding box containing all its children. You can make the container conform to its children size by calling new CAAT.Foundation.ActorContainer(true) If this is not your case, this is definitely a bug.
On the other hand, this is tricky, since organizing such a container, with hundreds of children can be low performant. My advice would be using the builtin quadtree, and overriding the paint method to draw only the selected group of tiles visible on the screen. I can set up a basic huge map with quadtree capabilities if after setting the container conform to its children size you get low performance.
Let me know if this is your case. Thanks for the heads up :)
- ibon
You're right, the problem was the parent size :+1:
Now all works fine, the performance is good on desktop but too lower on mobile. I tested it on Android (Samsung Galaxy S2) and on huge maps it's unusable, with little maps it has a low framerate but it's usable. The framerate is still low with maps that fit the screen (without new tiles printing) with a tiles grid of only 12x10, so I'm thinking about a new explore system (like one button on each side to scroll in a single direction for X tiles).
But, before I try to code a new explore system... do you have any advice to improve performance? Can we try with the quadtree capabilities?
EDIT: for mobile tests I'm using the Ludei cocoonjs cloud compiler, but my app seems to be like the left side of this video: http://vimeo.com/60235958
Thank you very much!
I just found SpriteImage.initializeFromMap(image, map), which answers my question. Does anyone know if I can nest sprite images? Ie, I have a large map of images, and some of them are in themselves image maps (ie, a bunch of buttons). Does that work with CAAT, or do I need to break things up?
Arne
On Sat, 06 Apr 2013 08:12:13 -0700 Francesco Casula [email protected] wrote:
Similar issue here, I have a main ActorContainer called TilesGrid with many Tiles (actors) inside. TilesGrid is biggest than canvas size, so I need a dragging functionality to offer an "explore" mode to the user.
I need a mouseClick listener (tile selection) and a mouseDrag listener (tiles exploration), so the two listeners are attached to the single tile (CAAT.Tile).
CAAT.Tile.prototype.mouseUp = function (mouseEvent) { console.log('hex up', this.Id);
// trying to reattach listeners to the "new" tiles on
mouseUp - didn't work for (var i in this.parent.Hexes) { this.parent.Hexes[i].enableEvents(true); this.parent.Hexes[i].mouseUp = CAAT.Tile.prototype.mouseUp; this.parent.Hexes[i].mouseDrag = CAAT.Tile.prototype.mouseDrag; this.parent.Hexes[i].mouseClick = CAAT.Tile.prototype.mouseClick; } };
CAAT.Tile.prototype.mouseClick = function (mouseEvent) { console.log('hex click', this.Id); this.selected = !this.selected; };
CAAT.Tile.prototype.mouseDrag = function (mouseEvent) { if (!this.oldDragX || !this.oldDragY) { this.oldDragX = mouseEvent.screenPoint.x; this.oldDragY = mouseEvent.screenPoint.y; } else { var speedX = parseInt(this.oldDragX - mouseEvent.screenPoint.x, 10), speedY = parseInt(this.oldDragY - mouseEvent.screenPoint.y, 10);
if (speedX < 0) { speedX *= -1; } if (speedY < 0) { speedY *= -1; } if (this.oldDragX < mouseEvent.screenPoint.x)
{ this.parent.x += speedX; } else if (this.oldDragX > mouseEvent.screenPoint.x) { this.parent.x -= speedX; }
if (this.oldDragY < mouseEvent.screenPoint.y)
{ this.parent.y += speedY; } else if (this.oldDragY > mouseEvent.screenPoint.y) { this.parent.y -= speedY; }
this.oldDragX = mouseEvent.screenPoint.x; this.oldDragY = mouseEvent.screenPoint.y; }
};
Now, all works fine, clicking and dragging, but when I drag the tiles grid, new tiles are shown, and the listeners on these "new" tiles didn't work.
Reply to this email directly or view it on GitHub: https://github.com/hyperandroid/CAAT/issues/126#issuecomment-15997733