as3: MOUSE_OVER is slow/not working correctly - actionscript-3

Okay so I'm working in pure as3 (no creative suite or xml). I have a sprite. It draws a large rectangle and then a slightly smaller rectangle. I want to change the color of the slightly smaller rectangle when I hover the mouse over it. Right now though it will either not respond (I can plainly have the mouse over the rectangle and nothing happens) or it is slow to respond. In addition the collision area of the rectangle seems a bit off, ie it responds more frequently when I have the mouse on the upper left corner of the rectangle than when I have the mouse elsewhere on it.
Anyways here's the code I'm using:
public function MAIN()
{
BUTTON_1.graphics.clear();
BUTTON_1.graphics.beginFill(0x000000);
BUTTON_1.graphics.drawRect(188,96,104,24);
BUTTON_1.graphics.endFill();
BUTTON_1.graphics.beginFill(0x0000DC);
BUTTON_1.graphics.drawRect(190,98,100,20);
BUTTON_1.graphics.endFill();
addChild(BUTTON_1);
BUTTON_1.addEventListener(MouseEvent.MOUSE_OVER,MOUSE_OVER_1);
function MOUSE_OVER_1():void
{
removeChild(BUTTON_1);
BUTTON_1.graphics.clear();
BUTTON_1.graphics.beginFill(0x000000);
BUTTON_1.graphics.drawRect(188,96,104,24);
BUTTON_1.graphics.endFill();
BUTTON_1.graphics.beginFill(0x0000A0);
BUTTON_1.graphics.drawRect(190,98,100,20);
BUTTON_1.graphics.endFill();
addChild(BUTTON_1);
}
}
I'm pretty new to as3 so if there's a better way to do this tell me.

this code doesn't seem correct. listener for mouse events takes MouseEvent object as parameter. So your MOUSE_OVER_1 should be like function MOUSE_OVER_1(e:MouseEvent):void.

I ended up using hitTestPoint, like this:
if (BUTTON_1.hitTestPoint(mouseX,mouseY,true))
{
removeChild(BUTTON_1);
removeChild(TEXT_MENU_1);
BUTTON_1.graphics.clear();
BUTTON_1.graphics.beginFill(0x000000);
BUTTON_1.graphics.drawRect(188,96,104,24);
BUTTON_1.graphics.endFill();
BUTTON_1.graphics.beginFill(0x0000A0);
BUTTON_1.graphics.drawRect(190,98,100,20);
BUTTON_1.graphics.endFill();
addChild(BUTTON_1);
addChild(TEXT_MENU_1);
}
else
{
removeChild(BUTTON_1);
removeChild(TEXT_MENU_1);
BUTTON_1.graphics.clear();
BUTTON_1.graphics.beginFill(0x000000);
BUTTON_1.graphics.drawRect(188,96,104,24);
BUTTON_1.graphics.endFill();
BUTTON_1.graphics.beginFill(0x0000DC);
BUTTON_1.graphics.drawRect(190,98,100,20);
BUTTON_1.graphics.endFill();
addChild(BUTTON_1);
addChild(TEXT_MENU_1);
}

Related

Handle friendly fire collision detection

I want to create a friendly-fire mechanism. Essentially, my cubes fire repeatedly a bullet to hit enemies. I also want to detect the hit between the bullet and another cube (friendly fire). In order to avoid that the bullet's boundaries overlap with the cube that fired it, in my "Cube" class i overrided equals. Each Cube has a unique id, initialized as soon as the Cube is created.
The issue is that i have a very bad bug. When i add the first Cube all behaves normally, but as soon as i add the second one, a collision is detected for both the cubes' bullets, instantly, even if they are not firing to each other. This happens even if i add more cubes. I checked the boundaries and they seems fine.
I put some code:
collision detection
// check collisions between bullets and cubes (friendly fire)
for(BaseBullet bullet : bullets) {
for(BaseSquare square : squares) {
// exclude collision between bullet and its own Cube
if (!bullet.getBaseSquare().equals(square)) {
// check if bounds overlap
if (square.getBounds().overlaps(bullet.getBounds())) {
System.out.println("collision between bullet and qube");
// propagate the event to anyone is interested in it
EventsManager.qubeHitByQube(bullet, square);
bullet.remove();
bulletsToDestroy.add(bullet);
}
}
}
}
cube's equals method
#Override
public boolean equals(Object o) {
if(!(o instanceof BaseSquare) || o == null) {
return false;
}
BaseSquare baseSquare = (BaseSquare)o;
return baseSquare.getUniqueID().equals(getUniqueID());
}
NOTE
With "friendly fire" i mean when your objects hit themselves and not the enemies.
I would suspect the problem is more likely coming from 'if (square.getBounds().overlaps(bullet.getBounds()))' than the square's equals() method.
Are 'BaseBullet' and 'BaseSquare' extending LibGDX's Sprite class? Should you not be calling getBoundingRectangle()?

AS3: Fast hovering doesn't execute rollOut

I'm having a serious problem that is getting me nervous:
I've made a button _btn that includes ROLLOVER and ROLLOUT animations with coding (an nested movieclip instance called barra that increases to half alpha when you hover over and decreases when you hover out).
[Here it should go a descriptive image but I'm new and I need 10 reputation. I'll appreciate your help]
This works perfectly but the problem occurs when I move my cursor very quickly from one point to another, with the button in between. It seems that the ROLLOUT function is not detected, so the ROLLOVER animation keeps working (and if you look carefully, the animation stops for a few seconds and then continues).
[Here it should go another descriptive image too]
This is the code in the Actions layer:
//Funciones ROLL OVER
function _btnOver(event:MouseEvent):void {
_btn.buttonMode = true;
_btn.addEventListener(Event.ENTER_FRAME,_btnFadeIn);
}
function _btnFadeIn(event:Event):void {
_btn.barra.alpha += 0.1;
if (_btn.barra.alpha >= 0.5)
{
_btn.removeEventListener(Event.ENTER_FRAME,_btnFadeIn);
}
}
_btn.addEventListener(MouseEvent.ROLL_OVER,_btnOver);
//Funciones ROLL OUT
function _btnOut(event:MouseEvent):void {
_btn.addEventListener(Event.ENTER_FRAME,_btnFadeOut);
}
function _btnFadeOut(event:Event):void {
_btn.barra.alpha -= 0.1;
if (_btn.barra.alpha <= 0.2)
{
_btn.removeEventListener(Event.ENTER_FRAME,_btnFadeOut);
}
}
_btn.addEventListener(MouseEvent.ROLL_OUT,_btnOut);
Click here if you want to download the FLA and SWF files, so you can see the problem clearly.
I barely know how to use ActionScript 3 (my only programming knowledge is Processing) and I don't have time now to learn it from head to toe, but I've researched about the problem and it's still not clear.
With tutorials and guides, I managed to learn how to create and understand this code, and I think the problem might be in the functions of the events ROLL_OVER and ROLL_OUT, which contain the addEventListener of the ENTER_FRAME events (where the animations actually are), respectively. But I don't know exactly what I have to do to fix it, what should I add or change.
I would be really glad if someone could help with this, I'm frustrated! What do you recommend me to do?
Thanks in advance
(PD: I don't understand most of the programming language. If you can be as clear and direct as possible, I'll really appreciate it)
Apparently your troubles lay in incoherent animation sequence by using enter frame listeners. You are running two independent listeners, both altering alpha of a single object, this creates a conflict, only one will work (you can determine which if you add both at once and trigger events, the resultant alpha value will indicate which listener changes it last) and you apparently expect one to do a fade in while the other to do a fade out. Instead, you should use one listener (probably even persistent) and give your object "target alpha" property as well as delta to change alpha per frame. An example:
var bbta:Number=0.2; // btn.barra's target alpha
_btn.addEventListener(Event.ENTER_FRAME,_btnFade);
function _btnFade(e:Event):void {
var a:Number=_btn.barra.alpha;
if (Math.abs(a-bbta)<1e-8) return;
// no sense of setting alpha with minuscule difference
const delta:Number=0.1; // how fast to change per frame
if (a>bbta) {
a-=delta;
if (a<=bbta) a=bbta;
} else {
a+=delta;
if (a>=bbta) a=bbta;
}
_btn.barra.alpha=a;
}
function _btnOver(event:MouseEvent):void {
_btn.buttonMode = true; // move this elsewhere, if you don't cancel buttonMode
bbta=0.5; // set target alpha, the listener will do a fade-in
}
function _btnOut(event:MouseEvent):void {
bbta=0.2; // set target alpha, the listener will do a fade-out
}
I edited some code in here, basically i am checking hover state onLoop function, so you can change your settings on here
import flash.events.Event;
var isRolledOver:Boolean = false;
//Funciones ROLL OVER
function _btnOver(event:MouseEvent):void {
isRolledOver = true;
}
function _btnOut(event:MouseEvent):void {
isRolledOver = false;
}
_btn.addEventListener(MouseEvent.ROLL_OVER,_btnOver);
_btn.addEventListener(MouseEvent.ROLL_OUT,_btnOut);
this.addEventListener(Event.ENTER_FRAME,onLoop);
function onLoop(e){
if(this.isRolledOver){
if(_btn.barra.alpha < 0.5) _btn.barra.alpha += 0.1;
}
else{
if(_btn.barra.alpha > 0.5 || _btn.barra.alpha > 0) _btn.barra.alpha -= 0.1;
}
}
I added the sample fla in case

"Smooth and Regular" scroll in flash

I am working on a news ticker in Flash AS3. The code is reading some RSS from CNN and generates a MovieClip with headline text one after another. Now this movieclip starts scrolling from right to left. For scrolling I am using TweenLite. I don't want any easing, just want a regular and smooth scrolling.
I have used both options:
TweenLite.to(news_mc, 60, {x:minX} );
and
TweenLite.to(news_mc, 60, {x:minX, ease:Linear.easeNone} );
But, in both case, the animation is not smooth. It starts scrolling speedily and at last it becomes very slow.
I've seen something similar to this. Are you implementing your TweenLite call in a loop? You should only be calling for a tween on the target object once. Only once that tween is finished or you want a brand new tween on that object should you call TweenLite.to with that target object again.
Seeing as how you're only after a linear tween, would it not be simpler to simply increment/decrement the target's X every frame? Something like this:
this.addEventListener(Event.ENTER_FRAME, onEnterFrame)
private function onEnterFrame(e:Event):void
{
if(news_mc.x > minX)
{
news_mc.x -= 3 //This is a shot in the dark, tweak this for your values
}
else
{
news_mc.x = maxX
}
}

How to make a stick man running when pressing a key?

I created a movieclip named stickman. In that, I created an animation by drawing a sequence of move in everyframe, so that stickman can run. Now what I want is that when I press a key, the stick man will run from left to right and when I release the key, it will stop. This is my code:
RunningMan.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN,keypresseddown);
function keypresseddown(event:KeyboardEvent):void
{
var key:uint = event.keyCode;
switch (key) {
case Keyboard.LEFT :
{
RunningMan.play();
RunningMan.x-=10;
RunningMan.scaleX=-1;
if(RunningMan.x<=0)
{
RunningMan.x=0;
}
};
case Keyboard.RIGHT :
{
RunningMan.play(); //play animated run
RunningMan.x+=10;
RunningMan.scaleX=1;
if(RunningMan.x>=stage.width)
{
RunningMan.x=stage.width;
}
};
default: RunningMan.stop();
}
}
However, when I pressed and held a key, it moved from left to right without animated run.
How can I fix it?
Thanks in advance.
EDIT:
I have a movieclip called character containing 3 movieclip named: standing, running and jumping, respectively. When I pressed up arrow key, it would jump, but if I released the key right away, it did not jump high as the jump movieclip could not finish its frames. This is the code:
if (key.isDown(Keyboard.LEFT))
{
gotoAndStop("running");
BGround.x+=speed;
scaleX=-1;
if(BGround.x>=stage.stageWidth)
BGround.x=stage.stageWidth;
}
else if (key.isDown(Keyboard.RIGHT))
{
gotoAndStop("running");
BGround.x -= speed;
scaleX=1;
}
else
if (key.isDown(Keyboard.UP))
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
How can I fix that?
First of all, I hope RunningMan is an instance of the class, not the class itself. And if it is an instance, you should really follow common naming conventions for when you share your code with others (like you are doing now) so it would be runningMan.
So 1st, make the 1st frame of the runnigMan's timeline a picture of the man standing still and name it "still" or something. then name the second "running" and extend that like 20 frames or however long your animation is. at the last frame you will have to use timeline code. just one line of gotoAndPlay("running") will cause those frames of 2 to 20 (or whatever) to loop. When you tell the timeline to go to frame 1 from outside the timeline code, it wont loop anymore and will stay on the frame of the man standing still. So from outside when you want the loop to start:
runningMan.gotoAndPlay("running"); // frame 2
To stop:
runningMan.gotoAndStop("still"); // frame 1
Or you could do it from inside the RunningMan class
public function startRunAnimation():void{
this.gotoAndPlay("running");
}
public function stopRunAnimation():void{
this.gotoAndStop("still");
}
And you could use them just by replacing these function names with the ones you have if your code ex( instead of play() it would be startRunAnimation() )
EDIT
What you could do for this problem is to have a boolean variable for when your character is in the air (somewhere in your code where you do collision detection with the ground or where you handle gravity - however it is set up) so that this part of your code know when your character is in the air. And then you could simple test for this however way you need it.
...
if (key.isDown(Keyboard.UP) || this.inAir==true)
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
Although if your character does not inheirt from a collidable object that has gravity, friction etc... then you would have to make the inAir property of whatever other class, public or make getter function for it - so that you can access it here. I hope this helps.

Flash CS6 Actionscript 3.0 button rollover forces movieclips to play uncontrollably

I'm a beginner when it comes to Actionscript 3.0 for Adobe Flash CS6. I'm trying to make a basic, plain animated interactive logo for a web portfolio, and have encountered a problem while trying to fix rollOver issues with triangles in the logo. With the current coding I've learned on my own, I'm able to get the animations and reactions just fine with movie clips instead of buttons. However, the execution of this method causes the "hit-boxes" of whichever movie clip is front-most on stage to play its animation even if you're trying to mouse over a movie clip behind it.
Here is the web page in question:
http://inancarrow.wix.com/home
Notice how when you roll over the left corner or bottom corner of the yellow triangle, the blue "Games" animation or the green "Skills" animation fades in and plays instead of the yellow "Connect" animation.
I have attempted to remedy this small but annoying problem by attempting to turn the movie clips to buttons, allowing an accurate response when people mouse over the shapes. The result is that all the movie clips that have animation play uncontrollably and loop their animations. From the searching I've done, it has something to do with nested movie clips...
I've spent too much trying to figure out what is wrong and how to fix the problem by myself, which is why I'm asking for help, advice, or insight as to how to either fix the overlapping rollOver problem, or how to fix my movieClips playing uncontrollably.
Here is the code I've been using:
RedIFader.addEventListener(MouseEvent.ROLL_OVER, RedIOver);
RedIFader.addEventListener(MouseEvent.ROLL_OUT, RedIOut);
//RedIFader.addEventListener(MouseEvent.ROLL_OVER, RedIClick);
function RedIOver(event:MouseEvent):void{
BioFadeIn.gotoAndPlay("BioFadeInOver")
BlueAFader.gotoAndPlay("BlueAFaderOver")
GreenAFader.gotoAndPlay("GreenAFaderOver")
YellowNFader.gotoAndPlay("YellowNFaderOver")
}
function RedIOut(event:MouseEvent):void{
BioFadeIn.gotoAndPlay("BioFadeInOut")
BlueAFader.gotoAndPlay("BlueAFaderOut")
GreenAFader.gotoAndPlay("GreenAFaderOut")
YellowNFader.gotoAndPlay("YellowNFaderOut")
}
BlueAFader.addEventListener(MouseEvent.ROLL_OVER, BlueAOver);
BlueAFader.addEventListener(MouseEvent.ROLL_OUT, BlueAOut);
//BlueAFader.addEventListener(MouseEvent.ROLL_OVER, BlueAClick);
function BlueAOver(event:MouseEvent):void{
GamesFadeIn.gotoAndPlay("GamesFadeInOver")
RedIFader.gotoAndPlay("RedIFaderOver")
GreenAFader.gotoAndPlay("GreenAFaderOver")
YellowNFader.gotoAndPlay("YellowNFaderOver")
}
function BlueAOut(event:MouseEvent):void{
GamesFadeIn.gotoAndPlay("GamesFadeInOut")
RedIFader.gotoAndPlay("RedIFaderOut")
GreenAFader.gotoAndPlay("GreenAFaderOut")
YellowNFader.gotoAndPlay("YellowNFaderOut")
}
GreenAFader.addEventListener(MouseEvent.ROLL_OVER, GreenAOver);
GreenAFader.addEventListener(MouseEvent.ROLL_OUT, GreenAOut);
//GreenAFader.addEventListener(MouseEvent.ROLL_OVER, GreenAClick);
function GreenAOver(event:MouseEvent):void{
SkillsFadeIn.gotoAndPlay("SkillsFadeInOver")
RedIFader.gotoAndPlay("RedIFaderOver")
BlueAFader.gotoAndPlay("BlueAFaderOver")
YellowNFader.gotoAndPlay("YellowNFaderOver")
}
function GreenAOut(event:MouseEvent):void{
SkillsFadeIn.gotoAndPlay("SkillsFadeInOut")
RedIFader.gotoAndPlay("RedIFaderOut")
BlueAFader.gotoAndPlay("BlueAFaderOut")
YellowNFader.gotoAndPlay("YellowNFaderOut")
}
YellowNFader.addEventListener(MouseEvent.ROLL_OVER, YellowNOver);
YellowNFader.addEventListener(MouseEvent.ROLL_OUT, YellowNOut);
//YellowNFader.addEventListener(MouseEvent.ROLL_OVER, YellowNClick);
function YellowNOver(event:MouseEvent):void{
ConnectFadeIn.gotoAndPlay("ConnectFadeInOver")
RedIFader.gotoAndPlay("RedIFaderOver")
BlueAFader.gotoAndPlay("BlueAFaderOver")
GreenAFader.gotoAndPlay("GreenAFaderOver")
}
function YellowNOut(event:MouseEvent):void{
ConnectFadeIn.gotoAndPlay("ConnectFadeInOut")
RedIFader.gotoAndPlay("RedIFaderOut")
BlueAFader.gotoAndPlay("BlueAFaderOut")
GreenAFader.gotoAndPlay("GreenAFaderOut")
}
Thank you for your time and consideration.
I'm not sure I understand your problem, but if I do, this is a solution you could do:
on your roll over handlers, set other colors mouseEnabled and mouseChildren properties to false.
RedIFader.mouseEnabled = false;
RedIFader.mouseChildren = false;
then on your roll out, set them all back to true:
RedIFader.mouseEnabled = true;
RedIFader.mouseChildren = true;
This will prevent the other colors from triggering mouse events until the mouse leaves the current color.
If this isn't your issue, then I would suggest using dummy objects:
Create a dummy shape (with an alpha of 0), convert it to a movieClip and put it where you want the mouse over to happen. Then add the roll over/out listeners to the dummys. You probably want to set mouseEnabled & mouseChildren to false on all the color objects so they don't get in the way.
//disable all the color buttons mouse interactions
RedIFader.mouseEnabled = false;
BlueAFader.mouseEnabled = false;
GreenAFader.mouseEnabled = false;
YellowNFader.mouseEnabled = false;
RedIFader.mouseChildren = false;
BlueAFader.mouseChildren = false;
GreenAFader.mouseChildren = false;
YellowNFader.mouseChildren = false;
//add listeners to the dummys
RedDummy.addEventListener(MouseEvent.ROLL_OVER,btnRollOver);
RedDummy.addEventListener(MouseEvent.ROLL_OUT,btnRollOut);
BlueDummy.addEventListener(MouseEvent.ROLL_OVER,btnRollOver);
BlueDummy.addEventListener(MouseEvent.ROLL_OUT,btnRollOut);
GreenDummy.addEventListener(MouseEvent.ROLL_OVER,btnRollOver);
GreenDummy.addEventListener(MouseEvent.ROLL_OUT,btnRollOut);
YellowDummy.addEventListener(MouseEvent.ROLL_OVER,btnRollOver);
YellowDummy.addEventListener(MouseEvent.ROLL_OUT,btnRollOut);
function btnRollOver(e:Event):void {
if(e.currentTarget != RedDummy){
RedIFader.gotoAndPlay("RedIFaderOver");
}else{
BioFadeIn.gotoAndPlay("BioFadeInOver")
}
if(e.currentTarget != BlueDummy){
BlueAFader.gotoAndPlay("BlueAFaderOver");
}else{
GamesFadeIn.gotoAndPlay("GamesFadeInOver");
}
if(e.currentTarget != GreenDummy){
GreenAFader.gotoAndPlay("GreenAFaderOver");
}else{
SkillsFadeIn.gotoAndPlay("SkillsFadeInOver");
}
if(e.currentTarget != YellowDummy){
YellowAFader.gotoAndPlay("YellowAFaderOver");
}else{
ConnectFadeIn.gotoAndPlay("ConnectFadeInOver");
}
}
function btnRollOut(e:Event):void {
if(e.currentTarget != RedDummy){
RedIFader.gotoAndPlay("RedIFaderOut");
}else{
BioFadeIn.gotoAndPlay("BioFadeInOut")
}
if(e.currentTarget != BlueDummy){
BlueAFader.gotoAndPlay("BlueAFaderOut");
}else{
GamesFadeIn.gotoAndPlay("GamesFadeInOut");
}
if(e.currentTarget != GreenDummy){
GreenAFader.gotoAndPlay("GreenAFaderOut");
}else{
SkillsFadeIn.gotoAndPlay("SkillsFadeInOut");
}
if(e.currentTarget != YellowDummy){
YellowAFader.gotoAndPlay("YellowAFaderOut");
}else{
ConnectFadeIn.gotoAndPlay("ConnectFadeInOut");
}
}
For me it seems to comes from the fact that your clips are triangles, probably using pictures for the blue, green, yellow triangles and the red i (PNG format images ?...).
The fact is that rollovers on pictures tend to get dispatched even when rolling on transparent areas of a PNG, thing that is obviously happening here.
To solve that, you could try using for example that InteractivePNG class that is supposed to take care of this problem.
And if you're not using PNGs files, the solution is as easy as removing any existing vector fill, even the transparent ones, from the empty parts of your movieclips.