Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / zooming/unzooming background image
- - By OldBoy Date 2013-01-17 20:58
I want to load large picture (above 3000x3000 pixels, static, like a background), and I want to be able to zoom/unzoom a portion of it (with mousewheel and/or keyboard) and also to move it to see other parts of whole image. Sort of like an imageviewer (acdsee, irfanview) - open image, zoom, unzoom, scroll to the edges.... The (big) plan is to load a map image, "surf" through it and record every movement and zoom(vent) and then play it at custom speed

I tried to achieve this with gamemaker studio, but scrolling feels unnatural, and I think it has a bug in latest version.

I just wonder if it's possible to do this with gosu and which methods am I looking for ?
I'm fairly new to ruby/gosu, just wanted to ask before I start to dig deeper
Parent - - By Spooner Date 2013-01-17 23:53
You should be able to do everything you are asking for in Gosu. You can move and scale images each time you draw them, so that is easy enough (or you can translate or scale the whole window). Gosu will happily load large images of any size, though internally it will actually use several smaller textures, but that is transparent to us.

In very complex games, scrolling with Gosu can get a bit jerky because the Ruby garbage collector decides to hate you, but for your simple application I can't imagine that being noticeable at all.
Parent - By erikskoglund Date 2013-01-18 09:31
I haven't read up a lot on the GC in Ruby. But I have some experience with other frameworks and languages that use garbage collection. From what I have tried there are two ways to go with this:
1. Allocate everything up front, during load time. Use resource pooling instead of creating new objects all the time. The goal of this method is to not have the GC run at all.
2. Keep a simple heap, small amount on references to objects. The goal of this method is to make the GC take less time to run.
Parent - By jlnr (dev) Date 2013-01-18 09:58
This is absolutely possible in Gosu. My biggest worry is that zoomed-out images will look odd because Gosu does not use MIP-mapping, and rendering a huge OpenGL texture onto a very small plane might look terrible.

Ruby (and by extension, Gosu) is also a desert when it comes to GUI libraries. So if you want to add a secondary window, or a custom application menu, you can only simulate it inside Gosu's drawing area.

Oh and you cannot load images asynchronously, so the app might hang for a bit when loading a huge image. I guess it all depends on whether this is a user-facing app or a creation tool ...
Parent - - By Donna111 Date 2013-10-25 06:56
HI there
I also want to zoom my image.But i don't know how.Is there any image  program which supports to zoom image online?
I think that would be more convinient.Thanks for any suggestion.
Parent - By jlnr (dev) Date 2013-10-25 13:12
Are you looking for a free image editor to stretch images? If so, then I think Paint.net is the most popular free editor for Windows. But even good old MS Paint can do it :)
Parent - - By ml Date 2013-10-26 06:33
@Donna111, good luck finding what you're looking for.

@OldBoy, you could try something like:

def increase_image_size
  self.factor *= 1.05
end

def decrease_image_size
  self.factor *= 0.95
end


and call these methods when an arrow is pushed or the scrollwheel is moved.
Parent - - By jlnr (dev) Date 2013-10-26 20:10
Note, this assumes one is using chingu. :)
Parent - By ml Date 2013-10-27 08:20
Oops! I unthinkingly assumed it was the same in Chingu as in Gosu... and we all know what assuming does....
Parent - - By OldBoy Date 2014-02-28 13:17
wow, it's already been a year since I asked this ... I must be the slowest programmer ever :)
Anyway, here's what I've came up with:
----------------------------------------------------------------------------------------------------------------
require 'rubygems'
require 'gosu'

class GameWindow < Gosu::Window
  POMAK = 5
 
  def initialize
    super 1366, 768, true, update_interval = 20
   
    @x = @y = 0
    @f_x = @f_y = 1.0
    @slika = Gosu::Image.new(self, '18.jpg', false)
    @font = Gosu::Font.new(self, Gosu::default_font_name, 20)
  end
 
  def update
    if button_down?(Gosu::KbLeft)
      @x += POMAK
    end
    if button_down?(Gosu::KbRight)
      @x -= POMAK
    end
    if button_down?(Gosu::KbUp)
      @y += POMAK
      #@player.accelerate
    end
    if button_down?(Gosu::KbDown)
      @y -= POMAK
    end
    if button_down?(Gosu::KbNumpadAdd)
      @f_x += 0.01
      @f_y += 0.01
      @x -= 15
      @y -= 15
    end
    if button_down?(Gosu::KbNumpadSubtract)
      @f_x -= 0.01
      @f_y -= 0.01
      @x += 15
      @y += 15
    end 
    if button_down?(Gosu::MsWheelUp)
      @f_x += 0.01
      @f_y += 0.01
      @x -= 15
      @y -= 15
    end
    if button_down?(Gosu::MsWheelDown)
      @f_x -= 0.01
      @f_y -= 0.01
      @x += 15
      @y += 15
    end 
  end
 
  def draw
    @slika.draw(@x, @y, 1, @f_x, @f_y)
    @font.draw("Mish_x: #{mouse_x}; Mish_y: #{mouse_y}", 10, 10, 3, 1.0, 1.0, 0xffffff00)
  end

  def button_down(id)
    case id
    when Gosu::KbEscape
      close
    end
    # when MsLeft
    # not working ! 
    # end
  end
 
  def needs_cursor?
    true
  end
end

window = GameWindow.new
window.show
------------------------------------------------------------------------------------------------------------


It's a good start, but I have few problems:

1- How to implement mouse wheel to work (wheel up should do same as KbNumpadAdd,  wheeldown = KbNumpadSubtract)
2- How to implement image movement when mouse left button is pressed and hold (like google maps) ... drag and drop, is that how it's called ?
3- How to ZOOM at the CENTER of the screen ?? You can notice that I am manually adding 15 pixels ( @x += 15 and @y += 15 ) when I'm changing factor_x/factor_y (@f_x -= 0.01 and @f_y -= 0.01) ... but it still isn't right ... I'm affraid I'll need some advanced math for this ?
4- How to set font to Courier New ?

Any help appreciated !
Parent - - By jlnr (dev) Date 2014-02-28 13:25
I only have time to answer 1 - MsWheelUp and MsWheelDown are sent to button_down(id) when the wheel is moved.
Parent - By OldBoy Date 2014-02-28 17:26
yep, that did the trick ... thank you very much ... now I have only one (two) problem(s) left:

a- How to zoom image at the center of the screen
or
b- How to zoom/unzoom image at the point of mouse cursor (google maps way)

Take as much time as you need ... I am very slow and inconsistent with finishing my code anyway
Parent - - By lol_o2 Date 2014-02-28 14:18
2.
You need three conditions: when mouse is pressed, being hold and released. You'd need some variable that is set true when you just press the button (in button_down(id)) or use simpler solution, store initial position of mouse and image and then translate while button is being pressed

if button_down?(Gosu::KbLeft) #button is being hold
  if !@drag #store the current position of image and mouse
    @drag = [mouse_x, mouse_y]
    @origin = [@x, @y]
  else
    @x  = @origin[0] - (mouse_x - @drag[0]) #translate according to mouse movement
    @y  = @origin[1] - (mouse_y - @drag[1])
  end
else #button is released
  @drag = @origin = nil #clear variables, so you can re-use them
end

Ask if you don't understand something.

4.
Instead of Gosu::default_font_name use just "Courier New" (string). Gosu will look for the font in your system directory or given path.
Parent - By OldBoy Date 2014-02-28 17:13
if button_down?(Gosu::MsLeft) #button is being hold
      if !@drag   #this executes only once,when we press mouse button @drag == nil means !@drag is true
        @drag = [mouse_x, mouse_y] #store the current position of mouse
        @origin = [@x, @y]         #store the current position of image
      else   #after initial mouse click, @drag != nil, meaning  !@drag == false, meaning this block executes while we hold mouse button pressed
        @x  = @origin[0] + (mouse_x - @drag[0]) #translate according to mouse movement
        @y  = @origin[1] + (mouse_y - @drag[1])
      end
    else #button is released
      @drag = @origin = nil #clear variables, so you can re-use them
    end

---------------------------------------------------------------------------------------------------

This is beautiful, works perfectly ... it took me some time to figure out whats going on though, so I added some comments if there are other newbies like me reading this.
You also solved my #4 question

Thank you very much !
Up Topic Gosu / Gosu Exchange / zooming/unzooming background image

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill