This post is about creating window sliding effect such as seen in my old program called GMConveter. Program itself was a bit of joke actually, since at the moment of it's publication the only actual difference between GM80 and GM81 formats was a version byte in file header, which GMConverter would change, making files compatible again. Not too bad of functional part for something that was downloaded over 4 thousand times over course of two years, right?
Apart from inner simplicity, it also had nice visuals, including a nice window sliding effect used on start and end of program. And that's what this article is about.
Basics
For start, we'll need a couple of variables to determine where the window will start moving from, where it will move to, and where exactly it is at the moment of time. For purpose of this example that code will look like this (goes into creation event):
slide_from = display_get_height() - 1 // slide in from bottom of screen slide_to = window_get_y() // sliding target position slide_now = 0 // position (0..1)
And a bit of code to actually move the window around (goes into step event):
slide_now = min(slide_now + 0.02, 1) window_set_position(window_get_x(), slide_from + slide_now * (slide_to - slide_from))
If you'll run code at this time, you'll see window sliding out of bottom of the screen like this:
That works. Not a particularly interesting effect yet, but causes window to gradually slide into the screen after game has started.
Making it "interesting"
As you've probably noticed, uniform movement does not look particularly interesting. This is because used "tweening" method is just linear interpolation. Which is not exciting by itself. However, that can be fixed, for example, by replacing it with trigonometry-related formula based in sine or cosine functions. Following image illustrates looks of that:
After this minor replacement, step event will look like this:
slide_now = min(slide_now + 0.02, 1) window_set_position(window_get_x(), slide_from + sin(slide_now * pi / 2) * (slide_to - slide_from))
And will behave like this:
Tweaks and extras
One thing that you may have noticed with earlier code, is that game appears at original position for a moment before snapping to bottom of screen and sliding from there. This can be fixed by copying window_set_position call to Create event too. Or moving that call into a user event, such as User Defined 0:
/// Updates window position window_set_position(window_get_x(), slide_from + (slide_to - slide_from) * sin(slide_now * pi / 2))
Other thing to be paid attention is that sliding in isn't generally enough. Application may not last forever, and thus could use a "slide-out" effect too. For that we'll need an extra parameter to indicate current sliding direction (speed), which'll also go into Create event:
slide_from = display_get_height() - 1 // slide in from bottom of screen slide_to = window_get_y() // sliding target position slide_now = 0 // position (0..1) slide_delta = 0.02 // sliding speed (_now change rate) event_user(0) // call first update
For sake of optimization and handling of new situation, Step event code also undergoes some changes:
if (slide_delta > 0) { // sliding in if (slide_now < 1) { slide_now = min(slide_now + slide_delta, 1) event_user(0) } } else { // sliding out slide_now += slide_delta if (slide_now <= 0) { // window disappears before closing if (window_get_visible()) window_set_visible(0) } else event_user(0) // this is where it actually closes: if (slide_now < -1) game_end() }
And, finally, slide-out situation has to be triggered from some place, such as press Escape keyboard event (note that you'll need to disable automatic game termination on this keypress in Global Game Settings):
/// start sliding out, if didn't already if (slide_delta > 0) { slide_to = window_get_y() // make sure coordinates didn't get broken slide_delta = -abs(slide_delta) // reverse sliding direction slide_now = 1 // again, making sure nothing gets broken }
And, after all these changes, we get perfectly fine sliding behaviour, which would look like this:
You can also download final composed version of example to avoid "assembly errors":
As such, you can also download intermediate file, which I've used to make small demonstration animations for this post without having to do some extreme wizardry with capturing full-scale animation and downscaling it afterwards.
Hello! First of all, great work. Works fantastic as is, but I’ve been trying to get it to work so I can have in-game sliding views when I click. It semi-works but gets stuck when it tries to move a second time. Any ideas on how you would do it?
“gets stuck” generally suggests that there’s something to do with logic, but it’s hard to tell the source of problem without seeing the related code. Perhaps it would be easier to use the “intermediate file” as implementation reference, since it’s also moving things in-game as opposed to game window.
Doesn’t work in fullscreen mode. Cool though. Fix please?
May I ask, how exactly could it work in fullscreen? If window is ran in fullscreen, it naturally occupies the whole screen, meaning that position and sizes cannot be changed. Slightly similar looking behaviour can be simulated by filling bottom-most view with opaque color, and then adjusting view_yport values of upper views to make them seem to slide out of bottom of screen… but that’s another story.
I have this since ages and it was a lot simpler to make (5 lines of code). Your code is probably more advanced tho as mine doesn’t slide back after its done.
As can be seen at end of “Making it interesting” section, code is also 5 lines long (3 lines create, 2 lines step). I agree that final code is not as short as it could be, but it is a “plug and play” type solution, meaning that modification of it would rarely be needed, if needed at all.
Dammit! I made this AGES ago! I should have uploaded it -_-
Great job :) Do you get many hits on this website? (curiosity)