Sign in to follow this  
gregkarber

Efficient way to generate a random mountain to climb

Recommended Posts

EDIT: I have decided to load and delete sprites around the borders of the viewable space. However, I'm having problems implementing this, as well. Please help.

 

I am working on a game where you play a head of lettuce that rolls, jumps, double-jumps, and wall-bounces up a procedurally generated cliff. I want this to go on for as long as possible, until you finally reach the top.

 

The first two implementations I attempted were both fruitless. First I tried to make the whole thing as sprites. Then I tried to make the whole thing with tiles (using .putTile, as I describe below). Then I tried to make it with tiles, but only place a couple rows at a time. All too slow.

 

So I abandoned the idea of using sprites and taught myself how to use the tilemap. Now I use .putTile to place all of the tiles. (I included the code that I used below, and believe me, I know how bad it is.) However, if I loaded more than a couple rows of it at the start, the game became quite slow.

 

What should I do? I am a bad programmer, so it takes me awhile to implement any of these.

 

1. Is there a more computationally efficient way to keep doing what I'm doing (placing tiles as the player gets close to them), perhaps without creating so many layers?

 

2. Generate the entire mountain as an array before starting, and then generate the blocks as sprites as the player gets near them. (This is what I would try next, as I how how to use arrays for proximity-based sprite generation because I used those in my first game)?

 

3. Generate the level either before or during as a tilemap, and place the tiles as we get near them?

 

4. Bite the bullet and break it into levels or stages, and swap them out at certain times?

 

5. Make it so that a fall always kills you, rather than allowing you to climb back up? The idea of falling down a huge thing seemed really hilarious to me, so I would hate to do this, but if I have to...

 

Basically, I want to know which of these is most likely to scale the best, because I really want my mountain to be freaking huge, and I lack the knowledge to understand which implementations will work.

 

Please help, or point me in the right direction, or tell me what I'm doing oh-so-wrong. In the meantime, I'll be working on implementation 2. Hopefully that'll work.

HR0LzNC.png

create: function() {	this.map = game.add.tilemap();	this.map.addTilesetImage('terrain', 'square', 64, 64, 0, 0);	this.superlayer = new Array();	this.the_tower = new Array();	this.tower_height = 1;	this.load_start = 15;},this.build_tower: function() 		this.superlayer[layer] = this.map.create('tower', HEIGHT, HEIGHT, 64, 64);    	this.superlayer[layer].scrollFactorX = 1;    	this.superlayer[layer].scrollFactorY = 1;    	    	for (var i=this.load_start; i<this.load_start+3; i++) {		    this.randchecker = Math.floor(Math.random()*4);		    this.tower_height += this.randchecker;		    if (this.randchecker == 3) this.create_platform(i,HEIGHT-this.tower_height);		    for (var k = HEIGHT-this.tower_height; k < HEIGHT-1; k++) {		    	this.map.putTile(0, i, k, this.layer1);		    	if ((k == HEIGHT-this.tower_height) && (Math.floor(Math.random()*2) == 0)) this.plant_tree(i, k-1);		    }		    		}				this.map.setCollision(0);		this.the_tower[layer] = game.physics.p2.convertTilemap(this.map, this.superlayer[layer], true, true);        for (var p = 0; p < this.the_tower[layer].length; p++) this.the_tower[layer][p].setMaterial(this.platformMaterial);		this.load_start += 3;},update: function() {	this.new_computation = 3*TILE*this.threshold;    	    	if (this.lettuce.x > this.new_computation) {    		if (this.switcher[this.threshold] == false) {    			this.switcher[this.threshold] = true;    			this.tower_build(this.threshold);    			this.threshold++;    		}    	}}

Share this post


Link to post
Share on other sites

I recommend going through the tutorial Pixi.js Parallax Scroller it's at the bottom 4 part series here: http://www.pixijs.com/resources/. I learned everything about game programming using this tutorial. Especially garbage collection, infinite map generation etc. It was quite a challenge because Pixi doesn't have high level features as Phaser. But most of the things in the tutorial are built in to Phaser already. I also recommend to check out my work on implementing Canabalt game using this tutorial https://github.com/eguneys/canabalt-html5. Finally it helps a lot to copy/clone existing projects, in situations like you have technical design considerations.

Share this post


Link to post
Share on other sites

1. And a bit of 3. You can make the level going infinitely if you recycle the sprites (or tiles, if that moves your boat) that are too far away. You only have a set number of sprites to cover three or four screens of your game. If the lettuce goes up the hill, you reposition the sprites that are further down up; if the lettuce goes down hill, you reposition the sprites further up to a closer position down below. Recycling objects is much easier computationaly than destroying and creating them continuously. If your sprites have a collision mask to only collide with the lettuce, it shouldn't impact your physics.

 

In order for the hill to always look the same, you could place the tiles according to a random number generation function that you change the seed of as the hill goes up or down. I recomend a Perlin Noise function, because it generates random numbers that vary in an organic way, making your hill look more natural and predictable for the player. Also, there is a two dimentional variation that would allow you to use x and y positions in your game as the seeds of the function, which is very convinient; just put a put a mathematical threshold to simulate the hill (so you only draw sprites on one side of an imaginary diagonal line). Here is an implementation of the Perlin Noise for javascript that I like: https://github.com/josephg/noisejs , just use it efficiently, if you use it too much, it could slow your game.

Share this post


Link to post
Share on other sites

Sorry for doble posting. Even better, use only x as the cordinates of the perlin noise, the resulting number is the height of that portion of the hill, you just need to multiply and constrain it according to your game . To that value you add a number that increases to the right and decreases to the left, so that the hill always goes generaly up to the right and down to the left.

Share this post


Link to post
Share on other sites

Thank you very much! I'm working on an implementation with sprites that are created on the edges and have .outOfBoundsKill = true. However, sprites that are created with this function don't seem to hold onto the physics bodies I'm trying to give them. Can anyone help?

 

I posted a new thread about it here. I have become so frustrated with my own ignorance and inability. Coding's hard, y'all.

Share this post


Link to post
Share on other sites

I couldn't get them to without killing them. I would love for someone to help with that. However, you just helped me figure out a huge thing. I have been loading individual square sprites, but almost 99% of them are columns. So I only loaded physics bodies on the top ones. However, I could massively reduce the number of sprites by making each sprite a column.

 

So thanks!

Share this post


Link to post
Share on other sites

( : No problem. Why can't you get to them without killng them? You can check, for example, onOutOfBounds without killing them. I believe you don't even need to check if it is outofbounds, though; you just need to check if the column on the extreme is too far from the player. Checking bounds can be expensive because it takes into account the overlapping of the collision box, but checking the distance on x is only getting a difference between two numbers, is very cheap. When the camera moves to the right, you check if the column that is further to the left is too far, if it is, you change its position to be the further column on the right. When the camera moves to the left, you check if the column that is further to the right is too far, if it is, you change its position to be the further column on the left.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.