Panorama scrolling show/hide border arrows

  • #1, by Simon_ASAMonday, 27. July 2015, 12:15 9 years ago
    Hello!

    In the game, I have several panoramic views where the cursor can scroll left/right.

    I have created an inteface with left and right arrows to show the player that it is possible to scroll in these scenes.

    I would like to hide the left arrow when the left border is reached. Then, when the player scrolls to the right, it should show the left arrow again if it was hidden already (and same on the right).

    The left (and right) arrow has a condition true/false to display it. The arrows are in an interface, because they should not move on the screen. In the scene of the panorama, I have created a script that looks for the cursor position (see below). The scene is 4000 pixels large, so at 0 px the left arrow should be hidden and at 4000 px the right arrow should be hidden.
    The game resolution is 1920 px large, so when the x cursor position is over 1920 px, it should show the left arrow again (in case it was hidden after reaching the very left border).

    -- left part
    
    -- acquire left cursor position
    local posleft = getCursorPos()
    
    -- hide left cursor if left screen border reached
    if posleft.x < 5
    then
    local cond = getObject("Conditions[Show_Left_Arrow?]")
     cond:setValue(VConditionValue, false) 
    end
    
    -- show left arrow if cursor scrolls to the right
    if posleft.x > 1920
    then 
    local cond = getObject("Conditions[Show_Left_Arrow?]")
     cond:setValue(VConditionValue, true) 
    end
    
    -- right part
    
    -- acquire right cursor position
    local posright = getCursorPos()
    
    -- hide right cursor if right screen border reached
    if posright.x > 3995
    then
    local cond = getObject("Conditions[Show_Right_Arrow?]")
     cond:setValue(VConditionValue, false) 
    end
    
    -- show right arrow if cursor scrolls to the left
    if posright.x < 2080
    then 
    local cond = getObject("Conditions[Show_Right_Arrow?]")
     cond:setValue(VConditionValue, true) 
    end
    
    


    However this code doesn't work, the arrows in the interface never hide.
    I forgot to say that this script is called at the beginning of the scene, then there is a Jump to #1 in order to make it loop. And at the end of the scene, the loop is stopped.

    Help! \o/

    Great Poster

    321 Posts


  • #2, by sebastianMonday, 27. July 2015, 14:55 9 years ago
    no need to use lua here. just define the two arrow "buttons" and define some (cursor enter / cursor leave) actions on these to show/ hide them... done

    Thread Captain

    2346 Posts

  • #3, by Simon_ASAMonday, 27. July 2015, 15:27 9 years ago
    Thanks a lot Sebastian. Unfortunately this is the first thing I tried, and it doesn't seem to work in this specific case...

    The 2 arrows cannot be clicked (the player won't scroll the view with Left click actions on the side arrows). I forgot to say that I use the option to "scroll scene if the cursor is at the edge of screen" (in the scene properties).

    So if I want to use the cursor enter/leave actions, I have to set them in the panorama itself (not in the interface) which means I can only put 2 hotspots to hide the arrows at the extreme borders of the panorama (at 0 px and at 4000 px) = they're very far from each other. I can use these hotspots separately to hide the left or right arrows individually (for ex. I can hide the left arrow when the cursor reaches the left border), but then I can't show the arrow again unless I reach the opposite border of the panorama, which is very far.

    If I show the arrow immediately after quitting the left hotspot (by using the cursor leave action), then the arrow will display immediately (= before any scrolling happened), which is not logical since we're still in the very left part of the panorama and the view has not changed (= we still can't move further on the left). The arrow should only display when the cursor has reached the opposite border of the screen (not the border of the panorama).

    Finally I had tried to put a hotspot in the middle of the panorama in order to activate the arrows that were hidden. It was working well, except if the cursor was going through another hotspot already used for another action. Then the arrows were not showing of course, so it's still a problem.

    Well there are several subtleties in creating this, and after several tries I think it's easier with lua. I usually try not to use it because I'm not very good at scripting, but here I don't know what to do...

    Great Poster

    321 Posts

  • #4, by afrlmeMonday, 27. July 2015, 15:46 9 years ago
    No, by default he has the arrows & various other animations shown as hotspots to show what the player can interact with & where the player can navigate to.

    How is this script called? I don't see a loop or anything.

    Quick note: the getCursorPos() function doesn't actually return the exact coordinate of the cursor on the screen. It returns the current coordinate inside of the current viewport (your games default resolution) so it will always return 0 to default resolution width / height. You have to do...
    if ( game.ScrollPosition.x + getCursorPos().x ) < 5 then 
    

    However I think it would be more beneficial to use the scrollposition field instead.
    if game.ScrollPosition.x == 0 then
     -- hide left arrow
    elseif game.ScrollPosition.x >= (scene_width - game.ScrollPosition.x) then
     -- hide right arrow
    else
     -- show left arrow; show right arrow
    end
    

    Please note that the example above is not a working example. Since 4.1, we can now return the width & height of image sprites which means we can return the width & height of the scene background sprite too, so you could easily make a more global function for showing & hiding the arrows for all 4 directions if need be.

    Imperator

    7278 Posts

  • #5, by Simon_ASAMonday, 27. July 2015, 16:10 9 years ago
    Oki doki, I will try as you say and will let you know if it works. Thanks AFRLme!

    Great Poster

    321 Posts

  • #6, by Simon_ASAMonday, 27. July 2015, 19:06 9 years ago
    I've tried several things but it doesn't work, nothing happens (the arrows never disapear).

    You were previously asking about the loop. I use an action Jump to part #1 (the script is in an action Execute script at the beginning of the scene).
    Do you think it might be a problem?

    Great Poster

    321 Posts

  • #7, by afrlmeMonday, 27. July 2015, 19:37 9 years ago
    Why not just use a Lua loop? Then you don't have to mess around setting up a loop with the jump to x action part each time you change to a new scene. Of course you could also do that, by listening for scene change & then having it call the called by other action containing the jump to x action loop if you don't want to use a pure Lua loop.

    The only issue with the action loop method is that you will need to add a pause action part before looping back to the beginning. It should be something like 50 to 100ms to prevent it from looping too fast as editor created loops can return errors if you have it looping too fast.
    scnSize = nil -- empty variable that we will be storing the scene size into...
    
    -- * call this function once at the beginning of each interactive scene * --
    function getSceneSize()
     scnSize = game.CurrentScene.SceneSprite.SpriteSprite:getSize()
    end
    
    function navArrows()
     if not game.CurrentScene:getBool(VSceneIsMenu) and scnSize ~= nil then
      if game.ScrollPosition.x == 0 then Conditions["Show_Left_Arrow"].ConditionValue = false else Conditions["Show_Left_Arrow"].ConditionValue = true end
      if game.ScrollPosition.x >= (scnSize.x - game.WindowResolution.x) then Conditions["Show_Right_Arrow"].ConditionValue = false else Conditions["Show_Right_Arrow"].ConditionValue = true end
     end
    end
    
    registerEventHandler("mainLoop", "navArrows") -- create the loop
    

    Add the script above to the script section. Leave as definition script. Please remove the ? marks from the condition names as special characters are not good when it comes to Lua script.

    P.S: have you made sure that the conditions determine if the buttons should be hidden?

    Imperator

    7278 Posts

  • #8, by Simon_ASAMonday, 27. July 2015, 22:56 9 years ago
    It still doesn't work, sorry roll roll
    Nothing happens when I reach the screen borders, the arrows never hide whatever I do (except if I toggle manually the conditions). I have checked everything and there are errors in the log with string problems. I'll try again tomorrow...

    For the moment I'd like to try the Shaders (CMS) things -- just for the fun. I find it interesting to have dynamic noise (it works very well!), and now I'd like to see if it is possible to simulate the small rotations/pans of a camera hold by hands (with the shaderViewport function maybe?).

    Great Poster

    321 Posts

  • #9, by afrlmeMonday, 27. July 2015, 23:21 9 years ago
    Could you please paste the log errors? I wrote the script off the top of my head, so no idea if it's correct or not. The log errors may help me understand why it's not working.

    Imperator

    7278 Posts

  • #10, by Simon_ASAMonday, 27. July 2015, 23:51 9 years ago
    I don't think the errors are useful in fact.

    23:48:57: Error: Failed to run string in Lua: [string "0001 start: PANO - Show/hide arrows: Execute ..."]:9: unexpected symbol near '<'
    23:48:57: Error: String content: -- hide left cursor if left screen border reached

    Great Poster

    321 Posts

  • #11, by afrlmeTuesday, 28. July 2015, 00:14 9 years ago
    That's not my script it's listing an error from.

    revised script...
    scnSize = nil -- empty variable that we will be storing the scene size into...
    local scn = nil
    
    -- * call this function once at the beginning of each interactive scene * --
    function getSceneSize()
     scnSize = game.CurrentScene.SceneSprite:getSize()
    end
    
    function navArrows()
     if not game.CurrentScene:getBool(VSceneIsMenu) and scnSize ~= nil then
      if game.ScrollPosition.x == 0 then Conditions["Show_Left_Arrow"].ConditionValue = false else Conditions["Show_Left_Arrow"].ConditionValue = true end
      if game.ScrollPosition.x >= (scnSize.x - game.WindowResolution.x) then Conditions["Show_Right_Arrow"].ConditionValue = false else Conditions["Show_Right_Arrow"].ConditionValue = true end
     end
     -- + --
     if scn ~= game.CurrentScene:getName() and not game.CurrentScene:isEmpty() then 
      scn = game.CurrentScene:getName(); startAction("Actions[get_scene_size]")
     end
    end
    
    registerEventHandler("mainLoop", "navArrows") -- create the loop
    

    Please remove whatever other scripts & actions you created for sorting out the arrow hiding / showing.

    Also please remove the "?" symbols from the Show_Right_Arrow? & Show_Left_Arrow? condition names. Symbols can sometimes cause issues when it comes to using Lua script.

    It should work now, providing you do what I just said. - untested mind.

    * edit: updated the script slightly after I quickly tested it. Seems that when you call SceneSprite that you don't need to add .SpriteSprite after it before calling the getSize() function. I don't currently have any scenes greater than the default game resolution for testing, so you'll have to tell me if it's working correctly or not.

    Imperator

    7278 Posts