pygame 的随机线生成
Random Line Generation For pygame
我的目标是使用 pygame 制作一款复古月球着陆器游戏。现在我正在尝试创建山脉和平台的背景。我希望每次开始新游戏时,平台和山脉都会有所不同。我的想法是绘制随机数量的随机长度的水平线作为平台。我对此有一些问题:
- 如何确保水平线不重叠,并且看起来像着陆时一样清晰可见。
- 我认为画山的最好方法是用更多的线连接平台,形成三角形,但我不知道从哪里开始做
我一直在使用的代码目前生成随机行,但我不确定如何进一步开发代码。
for platforms in range(1, random.randint(1, 10)):
rand_x_start = random.randint(0, 400)
rand_x_end = random.randint(0, 400)
rand_y = random.randint(HEIGHT / 2, HEIGHT)
pygame.draw.line(self.background, white, (rand_x_start, rand_y), (rand_x_end, rand_y), 2)
我已经尝试查看许多关于随机生成的问题和教程,但 none 与我正在寻找的内容相去甚远。
一个想法我必须解决重叠问题是,如果有一种方法可以 "read" 或 "see" 以前创建的线并根据某种方式限制绘图......但我'我不确定这样做的方法。
我整理了以下代码,希望对您有所帮助:
import random
from collections import namedtuple
from PIL import Image, ImageDraw
GaussianDistribution = namedtuple('GaussianDistribution', ['mu', 'sigma'])
Platform = namedtuple('Platform', ['start', 'end', 'height'])
Point = namedtuple('Point', ['x', 'y'])
PLATFORM_HEIGHT_DISTRIBUTION = GaussianDistribution(50, 10)
PLATFORM_WIDTH_DISTRIBUTION = GaussianDistribution(100, 10)
INTER_PLATFORM_DISTRIBUTION = GaussianDistribution(500, 20)
RANDOM = random.Random()
def sample_distribution(distribution):
return RANDOM.normalvariate(distribution.mu, distribution.sigma)
def create_platforms(num_platforms):
last_platform_end = 0
for i in range(num_platforms):
start = int(sample_distribution(INTER_PLATFORM_DISTRIBUTION) + last_platform_end)
end = int(sample_distribution(PLATFORM_WIDTH_DISTRIBUTION) + start)
height = int(sample_distribution(PLATFORM_HEIGHT_DISTRIBUTION))
last_platform_end = end
yield Platform(start, end, height)
def create_mountains_between_points(p1, p2):
mountain_start = p1.x
mountain_end = p2.x
num_points = int((mountain_end - mountain_start) / 10)
for i in range(num_points):
# TODO: use 1D Perlin function to generate point.y
yield Point(mountain_start + i * 10, RANDOM.random() * 100)
def create_terrain(platforms):
origin = Point(0, 0)
first_platform_start = Point(platforms[0].start, platforms[0].height)
terrain = []
terrain += list(create_mountains_between_points(origin, first_platform_start))
for i, platform in enumerate(platforms):
platform_starts_at = Point(platform.start, platform.height)
platform_ends_at = Point(platform.end, platform.height)
terrain.append(platform_starts_at)
terrain.append(platform_ends_at)
if i < len(platforms) - 1:
next_platform = platforms[i + 1]
next_platform_starts_at = Point(next_platform.start, next_platform.height)
mountains = create_mountains_between_points(platform_ends_at, next_platform_starts_at)
terrain += mountains
return terrain
def draw_terrain(terrain):
im = Image.new('RGBA', (4000, 200), (255, 255, 255, 0))
draw = ImageDraw.Draw(im)
draw.line(terrain, fill=(0, 0, 0, 255))
im.show()
if __name__ == '__main__':
platforms = list(create_platforms(num_platforms=10))
terrain = create_terrain(platforms)
draw_terrain(terrain)
这会生成以下地形。你可以看到有被山脉隔开的平坦区域(平台)。平台保证不重叠。它们也保证是 "accessible",因为它们上面永远不会生成任何地形。
我通过从均匀分布中采样来生成山脉的 y 坐标。您可能可以使用我之前提到的 Perlin 噪声算法使山脉看起来更好。我发现 this attempt 在 pygame 应用程序中使用 Perlin 噪声。
我的目标是使用 pygame 制作一款复古月球着陆器游戏。现在我正在尝试创建山脉和平台的背景。我希望每次开始新游戏时,平台和山脉都会有所不同。我的想法是绘制随机数量的随机长度的水平线作为平台。我对此有一些问题:
- 如何确保水平线不重叠,并且看起来像着陆时一样清晰可见。
- 我认为画山的最好方法是用更多的线连接平台,形成三角形,但我不知道从哪里开始做
我一直在使用的代码目前生成随机行,但我不确定如何进一步开发代码。
for platforms in range(1, random.randint(1, 10)):
rand_x_start = random.randint(0, 400)
rand_x_end = random.randint(0, 400)
rand_y = random.randint(HEIGHT / 2, HEIGHT)
pygame.draw.line(self.background, white, (rand_x_start, rand_y), (rand_x_end, rand_y), 2)
我已经尝试查看许多关于随机生成的问题和教程,但 none 与我正在寻找的内容相去甚远。
一个想法我必须解决重叠问题是,如果有一种方法可以 "read" 或 "see" 以前创建的线并根据某种方式限制绘图......但我'我不确定这样做的方法。
我整理了以下代码,希望对您有所帮助:
import random
from collections import namedtuple
from PIL import Image, ImageDraw
GaussianDistribution = namedtuple('GaussianDistribution', ['mu', 'sigma'])
Platform = namedtuple('Platform', ['start', 'end', 'height'])
Point = namedtuple('Point', ['x', 'y'])
PLATFORM_HEIGHT_DISTRIBUTION = GaussianDistribution(50, 10)
PLATFORM_WIDTH_DISTRIBUTION = GaussianDistribution(100, 10)
INTER_PLATFORM_DISTRIBUTION = GaussianDistribution(500, 20)
RANDOM = random.Random()
def sample_distribution(distribution):
return RANDOM.normalvariate(distribution.mu, distribution.sigma)
def create_platforms(num_platforms):
last_platform_end = 0
for i in range(num_platforms):
start = int(sample_distribution(INTER_PLATFORM_DISTRIBUTION) + last_platform_end)
end = int(sample_distribution(PLATFORM_WIDTH_DISTRIBUTION) + start)
height = int(sample_distribution(PLATFORM_HEIGHT_DISTRIBUTION))
last_platform_end = end
yield Platform(start, end, height)
def create_mountains_between_points(p1, p2):
mountain_start = p1.x
mountain_end = p2.x
num_points = int((mountain_end - mountain_start) / 10)
for i in range(num_points):
# TODO: use 1D Perlin function to generate point.y
yield Point(mountain_start + i * 10, RANDOM.random() * 100)
def create_terrain(platforms):
origin = Point(0, 0)
first_platform_start = Point(platforms[0].start, platforms[0].height)
terrain = []
terrain += list(create_mountains_between_points(origin, first_platform_start))
for i, platform in enumerate(platforms):
platform_starts_at = Point(platform.start, platform.height)
platform_ends_at = Point(platform.end, platform.height)
terrain.append(platform_starts_at)
terrain.append(platform_ends_at)
if i < len(platforms) - 1:
next_platform = platforms[i + 1]
next_platform_starts_at = Point(next_platform.start, next_platform.height)
mountains = create_mountains_between_points(platform_ends_at, next_platform_starts_at)
terrain += mountains
return terrain
def draw_terrain(terrain):
im = Image.new('RGBA', (4000, 200), (255, 255, 255, 0))
draw = ImageDraw.Draw(im)
draw.line(terrain, fill=(0, 0, 0, 255))
im.show()
if __name__ == '__main__':
platforms = list(create_platforms(num_platforms=10))
terrain = create_terrain(platforms)
draw_terrain(terrain)
这会生成以下地形。你可以看到有被山脉隔开的平坦区域(平台)。平台保证不重叠。它们也保证是 "accessible",因为它们上面永远不会生成任何地形。
我通过从均匀分布中采样来生成山脉的 y 坐标。您可能可以使用我之前提到的 Perlin 噪声算法使山脉看起来更好。我发现 this attempt 在 pygame 应用程序中使用 Perlin 噪声。