Libgdx - Animation only plays for 1 second inside if statement - libgdx

Basically, when the ball hits the top wall. I want it to make some lightning strike animation, but the animation only last around 1 second.
if(ball.getY() + ball.getHeight() > topWall.getY()) {
game.getBatch().draw(animation.getKeyFrame(timepassed, false), ball.getX(), ball.getY() + ball.getHeight(), 0, 0, leftWall.getWidth(), leftWall.getHeight() * -1, 1, 1, 0f);
LightingStrikeRectArrayList.add(new Rectangle(ball.getX(), Apm.HEIGHT - ball.getY() + ball.getHeight() / 2, topWall.getWidth(), topWall.getHeight()));
for (Rectangle rect : LightingStrikeRectArrayList) {
if (rect.overlaps(playerHitbox)) {
this.game.setScreen(new GameScreen(this.game));
}
}
if(!(LightingStrikeRectArrayList.isEmpty() && animation.isAnimationFinished(timepassed))) {
LightingStrikeRectArrayList.remove(0);
}
ball.reverseDirectionY();
}

The problem seems to be that you only draw the animation as long as the ball is on the top. When the ball moves back down the animation stops.
If you set a boolean variable that indicates, that the ball was touching the top wall, and draw the animation as long as this flag is set, it will continue to be drawn event if the ball moves back down.
A solution could look similar to this:
// create a global variable somewhere in the class, to store the flag
private boolean ballTouchedTopWall = false;
public void processGame() {
//...
if(ball.getY() + ball.getHeight() > topWall.getY()) {
// set the flag instead of drawing the animation
ballTouchedTopWall = true;
LightingStrikeRectArrayList.add(new Rectangle(ball.getX(), Apm.HEIGHT - ball.getY() + ball.getHeight() / 2, topWall.getWidth(), topWall.getHeight()));
for (Rectangle rect : LightingStrikeRectArrayList) {
if (rect.overlaps(playerHitbox)) {
this.game.setScreen(new GameScreen(this.game));
}
}
if(!(LightingStrikeRectArrayList.isEmpty() && animation.isAnimationFinished(timepassed))) {
LightingStrikeRectArrayList.remove(0);
}
ball.reverseDirectionY();
}
if (ballTouchedTopWall) {
game.getBatch().draw(animation.getKeyFrame(timepassed, false), ball.getX(), ball.getY() + ball.getHeight(), 0, 0, leftWall.getWidth(), leftWall.getHeight() * -1, 1, 1, 0f);
// reset the flag when the animation ends
if (animation.isAnimationFinished(timepassed)) {
ballTouchedTopWall = false;
}
}
}

Related

How to change frames when i move my mouse left or right (actionscript)

I am using a fish as a mouse cursor but when i move it around my stage it only faces one direction. what I want it to do is change direction when i move it left or right.
This should allow you to control the timeline of the fish movieclip:
It works by listening for a change in the position of the mouse, which after detecting the speed in which it does this, moves the timeline of the desired movieclip forwards or backwards depending on the new direction of the mouse.
Taken from the following thread: https://forums.adobe.com/thread/1450102?tstart=0
var mc:MovieClip = MovieClip(this); // <- The timeline you want to control with mouse position
var maxScrollSpeed:int=100; // max fps for mc above
var m:Number;
var b:Number;
var prevFPS:int;
paramF(0,-maxScrollSpeed,stage.stageWidth,maxScrollSpeed);
this.addEventListener(MouseEvent.MOUSE_MOVE,scrollF);
function scrollF(e:Event):void
{
var fps:int = Math.round(m*mouseX+b);
if(prevFPS&&prevFPS!=fps)
{
if(fps!=0)
{
if(fps>0)
{
playF(mc,mc.currentFrame,mc.totalFrames,fps);
}
else
{
playF(mc,mc.currentFrame,1,-fps);
}
}
else
{
stopF(mc);
}
}
prevFPS=fps;
}
function playF(mc:MovieClip, m:int, n:int, fps:int):void
{
var playFFF2:Function = function(mc:MovieClip):void
{
if (mc.m<mc.n)
{
mc.nextFrame();
}
else
{
mc.prevFrame();
}
if (mc.currentFrame == mc.n)
{
clearInterval(mc.int);
}
//updateAfterEvent();
};
mc.m = m;
mc.n = n;
mc.fps = fps;
mc.gotoAndStop(mc.m);
clearInterval(mc.int);
mc.int = setInterval(playFFF2, 1000/mc.fps, mc);
}
function stopF(mc:MovieClip):void
{
clearInterval(mc.int);
}
function paramF(x1:Number,y1:Number,x2:Number,y2:Number):void
{
m=(y1-y2)/(x1-x2);
b=y1-m*x1;
}
Store the mouseX position in a variable. When the mouse moves, compare the new mouseX position with your stored variable (you can do this with the ENTER_FRAME or MOUSE_MOVE events). If the new position is greater than the previous position, set the scaleX to 1, if the new position is less than the previous position set the scaleX to -1 (or vice versa).
Update the stored value and repeat.

libGDX bullet position logic

My game has a update method which handles the fire ability of my chracter.
my problem is the logic of my game, the bullet should fire from the position of my chracter, upon game start(not moving the character) fire bullet come from the position of the character, but when i move my character the start position of bullet is not same with the position of character.
The direction of the bullet depends on the direction of the player.
private void update() {
Vector2 direction = new Vector2(0, 0);
if (Gdx.input.isKeyPressed(Keys.D)) {
direction.x = 1f ;
}
if (Gdx.input.isKeyPressed(Keys.A)) {
direction.x = -1f ;
}
if (Gdx.input.isKeyPressed(Keys.W)) {
direction.y = 1f ;
}
if (Gdx.input.isKeyPressed(Keys.S)) {
direction.y = -1f;
}
if (direction.x != 0 || direction.y != 0) {
playerDirection.set(direction);
System.out.println("player x: " +playerDirection.x + "\t" +"player y:"+playerDirection.y);
}
if (Gdx.input.isKeyPressed(Keys.F)) {
bulletPos = new Vector2(startPos);
bulletDirection.set(playerDirection);
}
if (bulletPos != null) {
bulletPos.x += direction.x;
bulletPos.y +=direction.y;
if (bulletPos.x < 0 || bulletPos.x > mapPixelWidth
|| bulletPos.y < 0 || bulletPos.y > mapPixelHeight) {
bulletPos = null;
}
}
}
can anyone knows the logic error, or anyone there can provide simple logic of shooting that fire on a direction?
From what i see, you're always firing button from players start position (startPos), and then, when the bullet is moving, you update its position according to player direction (direction.x, .y)? But when player changes direction, bullet is starting to move other way as well. Thats wrong.
After its created, bullet should be always moved independent from your player. So when you create it, it has to have own start position (taken from current player position), and own direction (based on current player position). Your player movement cannot change bullet position anymore.
Something like:
if (Gdx.input.isKeyPressed(Keys.F)) {
bulletPos.set(currentPlayerPosition);
bulletDirection.set(currentPlayerDirection);
}
//and then in update()
bulletPos.x+=bulletDirection.x;
bulletPos.y+=bulletDirection.y;
//until it goes out of screen, or passes given distance,
//or new bullet is created, or whatever condition you like

flash as3 hitdetection function triggering other function

I am trying to code a script in which a movieclip drops a rope and catches fishes that follows it up if it touches it. here is the issue , i am using hitTestObject to detect collision . Ofcourse the problem is that i trigger the function when it touches but as soon as it doesnt touch the function for moving the movie starts so basically the fish goes up for few seconds and then starts moving straight again .
To try and fix that i tried to make a boolean variable which changes to true or false according to hit and accordingly makes the movieclip moves but also doesnt work because as soon as one mc is not touching the other it changes from true to false or 1 to 0 ..tried both (as in with boolean variable and Number variable) . Any help or putting me on the right direction would be highly appreciated . Thank you so much
// fish capture code
this.addEventListener(Event.ENTER_FRAME,handleCollision);
function handleCollision(e:Event):void
{
if (ropeHit.hitTestObject(fishy_1_a))
{
stopFish1();
trace(movefish1);
}
else
{
moveFish1();
}
}
//code enemy fishy
//fish 1 A
function moveFish1()
{
if (fishy_1_a.x < 800)
{
fishy_1_a.x += xSpeed;
}
else if (fishy_1_a.x >= 800)
{
fishy_1_a.x = -100;
}
}
function stopFish1()
{
fishy_1_a.y -= xSpeed;
}
Define some flag, that you can test:
function handleCollision(e:Event):void {
//Check if fishy is caught
if (!fishy_1_a.catched && ropeHit.hitTestObject(fishy_1_a)) {
//Change flag
fishy_1_a.catched = true;
trace("Gotcha!");
}
if (fishy_1_a.catched) {
stopFish1();
}else {
moveFish1();
}
}

how to stop a movieclip on the Y-axis with buttons?

I have two buttons that moves a movieclip up/down the Y-axis. How do I get the movieclip to stop at a certain height, and still be able to move it in the opposite direction?
I need this to work like this:
When you press the down-button, the movieclip goes downwards, but not past Y=500.
When you press the up-button, the movieclip goes upwards, but not past Y= 300.
I get the movieclip to stop at the correct point (500), but when it reaches this point it's stuck..
so it won't go upwards again if I press the up-button.
can someone help me please?:)
here's my code so far:
1) decrease = the down-button
2) increase = up-button
3) stempel = the movieclip I want to stop on the Y-axis
var moveStempel = 0;
decrease.addEventListener(MouseEvent.MOUSE_DOWN, decreasePressed);
decrease.addEventListener(MouseEvent.MOUSE_UP, removeEnterFrame);
increase.addEventListener(MouseEvent.MOUSE_DOWN, increasePressed);
increase.addEventListener(MouseEvent.MOUSE_UP, removeEnterFrame);
function decreasePressed(e:MouseEvent):void
{
moveStempel = 2;
addEnterFrame();
}
function increasePressed(e:MouseEvent):void
{
moveStempel = -2;
addEnterFrame();
}
// ADD ENTER FRAME
function addEnterFrame():void
{
this.addEventListener(Event.ENTER_FRAME, update);
}
function removeEnterFrame(e:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME, update);
}
function update(e:Event):void
{
if (stempel.y < 500)
{
stempel.y += moveStempel;
trace("inside");
}
else if (stempel.y > 500)
{
stempel.stop();
trace("outside");
}
In your code right now, once stempel has a y value greater than 500, it will never be able to move again.
There are two conditions when stempel can move: if it's moving down, it can't be at the bottom of the allowed area, and if it's moving up, it can't be at the top of the allowed area.
if ((stempel.y < 500 && moveStempel == 2) || (stempel.y > 300 && moveStempel == -2))
{
stempel.y += moveStempel;
trace("inside");
}
else
{
stempel.stop();
trace("outside");
}

Control volume of player - crackling noise

I want that my spaceship gets louder when my mouse moves away from it (and vice versa). Problem is that my function produces an annoying crackling sound I can't get rid of when I move my mouse away from it (and vice versa). The sound file is ok so far. What can I try next?
shipSpeed = (abs(player.x - playerPrevPt.x) + abs(player.y - playerPrevPt.y)) / 2;//the ship's speed gets calculated
//this is used to determine whether the ship's volume of its sound shall be increased or decreased
if (shipSpeedPrev < shipSpeed) {
sndManager.increaseSound(Main.SOUND_BACKGROUND, false, .01);
} else if (shipSpeedPrev > shipSpeed) {
sndManager.decreaseSound(Main.SOUND_BACKGROUND, false, .01);
} else if (shipSpeedPrev == shipSpeed) {
} else {
}
shipSpeedPrev = (abs(player.x - playerPrevPt.x) + abs(player.y - playerPrevPt.y)) / 2;//this is another ship speed so I can compare them
//the decreaseSound-function is almost the same
public function increaseSound(soundName:String, isSoundTrack:Boolean = false, steps:Number = .1, targetVol:Number = 1):void {
if (isSoundTrack) {
if (soundTrackChannel != null) {
musicVolumeAdj.volume += steps;
if (musicVolumeAdj.volume >= targetVol) {
musicVolumeAdj.volume = targetVol;
}
soundTrackChannel.soundTransform = musicVolumeAdj;
}
} else {
soundVolumeAdj = new SoundTransform(incrSndVal, 0);
incrSndVal += steps;
soundVolumeAdj.volume += incrSndVal;
if (soundVolumeAdj.volume >= 1) {
soundVolumeAdj.volume = 1;
}
soundChannels[soundName].soundTransform = soundVolumeAdj;
}
}
Most likely the audio ends up being clipped when you increase the volume. Try to find out at what volume the clipping occurs, and then change your function so that it doesn't got beyond that volume.
Perhaps you could also re-author the audio file and reduce the overall volume, so that you can increase it more from your game.