Scrolling does not accept decimals as scroll value

Discussion in 'Learning Ruby and RGSSx' started by Milena, Jul 30, 2016.

  1. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    Has anyone noticed why rpg maker vx ace does not accept decimal values for slower scrolling?


    For example:

    Code:
    class Scene_Title < Scene_Base
      #--------------------------------------------------------------------------
      # * Create Background
      #--------------------------------------------------------------------------
      def create_background
        @sprite1 = Plane.new
        @sprite1.bitmap = Cache.title1($data_system.title1_name)
        @sprite2 = Sprite.new
        @sprite2.bitmap = Cache.title2($data_system.title2_name)
      end
      
      def update
        super
        @sprite1.ox += 0.90
      end
      
    end
    
    If you do that, the background won't scroll at all. I want to scroll the title slower but why does it not? Any workaround on this?
     
    #1
  2. InspiredByBitcoin

    InspiredByBitcoin Villager Member

    Messages:
    18
    Likes Received:
    2
    Location:
    England
    First Language:
    English
    Greetings Milena,

    Hopefully this helps a little bit.

    Although I don't use decimals for "scrolling" specifically, I do use decimals in my project.

    [​IMG] 


    I find it easier to make a variable and set it then divide it to do fractions, below 1.00. RPGMaker by default truncates automatically using common methods, But you can get around it I think by doing something like this:
     

    class Scene_Title < Scene_Base
    #--------------------------------------------------------------------------
    # * Create Background
    #--------------------------------------------------------------------------
    $gamevariables[2] = 9.00
    $gamevariables[2] /= 10
    def create_background
    @sprite1 = Plane.new
    @sprite1.bitmap = Cache.title1($data_system.title1_name)
    @sprite2 = Sprite.new
    @sprite2.bitmap = Cache.title2($data_system.title2_name)
    end

    def update
    super
    @sprite1.ox += $game_variables[2]
    end

    end


    I don't know how to declare the variables as something else, like script-like but hopefully you can adapt it. It works on my project in an event, script box.

    Good luck to you, nonetheless.

    IBB
     
    Last edited by a moderator: Jul 30, 2016
    #2
  3. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    I tried this and the background does not scroll. I noticed that when the value is lower than 1, it won't work. (Except negative values)
     
    #3
  4. Wavelength

    Wavelength Pre-Merge Boot Moderator

    Messages:
    4,217
    Likes Received:
    3,542
    Location:
    Florida, USA
    First Language:
    English
    Primarily Uses:
    RMVXA


    This almost certainly wouldn't work because the precision of the divisor is zero decimal places - meaning Variable #2 would evaluate to 0.


    Dividing by 10.00 instead of 10 should correctly evaluate to 0.90, but my instinct is that the problem with Milena's attempt is that she is trying to move something by nine-tenths of a pixel, which makes no sense to a program that is evaluating a pixel as the smallest unit possible.  To make an analogy to a natural concept - it would be like walking into a classroom and seeing 25.9 kids sitting at their desks.  Hard to picture, ain't it?


    The way I would probably try to get around this, since the "update" method should run every frame, is to have a variable (possibly declared on scene startup - @number_of_frames = 0 or something like that) that tracks the frame count.  Every time the update runs, the frame count increases by 1.  Since we want the object to move one pixel in nine out of ten frames, we might rewrite the update method as:


    def update


    super


    @number_of_frames += 1


    if @number_of_frames % 10 > 0


    @sprite1.ox += 1


    end


    end


    If we wanted it to run every two out of three frames, instead of every nine out of ten:


    def update


    super


    @number_of_frames += 1


    if @number_of_frames % 3 > 0


    @sprite1.ox += 1


    end


    end


    If we wanted it to run every one out of three:


    def update


    super


    @number_of_frames += 1


    if @number_of_frames % 3 > 1


    @sprite1.ox += 1


    end


    end
     
    Last edited by a moderator: Jul 31, 2016
    #4
    InspiredByBitcoin likes this.
  5. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    I created a variable called @numberofframes in the start of scene title, then added a value of 1 every update then added the conditional branch. It works fine, but it works fast and normal as it should. Can this be more slower?
     
    #5
  6. Wavelength

    Wavelength Pre-Merge Boot Moderator

    Messages:
    4,217
    Likes Received:
    3,542
    Location:
    Florida, USA
    First Language:
    English
    Primarily Uses:
    RMVXA


    Your comment is a little ambiguous - do you mean to say that it's moving just as fast as if we had never made any changes to the script?  Or is it moving a little slower, but you want it even slower than that?  If it's the latter, you simply want to change the condition (I gave three examples in the post above; the final one should cause scrolling to be considerably slower); if it's the former, it's possible my approach wasn't sound or that one of your other scripts is overwriting what we're doing here.
     
    #6
  7. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    Yes, it just moves like +=1 or so. But this is weird, I thought ruby accepts decimal numbers, apparently it doesn't.
     
    #7
  8. InspiredByBitcoin

    InspiredByBitcoin Villager Member

    Messages:
    18
    Likes Received:
    2
    Location:
    England
    First Language:
    English

    Quite rightly pointed out and thanks for noticing. 

    It may or may not work by changing the division to $gamevariables[2] /= 10.00.

    That's my 2 cents.

    IBB
     
    #8
  9. Wavelength

    Wavelength Pre-Merge Boot Moderator

    Messages:
    4,217
    Likes Received:
    3,542
    Location:
    Florida, USA
    First Language:
    English
    Primarily Uses:
    RMVXA


    If it's still moving just as quickly with something like if @number_of_frames % 3 > 1 then something is going wrong.  I might try changing the line to if false and see what happens - most likely nothing will happen, that's good.  You could also try something direct like if rand(10) < 2 - this is more direct and it should move slowly and very erratically (which is why you wouldn't want this to be your condition in reality, but it's a good thing to test with).  If the random one works, but the modulo doesn't, it might mean that the @number_of_frames variable is being set over and over (rather than set once then incremented).


    Ruby/RGSS does accept decimal values - but it pays attention to the decimal precision of the values it manipulates (unlike JavaScript which I believe will generally treat numbers as floats with a large number of decimal places).  So 10/0.90 is zero, 10.00 / 9 is zero, but 10.00/9.00 is 0.90.  But again - you can't have 0.90 of a pixel; a pixel is the smallest unit your game will recognize.  Your monitor wouldn't be able to display it even if your game recognized it.  You can have 0.90 of most abstracts (such as the amount that a gauge is filled, or the rate to multiply physical damage by, or even an event's movement speed), but there are some things that you can't have it for, like the 0.90th element of an array (my_array = [3.50, "judd", false]; @my_value = my_array[0.9] would probably throw an error or at best would return the value 3.50) and you can't tell a sprite to move by 0.90 pixels.
     
    #9
  10. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    I finally found a way. For those who are interested, I created a @number_of_frames variable at the start of the scene title, make the value 0. Now on the update method, I added this:


    if @number_of_frames < 5
    @number_of_frames += 1
    else
    @number_of_frames = 0
    @sprite1.ox += 1
    end


    If the number_of_frames would be greater than 5 it just resets it and then adds a scroll to the x. Smaller value, the faster. Higher value, the slower.
     
    #10
  11. Noct

    Noct coffee.empty? ? refill_coffee : drink_coffee Veteran

    Messages:
    56
    Likes Received:
    275
    Location:
    USA
    First Language:
    [US] English
    Primarily Uses:
    RMVXA
    After reading everything else in this topic, here is my take on it. A pixel unit is the smallest movement and you can't cut that anymore then 1. HOWEVER, you can control how much it's updated. By default Update is called every frame but let's throw in a FRAME DELAY controller and then you'll be able to at least manipulate slower movement via frames. Just remember 60 = 1sec. I've written a new piece of code off of your original post that you can just plug and play. By default this will tell the engine every 1/3 of a second move by 1 pixel.


    #==============================================================================
    # ** Scene_Title
    #------------------------------------------------------------------------------
    #  This class performs the title screen processing.
    #==============================================================================


    class Scene_Title < Scene_Base
      #--------------------------------------------------------------------------
      # * CONSTANTS
      #--------------------------------------------------------------------------
      PIXEL_DELAY = 20
      #--------------------------------------------------------------------------
      # * Create Background
      #--------------------------------------------------------------------------
      def create_background
        @sprite1 = Plane.new
        @sprite1.bitmap = Cache.title1($data_system.title1_name)
        @sprite2 = Sprite.new
        @sprite2.bitmap = Cache.title2($data_system.title2_name)
        @delay_timer = 0
      end
      #--------------------------------------------------------------------------
      # * Frame Update
      #--------------------------------------------------------------------------
      def update
        super
        @sprite1.ox += 1 if @delay_timer == 0
        @delay_timer = (@delay_timer + 1) % PIXEL_DELAY
      end
    end
     
    #11
    Milena likes this.

Share This Page