I am trying to randomly generate terrain for a game, in such a way that an object at position x, y is of type number f(x, y) (so I don't have to store the values of all the objects. I am trying to generate an environment like a city, with streets and blocks between them.

For example:

# # # # #   # # #   # # # # 
# # # # #   # # #   # # # # 
# # # # #   # # #   # # # # 
# # # # #   # # #   # # # #
# # # # #
# # # # #   # # # # #   # # 
            # # # # #   # # 
# # # # #   # # # # #   # #  
# # # # #   # # # # #   # # 

#   # # # # # # #   # # # # 
#   # # # # # # #   # # # # 
#   # # # # # # #   # # # # 
#   # # # # # # #   # # # #

I can generate something kind of like this in a regular pattern, using f(x, y): (x*y) mod n, where n is a constant and a resulting tile is only empty if f(x, y) == 0.

For instance, with n as 5:

# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 

# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 

# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # # 
# # # #   # # # #   # # # #

How can I alter my algorithm (or get a new one) to get results more like the first example?

Or am I going about this completely the wrong way?

有帮助吗?

解决方案 2

I have found a function that produces more or less what I want, however it could definitely be improved.

Pseudocode:

function f(x, y):
if x mod size_of_zones == 0 or y mod size_of_zones == 0:
    return 0
elif x % (a number between the maximum and minimum block sizes, randomly picked but the same for each block) == 0:
    return 0
elif y % (a number between the maximum and minimum block sizes, randomly picked but the same for each block) == 0:
    return 0
else:
    return 1

My code for a number between the maximum and minimum block sizes, randomly picked but the same for each block was this:

shuffled_list_of_integers_between_min_and_max_block_sizes[(y floordiv zone_size) mod maximum_block_size]

for x and

shuffled_list_of_integers_between_min_and_max_block_sizes[(x floordiv zone_size) mod maximum_block_size]

for y.

其他提示

For the first question: it depends how 'naturally' you want it. You can easily use a random generator to generate some roads of a specific length; or better, make a road, then from both ends start a new road etc.

In case of a more natural way, think about how a real town/city looks like: longer roads, with smaller roads inside. this of course has to be reflected in the algorithm.

I don't understand your second question, ... just changing each # by different kind of symbols (denoting different buildings)? In that case, take into account buildings of different sizes. You better do the street layout first, then the remainding (maybe even by following the streets left/right side), filling in the buildings.

Edit:

You also could use instead of an 'ASCII' map like above use pointers to objects. E.g. in the 14x14 map above instead of using one ASCII character, use an object pointer. Which can point to anything like: - Road - Building (inheriting from multiple building types)

You can have multiple squares point to the same object (denoting bigger buildings), or the same street. Advantages: - You can use all kind of properties (like what kind of building, functions of the building, age, statistics per building) - For roads: name, pointers to other roads connected to it (for navigation purposes).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top