Search code examples
rubygame-physicslibgosu

Ruby Gosu how to start new time on click


Im trying to simply move an image on click from the one side of the screen to another. But I can't quite figure out how to work with time. Basically I need to start moving a ball after a Gosu::KbReturn.

Any help would be much appreaciated

require 'gosu'
  def media_path(file)
    File.join(File.dirname(File.dirname(
       __FILE__)), 'media', file)
  end
    class Game < Gosu::Window

  def initialize
    @width = 800
    @height = 600
    super @width,@height,false
    @background = Gosu::Image.new(
      self, media_path('background.png'), false)
    @ball = Gosu::Image.new(
      self, media_path('ball.png'), false)
    @time = Gosu.milliseconds/1000
    @x = 500
    @y = 500
    @buttons_down = 0
    @text = Gosu::Font.new(self, Gosu::default_font_name, 20)
  end

  def update
    @time = Gosu.milliseconds/1000
  end

  def draw
    @background.draw(0,0,0)
    @ball.draw(@x,@y,0)
    @text.draw(@time, 450, 10, 1, 1.5, 1.5, Gosu::Color::RED)
  end 
  def move
    if ((Gosu.milliseconds/1000) % 2) < 100 then @x+=5 end
  end

  def button_down(id)
    move if id == Gosu::KbReturn
    close if id ==Gosu::KbEscape
    @buttons_down += 1
  end
  def button_up(id)
    @buttons_down -= 1
  end
end

Game.new.show

Solution

  • First you have the keyboard event handler in a wrong place. The update method serves only as a callback in update_interval period and you should definitely place it in button_down instance method of Gosu::Window.

    Second, if you call move method to update game objects positions it is meaningless to do it in a loop. You should just update @x once per call.

    Third your use of @time instance variable in move method does not make any sense. If you need limit movement only after a some time has elapsed, you can just check timer exceeded specific increment, f.E. with integer modulo (with some tolerance): if (Gosu.milliseconds % @increment) < @epsilon then.

    Update: update @x for 10 secs after Enter key pressed

    class Game < Gosu::Window
      def initialize
        …
        @trigger = false    # if trigger for delayed action was activated
        @start_time = 0     # saved time when trigger was started
      end
    
      def update
        …
        if @trigger
          if Gosu.milliseconds - @start_time < 10_000
            @x += 1           # update x-position for 10 seconds
          else
            @trigger = false  # disable trigger after timeout elapsed
          end
        end
      end
    
      def button_down(key)
        case key
        when Gosu::KbReturn
          @start_time=Gosu.milliseconds   # store current elapsed time
          @trigger=true                   # enable trigger
        when Gosu::KbEscape
          …
        end
      end
    end