I encountered this really weird situation, I have this bar and I addEventListener to it, so when
the bar's clicked, trace localX
private function _barClicked($e:MouseEvent):void {
trace($e.localX)
}
The weird thing is that, when clicking at the same spot, sometimes it jump to a wrong number
which I can't figure out why, I traced the width of the bar, and it's the right value, the localX is
just giving me random numbers. Has anyone ever ran into this problem? Thanks!
Hmmm, strange
I've tried a simple scenario where I have a rectangle named 'bar' and pasted your listener for the CLICK event, then tried the MOUSE_DOWN event. Both worked fine.
I didn't get random values.
My guess is your bar clip contains other objects inside and you might get values from children of bar, not bar itself. Not sure though, it's just a guess.
You could try to make sure that your values come from $e.currentTarget as $e.target might change depending on: your clip and how many children it holds, position of the click and event phase.
Try
private function _barClicked($e:MouseEvent):void {
trace($e.currentTarget.mouseX);
}
Hope it helps!
I was having the same problem, and Kevin Condon solution from the comment above helped my problem. I am just posting it here, because I almost missed it in the comment.
private function _barClicked($e:MouseEvent):void {
var coord:Point = $e.currentTarget.globalToLocal(new Point($e.stageX, $e.stageY));
trace(coord.x);
}
Thanks Kevin.
Just wanted to note a variation on this problem for those for whom the above is not working.
I was having the same issue - localX showing odd values. Mine weren't random, just far lower than what I expected. I.e., click on the far right of the sprite and get only 17.2, event though the width was reporting as 160.
What I found was that my instance was a scaled version of a symbol who's native width was much less.
Once I set it up so that the symbol and the instance had the same width, I started getting the right values.
Hope this helps someone.
If found that as long as I use the solution that Kevin Condon proposed differences in scaling between different symbols are taken into account and everything works out fine.
Related
I simply added a sprite in AS3:
Sprite myspr = new Sprite();
myspr.addChild(mybitmap);
addChild(myspr);
Then I added an event. I did hitTestPoint for checking mouse is over my sprite or not.
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseCheck);
private function mouseCheck(evt:MouseEvent):void {
var xx:int = stage.mouseX;
var yy:int = stage.mouseY;
if(myspr.hitTestPoint(xx, yy, true)) {
...
// I'm checking mouse over here.
}
evt.updateAfterEvent();
}
Problem is: hitTestPoint gives true when mouse comes to full boundary box. But it should give true only if mouse comes on transparent isometric sprite.
Is there a solution for this, thanks in advance.
this should help. You need pixel perfect detection.
Actionscript 3 pixel perfect collision. How to? (learning purposes)
http://www.freeactionscript.com/2011/08/as3-pixel-perfect-collision-detection/
http://www.anotherearlymorning.com/2009/07/pixel-perfect-collision-detection-in-actionscript-3/
http://old.troygilbert.com/2009/08/pixel-perfect-collision-detection-revisited/
There's a few ways I usually do hit testing.
1) The easiest way is to use a an already made class that you can find online. Some people much smarter than me have created complex classes that allow for much better pixel to pixel interaction. The ones listed by Paras are all good. The problem with these is, for newer users, it can be hard to understand all the code and how to implement them. Usually it is simple once you understand what is going on though. You just replace your hit test with the class file and then enter in the correct arguments.
2) Another method is to actually go into the symbol, create a new layer, and then draw a rectangle(just turn the alpha down to 0%) where you want the hit test to work. This may seem like a stupid method, after all we are just confined to a square once again. BUT, it will actually work MUCH better than you'd expect. Just draw the square maybe slightly smaller than the height and width of your character you're detecting the hit test on, and you should be good to go. Give it an instance name (the hit square that is) and then just perform the hitTest with that square instead of the actual sprite. It works wonderfully and is a very simple solution. For what you're explaining though, this sounds like it might not work. This method is more from a gamer standpoint. It looks good when attacking and getting hit by enemies, but isn't necessarily exact. Also, if you want to do this with two characters (maybe a large attack hitting an enemy) simply draw a hit box for both sprites. This is probably a little more basic than using a pre-made pixel perfect hit detection test, but it works extremely well and takes only a few minutes.
I'm new to AS3/Flash and stackoverflow and have tried to browse through different threads with this issue.
My issue is that when I rollover too quickly on one of my buttons, the button will rollover to the "Click" state. I have a tester that debugs the line "hit! " and whenever that glitch happens, the tester does not show the line "hit" so I know that it isn't actually registering a user-input click.
Interestingly enough, the issue also only happens when I move from the bottom or top of the button to the other side vertically. Faster FPS does seem to minimize the effect but it's still there. I have tried to get rid of my hit area layer, thinking that it was the culprit to the problem somehow but even then it did not do anything.
I'll post the .fla in case anybody can figure this out, would truly appreciate it as it's been driving me nuts.
https://dl.dropboxusercontent.com/u/18672917/Main_Btn_7halp6.fla
Here's the code I used in case someone wants to figure it out solely from possible coding errors. (Also, better_mc.Hit._visible = false; doesn't work it seems)
import flash.events.MouseEvent;
stop();
better_mc.addEventListener(MouseEvent.ROLL_OVER, betterOver);
better_mc.addEventListener(MouseEvent.ROLL_OUT, betterOut);
better_mc.addEventListener(MouseEvent.CLICK, betterClick);
function betterOver(evt:MouseEvent):void{
better_mc.gotoAndPlay("Over");
}
function betterOut(evt:MouseEvent):void{
better_mc.gotoAndPlay(27- (better_mc.currentFrame-10));
}
function betterClick(event:MouseEvent):void {
better_mc.gotoAndPlay("Click");
}
better_mc.hitArea = better_mc.Hit;
better_mc.addEventListener(MouseEvent.MOUSE_DOWN, Hitbox);
function Hitbox (event:MouseEvent){
trace("hit! "+this.name);
better_mc.Hit._visible = false;
};
Ok, got it. this is what is happening
Your calculation on rollout is creating a problem
function betterOut(evt:MouseEvent):void{
**better_mc.gotoAndPlay(27- (better_mc.currentFrame-10));**
}
This expression sometimes returns frame number 28 which is ahead of your 'stop()' which is at frame 27 and so it goes on playing the whole click animation.
27- (better_mc.currentFrame-10)
Try the simple solution of adding 'stop()' before your click animation starts i.e. frame 31 in this case.
See if this sorts your issue.
Can not open your fla as i have CS5 so not much help on that
Not sure why you need both click and mousedown events, code seems fine apart from the gotoAndPlay(labelname) parts since no idea how the animations are added here
Just for the last part of your query
(Also, better_mc.Hit._visible = false; doesn't work it seems)
For AS3, property 'visible' is used and not '_visible' so it will be,
better_mc.Hit.**visible** = false;
Hi Im relatively new to flash developing and i have a quick question about saving user input. I have a maze scene whereby the user navagates a character around until confronted with another object, when the character hits the object a new scene is opened promting the user to pick a solution to a problem. Once the user clicks the correct answer a box appears saying return to the maze, however when clicked and returned to the maze the character starts back in its original postion, where as I would like the scene to resume where it left off, ie the character is at the point where it collided with the object, the object has dissappeared and the character can resume on the same course.
Thanks for giving this a read I hope it makes sense and some one has a solution for me.
I did have some nice images to explain it better but apprently i need 10 reputation points to upload those.
EDIT: First Id like to say thanks for the rep points you bunch of stars and secondly I know using scenes in flash is seriously cr*p practice and outdated but its the way I learnt all those years ago and seen as Flash itself will be outdated soon Im not really looking to learn another approach using sprites or frames, I just kind of want a fix for this way if poss thank you for answering!
EDIT: Wanting the red rectangle to be removed from the scene once the black square collides with it. It also takes you to the next frame upon doing so. here is my code.
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler (event:Event):void
{
if (player.hitTestObject(Risk))
{
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
removeChild(Risk);
nextFrame();
}
}
I'd suggest you forget about Scenes! They are old, buggy, bring loads of issues with code and are generally a Bad Pratice!! So if you are just learning AS3, dont learn with Scenes!!
Use MovieClips or Sprites instead. And just add and remove them as you need!
EDIT:
To ur edit ;)
and seen as Flash itself will be outdated soon
thats just plain false and a widespread misinformation. It just has a new purpose like MultiPlattform Game Development. But thats a whole different discussion.
You could solve this by saving the x,y coordinates and then restoring them. But i promise you, you will run in to alot more problems/bugs as you go allong!
Like saved Points and Time. Will you triger the Questionscene again when u place the player on the object(last Position). Save the answers, and so on ...
Changing to DisplayObjects will save you time in the end. Just saying ;)
EDIT2:
your code in the comment should look like this:
function fl_EnterFrameHandler (event:Event):void
{
if (player.hitTestObject(Risk))
{
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);//remove to prevent errors if it fires again and there is no Object to hitTest
removeChild(Risk);// do what needs to be done on this frame
nextFrame();// and then move to the next
}
}
And following correct convetions and make everybody's life easier reading this, it would look like this!
function fl_EnterFrameHandler (event:Event):void
{
if (player.hitTestObject(risk))
{
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);//remove to prevent errors if it fires again and there is no Onject to hitTest
removeChild (risk);
nextFrame ();
}
}
i'm probaly confusing u now, just use the top one ;)
EDIT3:
Ok, i just had a butchers at it. It's all on a single Frame now. I would have prefered Classes but that'lljust confuse you.
To add new qestions you just have to dublicate the Question MovieClip in the Library and change texts, leave instance names the same tho, then the code will work as is!
DOWLOAD
It is certainly possible. You would store the characters attributes (e.g. current position) within a variable. Then on returning to your game you would use this variable to set the starting position of your character.
I agree that scenes are not the ideal route you should be taking. Possibly reading a good AS3 book would save you hours/days/weeks in the long run.
I've been playing around with HTML5 and canvas and sprites and I've managed to get myself a bit stumped. I was wonderring if there was anyone out there with just a bit more experience than me who could help me 'tune' this (and also make it work).
I've got all the code up on GitHub https://github.com/AlexChesser/jsSprite and have put a live demo up over here http://chesser.ca/jsSprite
What you can see from Test 01 and 02 is that I'm able to send the Minotaur directly to the on-page canvas, I'm able to animate the Minotaur on the canvas... but when I try to create the Minotaur and add it to another canvas - I'm getting a blank screen.
(attempting to implement https://github.com/AlexChesser/jsSprite/blob/master/03-animated_minotaur_on_canvas.php)
I know it must be something small and sill that I'm doing wrong here, but I've been staring at it for hours and I can't track down the problem.
I thought I'd try posting up here to see if there's anyone who can see it 'in one go' AND to maybe let me know if there's anything I can do better.
If you're interested in getting a little further under the hood on this stuff, the lion's share of the code for this is coming from a Blog post http://www.johnegraham2.com/web-technology/html-5-canvas-tag-sprite-animation-demo/
Anyways, maybe it's one of those things that "comes to you" once you've walked away from the problem for a little bit. Fingers crossed I can either figure it out or someone out ther ecan give me that little push in the right direction.
Thanks!
:)
I just stepped through your code.
MainContext.drawImage(m.canvas, 0, 0, m.width, m.height);
is occuring before drawFrame gets called because the image isn't ready yet.
So the mainContext.drawImage is drawing a canvas that has nothing painted on it yet.
Then the Sprite's canvas is loaded and ready to go, but its too late!
For confirmation, you can call MainContext.drawImage(m.canvas, 0, 0, m.width, m.height); in the browser console and you will see the minotaur appear.
As Simon Sarris said, you are drawing the canvas too soon. What you'll need to do is either loop until the sprite is ready, or add a callback to your sprite that is called after it draws.
You already have a function attached to the image's onload event, you should be okay to do something similar for the whole sprite.
I am creating a photo editor app where, at some point, the photo you edit is supposed to be dropped between two layers of DisplayObjects (a background image and an image mask.)
There is a problem, though. When the image you are editing is dropped between the background and the image mask layers, it becomes unclickable, and therefore gets stuck there, with no chance of dragging it again. (The photo editor uses TransformManager library.)
I am looking for a way to allow you to select the image you are editing no matter if there is another DisplayObject on top of it. And that probably means finding some way to click through the image mask.
Is there a way to do that?
I tried setting mouseChildren = false on imageMask, but that didn't have the desired effect.
Many thanks.
I had similar problems and I managed to solve it by using both
displayobject.mouseChildren = false;
and
displayobject.mouseEnabled = false;
on the object that you want to click through.
How about this?
mask.mouseEnabled = false;
You can always attach a Mouse Click listener to the container, and then either use GetObjectsUnderPoint and check for your object or do a hit test and see if the mouse position is over your intended object.
The hit test would look something like this !this.YourPhoto.hitTestPoint(stage.mouseX, stage.mouseY, false)
b
If I understand your problem, this handy class should solve it:
http://www.mosessupposes.com/utilities/InteractivePNG.html
Take a look at what senocular does here, specifically in the handleUpdate method. Basically: getting a list of everything under the mousePoint to find your object.
I think I stumbled upon similar problem, although in as2.
In flash when you position movie clip over movie clip, and the movie clip on the top has any mouse events implemented, it captures all mouse events so they never reach occluded movie clip.
The solution is not to have any mouse events for the top movie clip and have the movie clip positioned at the bottom capture mouse event and redirect some of them to the top movie clip (you can check mouse position with hitTest to determine if they should be redirected).
i had a strange bug i used;
movieClip.mouseEnabled = false;
but wasn't working for some reason.. was driving me crazy!! as i have used it so many times before. tried lots of different things nothing worked then i deleted the MovieClip and the created a new one and worked.. so the MovieClip's contents must have been corrupt or something as it had a old dynamic Text Area box embedded within the MovieClip.
hope this helps someone out there..