Collision event twice as3 - actionscript-3

I have a brick clip that goes to frame 2 when hit by a ball clip. This code is inside the brick class, which is why why it is referred as "this":
if (this.hitTestObject(_root.mcBall)){
_root.ballYSpeed *= -1;
this.gotoAndStop(2);
}
My question is when it is hit the second time how can it go to frame 3? What code do I need to add?

Try a "clean" approach, like this:
if (this.hitTestObject(_root.mcBall)){
_root.ballYSpeed *= -1;
if (this.currentFrame !== 3) {
this.nextFrame();
}
}
This makes the clip go to its next frame if its current frame isn't 3.

You can verify the current frame of your brick and then if it's frame 2 go to frame 3, like this :
if (this.currentFrame === 2){
this.gotoAndStop(3)
}
You can also use a boolean to indicate if your brick has been hit. If true, go to frame 3.
EDIT
AS code :
- Using a boolean :
...
var hit:Boolean = false
...
if (this.hitTestObject(_root.mcBall)){
_root.ballYSpeed *= -1
if(!hit){ // this is the 1st time so set hit to true and go to frame 2
hit = true
this.gotoAndStop(2)
} else { // this is the 2nd time so go to frame 3
this.gotoAndStop(3)
}
}
- Using currentFrame :
if (this.hitTestObject(_root.mcBall)){
_root.ballYSpeed *= -1
if (this.currentFrame == 1){ // we are in the 1st frame so go to frame 2
this.gotoAndStop(2)
} else { // we are certainly not in the 1st frame so go to frame 3
this.gotoAndStop(3)
}
}
I hope that is more clearer.

Related

How can I fix the wrong timing of my fade/scroll animation?

Currently I'm busy with Actionscript. I have a map with diverse worlds. If you click on an arrow icon you will scroll to the other world. The code is:
street.street_market.addEventListener(MouseEvent.CLICK, straat_actie2);
function straat_actie2(evt:MouseEvent) {
market.bringToFront();
MovieClip(root).worldmap.targetX = marktx;
MovieClip(root).worldmap.targetY = markty;
old = "street";
new = "market";
addEventListener(Event.ENTER_FRAME, fade);
}
The worlds are sliding to each other and the other one is fading out. It works like this:
addEventListener(Event.ENTER_FRAME, ballEnterFrame)
function ballEnterFrame (pEvent):void
{
var b = pEvent.currentTarget;
b.x += (b.targetX - b.x) / 16;
b.y += (b.targetY - b.y) / 16;
}
function fade(e:Event)
{
if(new != "")
{
this[new].alpha+=0.03;
if(this[old].alpha >= 0.2)
{
this[old].alpha-=0.05;
}
}
}
It all works fine. Except one thing. The longer you stay on a world map the longer it will take to let the other world fade out. So if I stay on the street map for 10 secs and I scroll to the next one it takes around 10 seconds before the old map fades out.
Does someone know how I can solve this problem?
Thanks.
Try setting up your function like this...
function fade(e:Event)
{
if( new != "")
{
//# add : ONLY if less than 1 (full opacity)
if ( this[new].alpha < 1 )
{ this[new].alpha += 0.03; } //# fade in (increase)
//# minus : if NOT 0 -OR- is NOT less than 0 (transparent)
if ( this[old].alpha != 0 || !( this[old].alpha < 0 ) )
{ this[old].alpha -= 0.05; } //# fade out (reduce)
//# clamp within limits of 0 to 1 range
if ( this[new].alpha > 1 ) { this[new].alpha = 1; } //# never higher than 1
if ( this[old].alpha < 0 ) { this[old].alpha = 0; } //# never less than 0
}
}//# end function fade
Explained :
...if I stay on the street map for 10 secs and I scroll to the next
one it takes around 10 seconds before the old map fades out.
Do you realise that ENTER_FRAME is something that happens every frame according to your SWF's frame rate (FPS)?. If you set 30 FPS in your Document settings, by your code you are adding 0.03 x 30 every second for 10 seconds. The .alpha amount rises higher than 1, now the delay is waiting for it to reduce from 9.0 back to 1 then it fades out as expected. There is no visual benefit to allowing alpha values to become anything higher than 1 or less than 0.

Libgdx: Pause between one cycle of animation

I have animation with 5 frames. I want to make pause for x seconds every time one animation cycle ends
1,2,3,4,5 (pause) 1,2,3,4,5 (pause) ...
Array<AtlasRegion> regions = atlas.findRegions("coin");
animGoldCoin = new Animation(1.0f / 20.0f, regions, PlayMode.LOOP);
I can't find way to do this.
Thanks
I don't really like the animation class, you can make your own.
float pauseTime=5f; // lets say that you want to pause your animation for x seconds after each cicle
float stateTime=0f; // this variable will keep the time, is our timer
float frameTime=1/20f; //amount of time from frame to frame
int frame=0; // your frame index
boolean waiting=false; // where this is true, you wait for that x seconds to pass
void Update()
{
stateTime+=Gdx.graphics.getDeltaTime();
if(!waiting && stateTime>frameTime) // that frame time passed
{
stateTime=0f; // reset our 'timer'
frame++; // increment the frame
}
if(waiting && stateTime>=0)
{
frame=0;
waiting=false;
}
if(frame>=NUMBER_OF_FRAMES)
{
frame--;
waiting=true;
stateTime=-pauseTime;
}
}
}
I think this will work, do you understand what I did?
I just had a similar problem but managed to come up with a solution. It works well for me but may not be the best way to go about it.. I'm still learning.
I created a new animation from the old animation's frames but with a speed of 0. It stops on the frame its at until the player speed changes.
if(speedX == 0f && speedY == 0f){
playerIdle = new Animation(0f,playerAnim.getKeyFrames());
playerAnim = playerIdle;
}
I know its an old question, but hopefully this will be useful to someone.
I made a quick solution in my search to pause a Libgdx animation.
I wanted an animation to pause when I pressed the spacebar.
I did try the above method of instantiating a new object and it did work. So I tried to just set the frame duration to 0, but that didn't work for some reason. This a less expensive method w/o instantiation.
If you want to pause an animation simply create three variables two are Boolean variables named toStop and hasLaunched another is a TextureRegion named launchFrame. Haslaunched is used to tell me when the spacebar is pressed.
if (InputHandler.hasLaunched && toStop ) {
launchFrame = launchBarAnimation.getKeyFrame(runTime);
toStop = false;
} else if (InputHandler.hasLaunched && !toStop){
batcher.draw(launchFrame, 90, 20, 50, 37);
} else {
batcher.draw(launchBarAnimation.getKeyFrame(runTime), 90, 20, 50, 37);
}

Chance button in flash AS 3.0

i would like to ask this community for some help with my end-course project. I am making a tell tale game where if you click a button there is a chance of you moving from frame 1 to frame 2 or there is a chance of lets say 30% of going to slide 3. This is the script i am using right now.
stop();
Button1_btn.addEventListener(MouseEvent.CLICK, Shoot_1);
function Shoot_1 (event:MouseEvent):void {
gotoAndPlay(2);
}
I apologize for the poor structure of this post, this is my very first post.
PS: My goal is to make it go and play frame 2 at a % chance or go and play frame 3 at a % chance.
Thank you for your help
My suggestion would be use random number to check if it's greater than 7 because you want 30% of chance to get to frame 3.
stop();
var result:uint
Button1_btn.addEventListener(MouseEvent.CLICK, Shoot_1);
function Shoot_1 (event:MouseEvent) :void
{
result = randomIntBetween(1, 10);
if(result > 7)
{
gotoAndPlay(3);
}
else
{
gotoAndPlay(2);
}
}
var percentage:String = result + '0%';
trace(percentage);
function randomIntBetween(min:int, max:int):int {
return Math.round(Math.random() * (max - min) + min);
}

Actionscript 3: Healthbar and Button

So basically I am making a game in which a button is clicked to decrease the amount of health in a healthbar. I have a button on the stage named fortyfivedown_btn, and a healthbar, which is a 101 frame (includes zero) movieclip. The health bar has an instance name of lifebar. On the stage, the button coding is:
fortyfivedown_btn.addEventListener(MouseEvent.CLICK, fortyfivedownClick);
function fortyfivedownClick(event:MouseEvent):void{
lifebar.health = lifebar.health-45;
}
Inside the healthbar movieclip, I have a layer of coding that is:
var health:int = 100;
gotoAndStop(health + 1);
if(health < 0) health = 0;
else if(health > 100) health = 100;
gotoAndStop(health + 1);
So, there is my coding. The thing is, when the button is clicked, the healthbar does not go down. I traced the health variable in the button:
fortyfivedown_btn.addEventListener(MouseEvent.CLICK, fortyfivedownClick);
function fortyfivedownClick(event:MouseEvent):void{
lifebar.health = lifebar.health-45;
}
{
trace(lifebar.health);
}
I saw that the output is 0. For some reason the button believes the health is 0, when I declared it was 100 inside the healthbar movieclip? Any help is appreciated.
(Edit)
Alright, in answer to the trace question, if I don't do it like that, there is no output. I should say I'm a beginner at this all, and am learning as I go, so please bear with me. Here is my fla file:
https://skydrive.live.com/embed?cid=9AB08B59DCCDF9C6&resid=9AB08B59DCCDF9C6%21107&authkey=AGqFHhlHnvOXvuc
Okay so take the code that was in your lifebar movie clip out entirely, you can just delete that layer for now, then replace the code you have in the main scene with this and you should get the result you want:
fortyfivedown_btn.addEventListener(MouseEvent.CLICK, fortyfivedownClick);
var health:int = 100;
lifebar.gotoAndStop(101);
function fortyfivedownClick(event:MouseEvent):void{
health -= 45;
if(health < 0) health = 0;
else if(health > 100) health = 100;
lifebar.gotoAndStop(health + 1);
//Can write this also: lifebar.health += 45;
trace(health);
}
there's other ways to go about doing this but given your current setup this is going to be the least modification to get what you want. Another option is setting the width on a sprite.
I uploaded a modified fla and companion as file for how I would personally go about doing this instead of including things on the timeline so much:
http://www.mediafire.com/?d38hbm32p71x1n8

Actionscript 3 smooth Sprite movement

I move a Sprite across the screen using the keyboard, at a rate of 10 pixels/ENTER_FRAME event fire. The issue is that, when it moves, you can see it being "redrawn" every 10 pixels, which makes it hard to look at. I haven't seen this in other Flash games.
If you look closely, you can also see this here (although at a much lower scale): http://kirill-poletaev.blogspot.com/2010/07/smooth-character-movement-using-as3.html
I want to get rid of that effect, any ideas?
If the player is at a distance of ... from the screen edge, it stops moving (by moving in the opposite direction), and the BG starts scrolling (the same visual effect can be seen).
Music in playing in the background, a minimap is updated with the player's position.
private function updater(e:Event):void
{
if(up && GlobalVars.vars.upPossible)
{
cont.y-=unit;
setu(); // Player graphics state
}
else if(down && GlobalVars.vars.downPossible)
{
cont.y+=unit;
setd(); // Player graphics state
}
else if(left && GlobalVars.vars.leftPossible)
{
cont.x-=unit;
setl(); // Player graphics state
}
else if(right && GlobalVars.vars.rightPossible)
{
cont.x+=unit;
setr(); // Player graphics state
}
else
{
ups.visible=false; downs.visible=false; rights.visible=false;
lefts.visible=false; normals.visible=true; // Player graphics state
GlobalVars.vars.scXr=0; GlobalVars.vars.scYu=0; GlobalVars.vars.scXl=0;
GlobalVars.vars.scYd=0; cont.x=int(cont.x); cont.y=int(cont.y); //Someone from the Kongregate.com forums suggested this, no visible effect
}
if((cont.x=GlobalVars.vars.maxX))
{
if(cont.x=GlobalVars.vars.maxX && right && GlobalVars.vars.canScrollR) GlobalVars.vars.scXr=1, cont.x-=unit, setr();
}
else GlobalVars.vars.scXl=0, GlobalVars.vars.scXr=0; //BG Scrolling
if((cont.y=stage.stageHeight*7.3/10))
{
if(cont.y=stage.stageHeight*7.3/10 && down && GlobalVars.vars.canScrollD) GlobalVars.vars.scYd=1, cont.y-=unit, setd();
}
else GlobalVars.vars.scYu=0, GlobalVars.vars.scYd=0; //BG Scrolling
if(cont.y>=stage.stageHeight*7.3/10 && cont.x>=GlobalVars.vars.maxX) GlobalVars.vars.minimapTr=1;
else GlobalVars.vars.minimapTr=0;
if(cont.y-unitGlobalVars.vars.sH-cont.height-3.1) GlobalVars.vars.downPossible=false;
else GlobalVars.vars.downPossible=true;
if(cont.x-unitGlobalVars.vars.sW-cont.width-3.5) GlobalVars.vars.rightPossible=false;
else GlobalVars.vars.rightPossible=true;
GlobalVars.vars.plX=cont.x; //for minimap
GlobalVars.vars.plY=cont.y;
Also, key listener functions:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyD, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_UP, keyU, false, 0, true);
private function keyD(e:KeyboardEvent):void
{
if(e.keyCode==37 || e.keyCode==65) left=true;
if(e.keyCode==38 || e.keyCode==87) up=true;
if(e.keyCode==39 || e.keyCode==68) right=true;
if(e.keyCode==40 || e.keyCode==83) down=true;
}
private function keyU(e:KeyboardEvent):void
{
if(e.keyCode==37 || e.keyCode==65) left=false;
if(e.keyCode==38 || e.keyCode==87) up=false;
if(e.keyCode==39 || e.keyCode==68) right=false;
if(e.keyCode==40 || e.keyCode==83) down=false;
}
I've encountered some improvement by increasing the FPS to 120, and decreasing the step to 4, but it's still there. I'm fairly sure it's not a performance issue, but, rather, a movement method fault.
A couple of suggestions:
Increase the frame rate
Use a tween library (e.g. GTween) with some easing effect.
Basically, if you want the object to jump 10px to the right, don't just move it right away, let it animate to its new position with some easing effect. Additionally, if the object is still moving and the key is pressed again, you probably want to accelerate the movement a bit (but only up to a point!).
I think you're asking how to make it more smooth. Well:
If you change the movement 2px per frame, then you'll have a much smoother experience. However, the movement will see very slow. To combat this, you just increase the frame rate of your swf. I believe the maximum is 120 frames, but that should be more than enough.
I love Tweenlite, it's great for pre-defined effects. It isn't for the core of your game though so I'd use Tweenlite for UI effects but barely for ingame movements responding to user controls.
I think around 24-30 fps for games is great, that's how I set all my games. I think abit you're picky, but perhaps what you're missing is a bit of edge: a smooth start and end for the movement. In most platformers I have a similar mechanic:
You want the start of the movement to start slow, reach the normal (max) speed you define and when the player lets go of a button, it slows down back to 0. This means you need to check the speed on enter frame regardless of the button triggers (they increment the speed but aren't the only condition to change speed and move the object)
enterframe loop:
//check for each direction:
if up, y_speed++
else if down, y_speed--
else if right, x_speed++
else if left, x_speed--
else // perform a decrease:
y_speed *= .8
x_speed *= .8
// make sure we aren't past the max speed
if x_speed>max_x_speed
x_speed = max_x_speed
etc. else other direction and y_speed
// now apply the movement
object.x += x_speed
object.y += y_speed
// remove the enterframe for better performance
if math.abs(x_speed)<.1 && math.abs(y_speed)<.1
// remove enterframe for movement here, add it again next time we know we have movement (button downs related to the movement, etc.)
I would implement this in your code but your code is too crowded. Anyway otherwise, most games with these simple controls are working just like your application does.