2017-01-06 70 views
1

我的目标是让使用pygame的复古月球着陆器的游戏。现在我正在尝试创建登陆山脉和平台的背景。我希望每次新游戏开始时,平台和山脉都会有所不同。我的想法是绘制随机数的随机长度的水平线作为平台。我有几个问题是:随机线生成对于pygame的

  1. 如何确保水平线不重叠,并且都在看它像你登陆的问候​​所有入店。
  2. 我想画山是连接与创建三角形多线平台的最佳方式,但我不知道从哪里开始做

的代码,我已经工作了当前生成随机线,但我不知道如何进一步开发代码。

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) 

我试图寻找通过对随机生成的许多问题和教程,但没有一个是远程接近我要找的。

一个念头,我不得不解决重叠的问题是,如果有“读”或“看”以前创建的线条和限制的方式绘制基于一些如何......但我不知道的方法来做到这一点。

+0

一种想法可能是使用一个[1D柏林噪声函数(http://imgur.com/reUrcB8.png)随机生成山脉的轮廓。您可以使用类似于您必须生成随机长度平台(水平线)的代码,并使用Perlin算法来生成山间地形。 – Tagc

+0

这看起来就像我想为山脉做的一样。我将不得不查看如何重新创建。我的问题是,如果有一种方法可以控制它随机创建平台,或者随机选择屏幕上的任意直线? –

回答

1

我总结了以下代码的东西,可能会帮助你:

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) 

这将生成以下地形。你可以看到有平坦的地区(平台)被山脉分开。平台保证不重叠。他们也保证是“可访问的”,因为他们永远不会产生任何地形。

Terrain

我通过从均匀分布采样产生用于山区在y坐标。通过使用前面提到的Perlin噪声算法,您可能可以让山看起来更好。我发现this attempt在pygame应用程序中使用Perlin噪声。

+0

我使用Pygame的库来处理我的屏幕和我的游戏制作需要的休息,但它使用与顶部的坐标系统保留为(0,0)。我怎样才能改变这段代码让山脉朝向屏幕的底部?我试图改变我看到这两个变量不得不处理高度 –

+0

制作'window.height'“基地”,并从中减去生成的“高度”的值。 – Tagc

+0

对不起,我真的在努力学习,但这似乎并没有影响到它...... –