GameMaker Screen wrap around

Hyomoto

Member
This has been on my plate for a very long time and is the major reason I've always avoided using the views and cameras. If I want to have some sort of seamless level wraparound, there doesn't seem to be any really good way of being able to do that. What I've done in the past is render the entire room to a surface, then you can just use surface_draw_tiled() to achieve this effect. A bit performance intensive, but ultimately it does get the job done if you are working in room sizes small enough to fit into a single surface.

However, I feel like I have to just be overlooking something. It really feels like there should just be a check box somewhere under views to allow wrap around rendering. Now, I understand "it's not as easy as all that", as I've just described I've built ways of doing this. But my interest is in that views seems to cull out any tiles that aren't being drawn, which is a significant performance enhancement. I also discovered they are very compatible with a lot of rendering tricks I've used in the past. So it's like, this wraparound issue is really my final barrier to being able to make use of views and cameras.

So I'm throwing it out to the community. Does anyone have any knowledge of this topic, and can they point me in a direction to find a solution?
 

Alexx

Member
I did do an example a while back in GMS1.
I only did for left and right side of the room.
I did it through using more than view port, which would change size and location based on the players position.
So if the room width was say 800, if the player was closing to the room edge than this the other view would kick in and draw the appropriate area based on this. This would update as the player moved.

I don't have this example anymore, but maybe I can redo it for GMS2 if needed.
 

Hyomoto

Member
I did do an example a while back in GMS1.
I only did for left and right side of the room.
I did it through using more than view port, which would change size and location based on the players position.
So if the room width was say 800, if the player was closing to the room edge than this the other view would kick in and draw the appropriate area based on this. This would update as the player moved.

I don't have this example anymore, but maybe I can redo it for GMS2 if needed.
That's something that I was considering, as it really seems like the only feasible way to do this. It creates some other potential issues, but those can be worked around to some degree especially if the performance is acceptable. As I understand it though, every instance has its draw code called for every view. It's good to hear someone else tried this and had success though, it means its still on the table.

@Mike, that it does not. Check the code, he's using a view but draws everything manually and this would not work at all with tiles. He could probably simplify his code by getting rid of the view. I appreciate the response, but maybe I just don't see how this demo reflects my problem?
 

Mike

nobody important
GMC Elder
I wrote the demo, so I know what it does. for wrapping it works fine.

GM doesn't do automatic wrapping, so you do need to do some "tricks" to make it do what you want it to, unless you want to render stuff to a surface and do a split render. Views can be manipulated to produced the effect you're after, by using 2 and dynamically generating the ports on screen.

But if it's not suitable ,then no worries....
 

Alexx

Member
I won't provide anything further on this topic, Mike's example totally outshines anything I could do.
 
Last edited:

Hyomoto

Member
@Mike - @Alexx also suggested manipulating views. Make no mistake, I appreciate your input: if you say its possible, its possible. However, I don't see anything in the demo that would lead to a split render or dynamically generating ports on screen. I'm not questioning whether the demo accomplishes screen wrapping, but I'm not asking "how to do screen wrapping", I'm asking if there is a way to wrap the screen using views. The demo really doesn't do that. You are drawing the background as a sprite offset to the view, then everything else on top of it. That's why I say you probably don't even need the view, you aren't using it for anything. I assume its there purely to set up the window. Otherwise it's more or less what I did before. Rather than a sprite, I compressed all the layers down into a surface and drew that as the background. Maybe its not your instinct to give really technical advice, and if I was unclear in my initial post I apologize, but that's the type of information I'm looking for.
 
Wrap like a NES wrap where you go out the left and appear the right? I would double enemies and double the player that breaches the X lines to exit the screen.
 

Mike

nobody important
GMC Elder
okay... using 2 views technically....

define a room and create 2 views evenly split, one on the left, one on the right. Both reaching the top of the screen, and view 1 is disabled.
Enable view 0 and set the size to fill the view, and the X to where the screen is to be positioned.

Next, if the position is off the right of the room, then change the size of view 0 so that view 0 is the screen width-the distance PAST the room width.
i.e. view size is 20, room width is 100, x = 95, then view 0 with would be position at 95 with a width of 5
Next enable view 1 then size it's position to 5 on screen, with a view of 0 and a width of 15.

next frame... 1 pixel further on.

i.e. view size is 20, room width is 100, x = 96, then view 0 with would be position at 96 with a width of 4
Next enable view 1 then size it's position to 4 on screen, with a view of 0 and a width of 16.

Do this every frame.....
 

Hyomoto

Member
@Mike - The math isn't important. I can figure that out, I'm just trying to pick your brain for viable options and to make sure I didn't miss something buried in a function somewhere. Thank you for the input. Ultimately it apparently comes down to stitching images together in one way or another. Reading up on the views I found you can draw views to surfaces (I also found, this isn't in the manual, that doing so ties hport and vport to the surface dimensions), which means there might be a less fiddly way than constantly resizing cameras. Amusingly, it seems like the performance I would gain from using views ends up lost having to use four of them. Still, it's a path to experiment with and I'll see where it goes. If you know any other hacks or tricks, I'm interested to hear them.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Having multiple views means each draw event is run multiple times, so I'm unsure if there's any performance gain to speak of. Just drawing things close to the border regions again (with their coordinates added/subtracted by one room width/height) achieves the same thing in the worst case (everything needs to be redrawn) and has a better performance most of the time (if you're smart to check whether additional drawings are needed or not every time), and interferes less with stuff like particle systems (doesn't loop around) and full-screen surfaces (might need to be split and adjusted to match the view FOUR TIMES!)
 

Hyomoto

Member
Having multiple views means each draw event is run multiple times, so I'm unsure if there's any performance gain to speak of. Just drawing things close to the border regions again (with their coordinates added/subtracted by one room width/height) achieves the same thing in the worst case (everything needs to be redrawn) and has a better performance most of the time (if you're smart to check whether additional drawings are needed or not every time), and interferes less with stuff like particle systems (doesn't loop around) and full-screen surfaces (might need to be split and adjusted to match the view FOUR TIMES!)
I've considered most of that, but honestly individual objects are perhaps the easiest thing to "fix" in this case. GML is surprisingly flexible with the draw pipeline and removing extraneous draw calls. However, I agree with the rest of that. There's a lot of management going on to calculate, place, draw, etc... The short version is the old method I was using is probably best for the purposes I want it for, but it's still worth trying out something new. Especially if it turns out there's an approach I haven't considered before!
 

Bentley

Member
@Mike that idea of using views is pretty cool. (I don't know if this is camera wrapping) but I did this for a Fantasy Zone "remake": similar / same as @Alexx said, I drew two borders, left and right, and they tiled with the center, and if the player went too far right, he and everything around would wrap.
 
Top