Libgdx cursor disappears - libgdx

In my LibGdx game i am changin the cursor a lot. For example there are circles you can resize and the "resize cursor" must rotate. I have a .png for every 10°. It works but after playing with it for a while the cursor disappears. It reappears again, when I move the mouse outside the circle and set it back to Gdx.graphics.setSystemCursor(Cursor.SystemCursor.Arrow); But after that it gets invisible again, when setting a custom cursor(hovering over the circle). This is the code (simplified), I have in mouseMoved():
if(showResizeCursor) {
Gdx.graphics.setCursor(Gdx.graphics.newCursor(
resizeCursor(mousePos,center), 32, 32));
} else {
Gdx.graphics.setSystemCursor(Cursor.SystemCursor.Arrow);
}
The function resizeCursor() returns a Pixmap rotated in the right angle.

Related

AS3: How can I implement a perfect ROLL_OVER(or MOUSE_OVER) event listener on curved movieclips

I've a problem with ROLL_OVER event listener. When I enter the empty area withing the movieclip with mouse cursor, ROLL_OVER event triggers. But I want that event trigger only when mouse cursor is on the colored area.
To Make it more clear: Think about " O " letter, when mouse cursor is between the empty area of O letter (inside of O) , event shouldn't trigger. It should trigger only when mouse curser is on the black area.
How can I implement this?
Thanks
-Ozan
PROBLEM IS SOLVED THANKS TO #Ethan Kennerly
I just want to add a few things to help people have problem same as me. In my situation I tried to make continents glow when my mouse is over them. I used the ROLL_OVER/MOUSE_OVER eventlistener to check if my mouse is over them or not. But with the data given by Ethan Kennerly I produced another way.
In Ethan Kennerly's solution, if your mouse enters the area of continent from a transparent area , it doesn't get blur effect because ROLL_OVER and MOUSE_OVER event listeners only trigger once per enters so I used MOUSE_MOVE event listener on each continent movieclips.
And for this statement:
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
add whatever is in the "ROLL_OUT or MOUSE_OUT" eventlistener function, add all of them inside this statement. But don't remove ROLL_OUT or MOUSE_OUT functions.
It sounds like the movie clip contains a shape that has transparent pixels. Transparent pixels respond to mouse over and roll over. If you could draw vector graphics that have no shapes with transparent pixels, the mouse would ignore the empty space in the movie clip's bounding box.
Yet it sounds like you need to use transparent pixels and you want the mouse to ignore them, so you could guard, like this:
private function onRollOver(event:MouseEvent):void
{
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
// respond to roll over.
}
To detect transparency, Miguel Santirso rendered the pixels and translated the coordinate space here: http://sourcecookbook.com/en/recipes/97/check-if-a-pixel-is-transparent-in-a-displayobject (Except line 38 looks on my computer like "rect" got rendered as "ct"). You could optimize that code by only drawing the pixel in question, instead of the whole image, and checking if that pixel value (getPixel32) is 0, instead of calling a hitTest. I would optimize Miguel's code like this:
public static function isPixelTransparent(objectOnStage:DisplayObject, globalPoint:Point):Boolean
{
var local:Point = objectOnStage.globalToLocal(globalPoint);
var matrix:Matrix = new Matrix();
matrix.translate(-local.x, -local.y);
var data:BitmapData = new BitmapData(1, 1, true, 0x00000000);
data.draw(object, matrix);
return 0x00000000 == data.getPixel32(0, 0);
}
By the way, if all your movie clips would have the same hit test shape, you could create a separate transparent shape that listens to the roll over. I use a transparent shape to define a custom hit test shape that is a consistent and simple shape (like a circle) when the image is a more complicate shape (like an X or an O with nothing in the middle). The custom hit test shape is a Sprite with a transparent shape. The sprite listens to the roll over. A separate mouse listener shape is also useful if your movie clip, on later frames, creates new shapes that alter the silhouette of the movie clip.
The easiest solution would be using the Interactive PNG class by Moses.
http://blog.mosessupposes.com/?p=40
Normally the clear areas of a PNG are treated as solid, which can be especially frustrating when dealing with a lot of images that overlap each other because they tend to block mouse interactions on the clips below them.
This utility fixes that so that mouse events don't occur until you
bump against a solid pixel, or a pixel of any transparency value
besides totally clear. InteractivePNG lets you set an alphaTolerance
level to determine what transparency level will register as a hit.

displacementMapfilter floats with object below it

I've been creating a magnifier class using a standard displacementMapfilter similar to Adobe's and numerous other examples: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7da2.html
The filter is being used at the application level so it filters everything, and there's a large number of image elements that can be dragged, rotated, and scaled around the screen, and when passed below this filter it magnifies them. I also intend to add some more functionality to allow dragging the filter around.
The filter works as intended, magnifying everything that passes by it. The weird thing is whenever an image is being dragged outside of the top or left edge of the screen, the filter floats in that direction the distance it takes before the image is entirely offscreen (ie: the filter floats 500 pixels left if a picture 500 pixels wide is pulled offscreen to the left.)
I'm using an enterFrame listener to constantly update its position, and it works as follows:
private function onEnterFrame(e:Event):void {
dPoint.x = stage.stageWidth - radius;
dPoint.y = stage.stageHeight - radius;
dFilter = new DisplacementMapFilter(map, dPoint, BitmapDataChannel.RED, BitmapDataChannel.BLUE, 100, 100, DisplacementMapFilterMode.IGNORE, 0x000000, 0);
// The application is a displayObject itself, so just apply filters to "this"
this.filters = [dFilter];
}
So this code should anchor the filter at the bottom right of the screen, yet somehow whenever an image is dragged off, the filter drifts with it. Is there any reason a filter would do that, and any way I could stop it?
Dragging an image off the stage changes the size and shape of the rectangle the filter is being applied to (picture the filter as if it's taking a snapshot of everything on the stage). When the image moves off the top left, it means that (0, 0) on the filter is actually at the top left corner of the image.
If you check the bounds of the stage (in the stage's own coordinate space), you should see top and left become negative numbers when you drag an image off:
stage.getBounds(stage).top;
stage.getBounds(stage).left;
Cancelling out any negative bounds should keep your filter in the correct position:
var stageBounds:Rectangle = stage.getBounds(stage);
if (stageBounds.left < 0) {
dPoint.x -= stageBounds.left;
}
if (stageBounds.top < 0) {
dPoint.y -= stageBounds.top;
}

XY restrictions for custom mouse cursor in Actionscript3

I have this interactive 5 seconds animated intro for a website. the preloader and one item are animating and i made the second animation follow the mouse cursor but it has to stay within a certain part of the stage to work with the other animation happening on screen.
I have this code on the movie clip
Mouse.hide();
potistiri.addEventListener(Event.ENTER_FRAME, newCursor);
function newCursor(event:Event): void { potistiri.x = mouseX;
potistiri.y = mouseY; }
and i like i said i just want it to stay in the area i want...
i found this code which gives me errors for not putting the staments if and else if correctly or that it needs a rightparen when i input my numbers in...
if(this._x>Stage.width){
this._x=Stage.width;
}else if(this._x<0){
this._x=0; }
but i cant get it to work...
i need it to move between x 208-656 and y 140-336 and when it gets out of that area the object stay there doing its loop and you see the normal mouse cursor moving in the rest of the screen.
thanks a lot in advance...im leaving my it to the experts in here to pls help me ouy!
The logic you're using in your if/else is fine for clamping the movie clip to a specific area, what exactly do your errors say?
In regards to seeing the normal mouse cursor again you could try using the same if/else checks to determine whether the mouse should or should not be hidden ie if the mouse is outside the area and is hidden, call Mouse.show(), else if it is inside the area and shown, call Mouse.hide().

Drag Won't Stop with ActionScript 3

In writing an ActionScript 3 program, I am trying to make it so that I can drag an object from one location to another after doing some other stuff. The trouble is, I can drag just fine, but apparently I can't stop dragging, even with a listener to make it stop. I can't figure out any reason why this is happening. The relevant part of my code is as follows:
public function setToDragAndDrop(){
this.graphic.removeEventListener(MouseEvent.CLICK, rotate);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
this.graphic.addEventListener(MouseEvent.MOUSE_UP, endDrag);
}
private function drag(e:MouseEvent):void{
trace("Dragging...");
this.graphic.startDrag(true);
trace(this.graphic.hasEventListener(MouseEvent.MOUSE_UP)); //Returns true
}
private function endDrag(e:MouseEvent):void{
trace("Stopped dragging.");
this.graphic.stopDrag();
}
I do not get the "Stopped dragging" line in my output, so the endDrag MouseEvent is never getting called, even though it exists (as the trace proves). So instead whether the mouse is up or down, it continues to drag. I've found that if I click on another draggable object, that one starts dragging instead.
I'm baffled. Any help would be greatly appreciated!
I figured out the problem. Apparently when you create the shape, it's "drag point" is at (0,0), or if you premake the shape in Flash, the upper left corner of the "rectangle" that surrounds the figure. When you click on the shape, your mouse jumps to this "drag point."
Apparently, if the drag point does not actually lie on the body of the shape, drag and drop doesn't work. So the ovals I was using earlier didn't work because the drag point was off the shape. Your example did work because it was created at (0,0) and your drag point was at (0,0). But if you draw a circle that isn't at (0,0), like drawCircle(200,200,100) (i.e. draw a circle at point (200,200) with a radius of 100), then you encounter the problem that I have because the drag point is not on the shape.
The solution then is to create the circle at 0,0, then move it to the position you want. It's strange, but I finally got it to work.
public function setToDragAndDrop(){
this.graphic.removeEventListener(MouseEvent.CLICK, rotate);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
}
private function drag(e:MouseEvent):void{
this.graphic.startDrag(true);
this.graphic.removeEventListener(MouseEvent.MOUSE_DOWN, drag);
this.graphic.addEventListener(MouseEvent.MOUSE_UP, endDrag);
}
private function endDrag(e:MouseEvent):void{
this.graphic.stopDrag();
this.graphic.removeEventListener(MouseEvent.MOUSE_UP, endDrag);
this.graphic.addEventListener(MouseEvent.MOUSE_DOWN, drag);
}
it works very well here.
http://wonderfl.net/c/CvWO
Check the flash "fiddle" .

Zoom in Zoom out loop on action script 3

I have this code for my effect to zoom in and zoom out in certains buttons
canada.addEventListener(MouseEvent.MOUSE_OVER, canadaover);
function canadaover(event:MouseEvent):void
{
gotoAndPlay("canadaS");
trace("in");
}
canada.addEventListener(MouseEvent.MOUSE_OUT, canadaout);
function canadaout(event:MouseEvent):void
{
gotoAndPlay("canadaF");
trace("out");
}
canada.addEventListener(MouseEvent.CLICK, clickcanada);
function clickcanada(event:MouseEvent):void
{
trace("Mouse clicked");
}
the problem is when u reach certain corner of the button it kinda gets into a loop, any ideas how can i fix this?
here its the link of the swf i'm trying to do:
http://viajescupatitzio.com/america%20map.swf
If your buttons are MovieClips you can add inside a layer with a mask (for example rectangle) on top. Mask width and height should be your mouseover region and give it alpha = 0. It will be invisible, but it will work with MOUSE_OVER and MOUSE_OUT Events.
You should move your buttons into a different hierarchy level than the graphics you are changing - even if the buttons disappear, or are covered with graphics for just a very short moment, both mouseOver and mouseOut events will be fired (the mouse has left and reentered the button) - and that probably causes your "loop".
It is generally a good idea to have animations and graphical objects within nested MovieClips, and place control elements on a higher level of the display list - that way you can make sure the elements don't overlap and/or interfere.