Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / Pseudo wait
- - By SPK Date 2013-05-23 19:20
Hello,

I'm showing an animation and want to wait until it's done.

I have battler objects and each of them releases an animation which I just call by iterating over them.
But the second battler shall only show his animation when the first one is done and the third when the second is done.

Okay, that's actually not that difficult. But somehow, my code seems to has a flaw.
My environment that draws the animation has a animation object, it's nil until I iterate over those battlers.

http://pastebin.kde.org/749792/

class Environment
  def initialize
    @animation = nil
    @battlers = [Battler.new("some"), Battler.new("ordinary"), Battler.new("objects")]
  end

  def update
    @battlers.each {|battler| battler.update}
  end

  def draw
    @battlers.each {|battler| battler.draw}

    if not @animation.nil?
      if not @animation.shown
  @animation.draw
      end
    end
  end

  def performAnimations
    @battlers.each do |battler|
      # some stuff
      @animation = Animation.new(battler.highOugiAnimation)
     
      # wait until animation finished
      waitAnimation
    end
  end

  def waitAnimation
    if not @animation.nil?
      while not @animation.shown
  update
  draw
      end
    end
  end
end

class Animation
  attr_reader :shown
  def initialize(animation)
    @animation = animation
    @shown = false
    @pseudoTimer = 0
    @pseudoNumber = 1500
  end

  def draw
    @animation.draw(24, 24, 24)
    @pseudoTimer += 1
   
    if @pseudoTimer > @pseudoNumber
      @shown = true
    end
  end

end


I expect the animation to be shown, during that period the draw and update works normally, but "feels" like a wait.
But what happens instead is that the animation is NOT drawn, everything freezes up during the waitAnimation call and
I have no clue WHY it happens.

Please, I need your advice...
Parent - By SPK Date 2013-05-24 22:29
YEEEEEEEEEES- after hours of trying it's finally working.

The solution looks more or less like this now:

def update
  # ...
  if @environment.allAnimationsDone
    # prevent animation from showing
  elsif @animation.nil?
    startAnimation(@environment.getNextAnimation)
  elsif !@environment.activeAnimation.nil?
    if @animation.shown
      if @environment.activeAnimation.state == :DONE
  startAnimation(@environment.getNextAnimation)
      else
  endAnimation(@environment.activeAnimation)
      end
    end
  end
  # ...
end


:)
Parent - By RavensKrag Date 2013-05-29 04:07
The reason your code freezes up is because there's nothing to break out of the while loop under #wait_animation.  Generally speaking, trying to wait like that isn't very useful in game programming because the entire program is already a giant loop, so you can't use general looping constructs to repeat.  That'll just cause your game to get stuck on one tick.
Parent - By RavensKrag Date 2013-05-29 04:09
As a separate issue, why are you iterating over all Battlers when you only want the first one to play it's animation? Why not just queue the battlers, and only process the first one?

Something like...

@battlers = [Battler.new("one"), Battler.new("two"), Battler.new("three")]
@battlers.first.animate
@battlers.shift if @battlers.first.animation_done? # remove the first element from the queue


This is a more simplistic pattern which should accomplish the same task.  It's much more readable, which will help as your codebase grows larger.
Up Topic Gosu / Gosu Exchange / Pseudo wait

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill