如果你打算在你的游戏世界中有一个坚固的地面,这种地面是很简单的。你只需要从整个窗口的一边到另一边“克隆”你的地面瓷砖。例如,你可以创建一个 X 和 Y 值的列表来规定每个瓷砖应该放置的位置,然后使用一个循环来获取每个值并绘制每一个瓷砖。这仅是一个示例,所以不要添加这到你的代码:
1 2
# Do not add this to your code gloc = [0,656,64,656,128,656,192,656,256,656,320,656,384,656]
不过,如果你仔细看,你可以看到所有的 Y 值是相同的,X 值以 64 的增量不断地增加 —— 这就是瓷砖的大小。这种重复是精确地,是计算机擅长的,因此你可以使用一点数学逻辑来让计算机为你做所有的计算:
添加这些到你的脚本的设置部分:
1 2 3 4 5 6 7 8 9 10
gloc = [] tx = 64 ty = 64
i=0 while i <= (worldx/tx)+tx: gloc.append(i*tx) i=i+1
ground_list = Level.ground( 1,gloc,tx,ty )
现在,不管你的窗口的大小,Python 会通过瓷砖的宽度分割游戏世界的宽度,并创建一个数组列表列出每个 X 值。这里不计算 Y 值,因为在平的地面上这个从不会变化。
为了在一个函数中使用数组,使用一个 while 循环,查看每个条目并在适当的位置添加一个地面瓷砖:
1 2 3 4 5 6 7 8 9 10 11 12 13
def ground(lvl,gloc,tx,ty): ground_list = pygame.sprite.Group() i=0 if lvl == 1: while i < len(gloc): ground = Platform(gloc[i],worldy-ty,tx,ty,'tile-ground.png') ground_list.add(ground) i=i+1
if lvl == 2: print("Level " + str(lvl) )
return ground_list
除了 while 循环,这几乎与在上面一部分中提供的瓷砖类平台的 ground 函数的代码相同。
对于移动的平台,原理是相似的,但是这里有一些技巧可以使它简单。
你可以通过它的起始像素(它的 X 值)、距地面的高度(它的 Y 值)、绘制多少瓷砖来定义一个平台,而不是通过像素绘制每个平台。这样,你不必操心每个平台的宽度和高度。
这个技巧的逻辑有一点复杂,因此请仔细复制这些代码。有一个 while 循环嵌套在另一个 while 循环的内部,因为这个函数必须考虑每个数组项的三个值来成功地建造一个完整的平台。在这个示例中,这里仅有三个平台以 ploc.append 语句定义,但是你的游戏可能需要更多,因此你需要多少就定义多少。当然,有一些不会出现,因为它们远在屏幕外,但是一旦当你进行滚动时,它们将呈现在眼前。
#!/usr/bin/env python3 # draw a world # add a player and player control # add player movement # add enemy and basic collision # add platform
# GNU All-Permissive License # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty.
import pygame import sys import os
''' Objects '''
class Platform(pygame.sprite.Sprite): # x location, y location, img width, img height, img file def __init__(self,xloc,yloc,imgw,imgh,img): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(os.path.join('images',img)).convert() self.image.convert_alpha() self.rect = self.image.get_rect() self.rect.y = yloc self.rect.x = xloc
class Player(pygame.sprite.Sprite): ''' Spawn a player ''' def __init__(self): pygame.sprite.Sprite.__init__(self) self.movex = 0 self.movey = 0 self.frame = 0 self.health = 10 self.score = 1 self.images = [] for i in range(1,9): img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert() img.convert_alpha() img.set_colorkey(ALPHA) self.images.append(img) self.image = self.images[0] self.rect = self.image.get_rect()
def control(self,x,y): ''' control player movement ''' self.movex += x self.movey += y
''' Main loop ''' while main == True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); sys.exit() main = False
if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT or event.key == ord('a'): player.control(-steps,0) if event.key == pygame.K_RIGHT or event.key == ord('d'): player.control(steps,0) if event.key == pygame.K_UP or event.key == ord('w'): print('jump')
if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == ord('a'): player.control(steps,0) if event.key == pygame.K_RIGHT or event.key == ord('d'): player.control(-steps,0) if event.key == ord('q'): pygame.quit() sys.exit() main = False
# world.fill(BLACK) world.blit(backdrop, backdropbox) player.update() player_list.draw(world) #refresh player position enemy_list.draw(world) # refresh enemies ground_list.draw(world) # refresh enemies for e in enemy_list: e.move() pygame.display.flip() clock.tick(fps)