scroll screen when character crosses a threshold

Started by daniel, Tue 16/05/2017 10:27:17

Previous topic - Next topic

daniel

hey guys,

i have a scrolling background with a doorway and i want it to scroll over all the way only when the character walks into/through the doorway.
right now i'm using this:

Code: ags

function room_RepExec()
{
  //Viewport Scroll
  if (player.x > 300) {
    while (ViewportX < 250) {
    ViewportX = (ViewportX) +5;
    SetViewport(ViewportX, 0);
    Wait (1);
    }
  }
  else {
    while (ViewportX > 10) {
    ViewportX = (ViewportX) -5;
    SetViewport(ViewportX, 0);
    Wait (1);
    }
  }


this works totally fine actually but yesterday i discovered the magic that is the tween module and thought some easeInOut is exactly what that scrolling needs.
once i put in the tween though i get the "more than 64 tweens" error and the game crashes. which made me realize that this is probably a bad way to check if the scroll should be executed at all.

setting the check to a specific coordinate like
Code: ags
if (player.x == 300)
doesn't work since that only seems to click if the character stops at exactly 300 X. also if the player would leave the character standing on that coordinate a while the game would crash again i suppose.
is there a way to check if the character started at a certain point < 300 and then stopped at a point > 300 so that the code only gets executed once when needed?
or is there some other smart way of doing this?

thanks!

Snarky

#1
First, I would caution about those Wait(1) lines in your original code. What you're doing there is that every turn you're telling the game to block for one turn. And room_RepExec() doesn't run when the game is blocked, so that means you'll run room_repExec once, then the whole game will block one turn (without anything happening), then run room_repExec() once more, then block another turn, and so on. In other words, you're cutting the framerate in half whenever you're scrolling.

You don't need any Wait() lines at all: room_RepExec() will only run once per turn, and you don't have any loops that need to pause. By cutting the Wait() lines and reducing the movement per frame (to 2 or 3 pixels), you can get scrolling that is twice as smooth, and without affecting any other ongoing animations.

OK, so about your tweens overflow problem... are you still putting your code in room_RepExec()? I'm pretty sure the problem is that you're creating a new tween every loop. You need to change it so that it only creates a tween once for each scroll event. (Edit: On re-reading your post, I see that you realize this on your own.) The usual way to do this is with a "flag" (a variable you can check the value of to keep track of the status of the program). For example, you might have an "isScrolling" flag, and only if it's set to false do you create a new tween.

daniel

#2
thanks for your help again snarky:)

in the end i just used the viewportX position as the flag:

Code: ags
if ((player.x>300)&&(ViewportX==10)){
      TweenViewportX(2.0, 210, eEaseInOutSineTween, eNoBlockTween);
      ViewportX=210;
  }
  if ((player.x<300)&&(ViewportX==210)){
      TweenViewportX(2.0, 10, eEaseInOutSineTween, eNoBlockTween);
      ViewportX=10;
  }


took me a while to figure out that tweening the viewport to a certain X position doesn't seem to actually "set" the viewport to that position which is why i still kept getting overflows all the time (and when using block the tween would keep blocking forever).

Khris

Quote from: Snarky on Tue 16/05/2017 12:13:28First, I would caution about those Wait(1) lines in your original code. What you're doing there is that every turn you're telling the game to block for one turn. And room_RepExec() doesn't run when the game is blocked, so that means you'll run room_repExec once, then the whole game will block one turn (without anything happening), then run room_repExec() once more, then block another turn, and so on. In other words, you're cutting the framerate in half whenever you're scrolling.
The Wait(1)s were inside while loops, not just if blocks. That's fine in room_RepExec, as long as you don't mind the game being blocked until the loop finishes.

daniel:
ViewportX is a custom variable created by you; it isn't updated by AGS.

The code you have is fine, but I recommend rewriting it a bit:
Code: ags
bool playerWasLeft = true;

function room_RepExec() {
  bool playerIsLeft = player.x < 300;
  if (playerIsLeft && !playerWasLeft) TweenViewportX(2.0, 10, eEaseInOutSineTween, eNoBlockTween);
  else if (!playerIsLeft && playerWasLeft) TweenViewportX(2.0, 210, eEaseInOutSineTween, eNoBlockTween);
  playerWasLeft = playerIsLeft;
}

Now every hardcoded coordinate only occurs once, and it's a bit more readable.

daniel

hehe...thx khris, you're right of course. it all starts making sense now:)

SMF spam blocked by CleanTalk