Implementing scrolling background layers and foreground interaction objects

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Annabelle
Prole
Posts: 13
Joined: Sun Feb 19, 2017 1:37 pm

Implementing scrolling background layers and foreground interaction objects

Post by Annabelle »

Hi! So I'm working on and off on this space sort of exploring game. So far with some previous help here I implemented simple background infinite scrolling and that is great and all. But I'm having trouble now doing two main things.

1. How would I make multiple layers of background say stars so I can scroll multiple levels, background planets, asteroids etc. If someone can help me figure out how to even add one extra layer I bet I can do multiple layers. I'd like it so I can generate the content in the background off screen and then it scrolls on screen and vanishes, that way it can be totally different background and unique landscape all the time while moving in space.

2. How would I have pop ups of say monsters/asteroids/aliens and powerups appear on the same plane as the player, so I can have them scroll across and be collected as well? I'd like to be able to generate these too so they randomly appear over time. That is once something leaves the screen it shouldn't matter anymore, but when it's on screen it should be stationary in a spot to be collected (powerup) or a floating object (asteroid/aliens). I tried doing it but my item is just stuck in a quad and keeps resetting or something, which is useless.

I know this is a lot but I'm hoping someone can help/guide me so I can do at least part of these and then implement rest on my own from the ideas.

Github link of latest project release/code so far:

https://github.com/princessannabelle/Planet-Explorer-

Thank you for the advice!
hamberge
Prole
Posts: 25
Joined: Wed Aug 16, 2017 2:55 pm

Re: Implementing scrolling background layers and foreground interaction objects

Post by hamberge »

I'll take a crack at this but I can't promise it'll work. Also this is going to depend on what you have already implemented. I haven't had the chance to look through your code.

For 1) I think you need to extend your current background system to implement additional layers. For each layer you will determine what to draw based on an underlying set of values. I assume you already do something like this -- render a background layer based on player or camera position. For the additional layers, simply have another renderer that renders a different background based on the same underlying set of values. Does this help at all?

For 2) I think this is going to be a separate system than background, based on player position. If I were to implement this I'd just have an item generator that takes in the player position, calculates the extent of the player's vision (i.e., what's on the screen) based on the player position and maybe camera characteristics, and spawns items based on whatever algorithm you choose to implement. If you want random item spawn, this is easy. You can have an item density variable that you use in conjunction with a random number generator to check whether each area of space is going to have an item spawn when that area becomes visible. And for the item to spawn, you can just randomize across already-defined items.

For killing the items, either the items themselves can determine when they are dead based on their position in the player's vision or your item spawner can check the items each frame and kill them when they go out of vision. Maybe doing it with the spawner is cleaner but I'm not sure.

Edit: I looked at your code. The place where you calculate your quadcoords -- this is where you want to calculate whatever variable you need to render a different background. You can just calculate different values for the backgrounds and use them to draw the second background layer.

By the way, if somebody hasn't told you this already, and/or if you aren't aware, if you want to build this game out to be much more complicated, you are going to need to decouple a lot of things. For example, it's generally not considered good practice to calculate features of your graphics in your update function. So the quadcoord calculations really should be in draw. It's also good practice to isolate the capture of input to the actual use of input, which would allow you to easily change both what input you want to capture and what you do with that input. Another thing is change player.x and player.y based on player.v, not background coords. Then you can maybe update the camera field of view based on player x and y. And then in draw you render background based on camera field of view. It sounds complicated up front but separating these different aspects out simplifies problems in the long run.
Annabelle
Prole
Posts: 13
Joined: Sun Feb 19, 2017 1:37 pm

Re: Implementing scrolling background layers and foreground interaction objects

Post by Annabelle »

hamberge wrote: Mon Oct 09, 2017 6:03 pm I'll take a crack at this but I can't promise it'll work. Also this is going to depend on what you have already implemented. I haven't had the chance to look through your code.
Thank you. I've detailed questions about your comments below.
hamberge wrote: Mon Oct 09, 2017 6:03 pm For 1) I think you need to extend your current background system to implement additional layers. For each layer you will determine what to draw based on an underlying set of values. I assume you already do something like this -- render a background layer based on player or camera position. For the additional layers, simply have another renderer that renders a different background based on the same underlying set of values. Does this help at all?
I think it does, but I'm guessing I would need different quads to deal with multiple layers...?
hamberge wrote: Mon Oct 09, 2017 6:03 pm For 2) I think this is going to be a separate system than background, based on player position. If I were to implement this I'd just have an item generator that takes in the player position, calculates the extent of the player's vision (i.e., what's on the screen) based on the player position and maybe camera characteristics, and spawns items based on whatever algorithm you choose to implement. If you want random item spawn, this is easy. You can have an item density variable that you use in conjunction with a random number generator to check whether each area of space is going to have an item spawn when that area becomes visible. And for the item to spawn, you can just randomize across already-defined items.


Player is always in center of screen. Problem I have is how do I have the item simply float across screen randomly? So it doesn't get caught in one of my background quads or only a portion of screen, that is scrolling across same pane as user?
hamberge wrote: Mon Oct 09, 2017 6:03 pm For killing the items, either the items themselves can determine when they are dead based on their position in the player's vision or your item spawner can check the items each frame and kill them when they go out of vision. Maybe doing it with the spawner is cleaner but I'm not sure.

Edit: I looked at your code. The place where you calculate your quadcoords -- this is where you want to calculate whatever variable you need to render a different background. You can just calculate different values for the backgrounds and use them to draw the second background layer.

By the way, if somebody hasn't told you this already, and/or if you aren't aware, if you want to build this game out to be much more complicated, you are going to need to decouple a lot of things. For example, it's generally not considered good practice to calculate features of your graphics in your update function. So the quadcoord calculations really should be in draw. It's also good practice to isolate the capture of input to the actual use of input, which would allow you to easily change both what input you want to capture and what you do with that input. Another thing is change player.x and player.y based on player.v, not background coords. Then you can maybe update the camera field of view based on player x and y. And then in draw you render background based on camera field of view. It sounds complicated up front but separating these different aspects out simplifies problems in the long run.
Okay I'll try that.

Anyone else have advice? Or perhaps some examples that I can look at?

Edit: I also just noticed but for some reason after making the git repo my code doesn't even launch anymore? What could've possibly happened? I don't know how to fix it.
hamberge
Prole
Posts: 25
Joined: Wed Aug 16, 2017 2:55 pm

Re: Implementing scrolling background layers and foreground interaction objects

Post by hamberge »

To simplify the issues you are having, I think you need to make sure that your program has the notion of a world position in it. Your program kind of skips this, going directly from player velocity to adjusting the background. The player is always in the center of the screen, as you say, but the player is traversing through a world and has a position in that world. Once you have this concept, the display of everything else should fall into place fairly easily. Your backgrounds would be calculated based on the position of your player in the world. The items will also have a position in the world and it will be easy to calculate the position of the items in that world.

First, note that your code has player.x and player.y variables. However, it doesn't look like you update them or use them. These would be very useful. You should update them based on the velocity. These player.x and player.y variables should be thought of as a position of the player in your world, not on the screen.

So you could do:

Code: Select all

player.x = player.x + player.v.x
player.y = player.y + player.v.y
Once you have player.x and player.y variables updated, you can have top left corner and bottom right corner x and y variables to define the rectangular extent of your camera. These top left corner and bottom right corner x and y variables would be updated based on the player x and y variables and a "camera" width and height, which should match screen resolution. For example:

Code: Select all

cameraTopLeft.x = player.x - cameraWidth/2
cameraTopLeft.y = player.y - cameraHeight/2
cameraBottomRight.x = player.x + cameraWidth/2
cameraBottomRight.y = player.y + cameraHeight/2
Once you have the camera defined in terms of width and height as well as position, you can update any number of background layers you want. Just calculate which quads you need based on the extents of your defined camera as stated above. Calculate the quads based on cameraTopLeft.x, cameraTopLeft.y, cameraBottomRight.x, and cameraBottomRight.y. It's easy to do this -- just determine how the quads align with your world coordinates and calculate which quads to display based on that positioning.

For your items, I'm not completely sure what you mean by float across the screen. I think you might mean that the item will have a fixed position in the world but will change position based on your player's position in the world. Again, you will take advantage of the notion of a camera to change the displayed position of the items. Whenever you create the items, you need to give them x and y positions in your world. Then you can just check whether those items are within the extents of your camera, again as defined above.

To create the items, you might want to look into the notion of object oriented programming and how that can help you achieve the idea of spawning objects. You could, for example, have an itemSpawner table that has a spawnItem(x, y, type) function. That function could be called as your player moves across your world and would return an item object (a table in Lua). You would only want to call it occasionally, so that your screen doesn't fill up with objects. The code for deciding when to call it could be in love.update().

For the items, if you do not want them to actually move in your world, but only across the screen as your player moves, all you need to do is have a item.draw() function that draws the item to the screen based on its position in the world. You could compare the position of the item to the extents of the camera and, based on that comparison, determine a location for the item on the screen.

To kill the items, have an checkForDeadItem() function that is called for each item in love.update(). This function would check a particular item to determine whether that item is within the extents of the screen and destroy the item if so. One easy way to destroy the item would be to set its value to nil.
Post Reply

Who is online

Users browsing this forum: Amazon [Bot], Bing [Bot], Google [Bot] and 2 guests