使你的 Python 游戏玩家能够向前和向后跑

使你的 Python 游戏玩家能够向前和向后跑

使用 Pygame 模块来使你的 Python 平台开启侧滚效果,来让你的玩家自由奔跑。-- Seth Kenlon(作者)


这是仍在进行中的关于使用 Pygame 模块来在 Python 3 中在创建电脑游戏的第九部分。先前的文章是:

通过构建一个简单的掷骰子游戏去学习怎么用 Python 编程使用 Python 和 Pygame 模块构建一个游戏框架如何在你的 Python 游戏中添加一个玩家用 Pygame 使你的游戏角色移动起来如何向你的 Python 游戏中添加一个敌人在 Pygame 游戏中放置平台在你的 Python 游戏中模拟引力为你的 Python 平台类游戏添加跳跃功能

在这一系列关于使用 Pygame 模块来在 Python 3 中创建电脑游戏的先前文章中,你已经设计了你的关卡设计布局,但是你的关卡的一些部分可能已近超出你的屏幕的可视区域。在平台类游戏中,这个问题的普遍解决方案是,像术语“ 侧滚(side-scroller)”表明的一样,滚动。

滚动的关键是当玩家精灵接近屏的幕边缘时,使在玩家精灵周围的平台移动。这样给予一种错觉,屏幕是一个在游戏世界中穿梭追拍的摄像机。

这个滚动技巧需要两个在屏幕边缘的绝对区域,在绝对区域内的点处,在世界滚动期间,你的化身静止不动。

在侧滚动条中放置卷轴

如果你希望你的玩家能够后退,你需要一个触发点来向前和向后。这两个点仅仅是两个变量。设置它们各个距各个屏幕边缘大约 100 或 200 像素。在你的设置部分中创建变量。在下面的代码中,前两行用于上下文说明,所以仅需要添加这行后的代码:

player_list.add(player)steps = 10forwardX = 600backwardX = 230

在主循环中,查看你的玩家精灵是否在 forwardx 或 backwardx 滚动点处。如果是这样,向左或向右移动使用的平台,取决于世界是向前或向后移动。在下面的代码中,代码的最后三行仅供你参考:

    # scroll the world forward    if player.rect.x >= forwardx:        scroll = player.rect.x - forwardx        player.rect.x = forwardx        for p in plat_list:            p.rect.x -= scroll    # scroll the world backward    if player.rect.x <= backwardx:        scroll = backwardx - player.rect.x        player.rect.x = backwardx        for p in plat_list:            p.rect.x += scroll    ## scrolling code above  world.blit(backdrop, backdropbox)  player.gravity() # check gravity  player.update()

启动你的游戏,并尝试它。

Scrolling the world in Pygame

滚动像预期的一样工作,但是你可能注意到一个发生的小问题,当你滚动你的玩家和非玩家精灵周围的世界时:敌人精灵不随同世界滚动。除非你要你的敌人精灵要无休止地追逐你的玩家,你需要修改敌人代码,以便当你的玩家快速撤退时,敌人被留在后面。

敌人卷轴

在你的主循环中,你必须对卷轴平台为你的敌人的位置的应用相同的规则。因为你的游戏世界将(很可能)有不止一个敌人在其中,该规则应该被应用于你的敌人列表,而不是一个单独的敌人精灵。这是分组类似元素到列表中的优点之一。

前两行用于上下文注释,所以只需添加这两行后面的代码到你的主循环中:

  # scroll the world forward  if player.rect.x >= forwardx:    scroll = player.rect.x - forwardx    player.rect.x = forwardx    for p in plat_list:      p.rect.x -= scroll    for e in enemy_list:      e.rect.x -= scroll

来滚向另一个方向:

  # scroll the world backward  if player.rect.x <= backwardx:    scroll = backwardx - player.rect.x    player.rect.x = backwardx    for p in plat_list:      p.rect.x += scroll    for e in enemy_list:      e.rect.x += scroll

再次启动游戏,看看发生什么。

这里是到目前为止你已经为这个 Python 平台所写所有的代码:

#!/usr/bin/env python3# draw a world# add a player and player control# add player movement# add enemy and basic collision# add platform# add gravity# add jumping# add scrolling# 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 pygameimport sysimport os'''Objects'''class Platform(pygame.sprite.Sprite):# x location, y location, img width, img height, img filedef __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 = ylocself.rect.x = xlocclass Player(pygame.sprite.Sprite):'''Spawn a player'''def __init__(self):pygame.sprite.Sprite.__init__(self)self.movex = 0self.movey = 0self.frame = 0self.health = 10self.collide_delta = 0self.jump_delta = 6self.score = 1self.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 jump(self,platform_list):self.jump_delta = 0def gravity(self):self.movey += 3.2 # how fast player falls if self.rect.y > worldy and self.movey >= 0:self.movey = 0self.rect.y = worldy-ty def control(self,x,y):'''control player movement'''self.movex += xself.movey += y def update(self):'''Update sprite position''' self.rect.x = self.rect.x + self.movexself.rect.y = self.rect.y + self.movey# moving leftif self.movex < 0:self.frame += 1if self.frame > ani*3:self.frame = 0self.image = self.images[self.frame//ani]# moving rightif self.movex > 0:self.frame += 1if self.frame > ani*3:self.frame = 0self.image = self.images[(self.frame//ani)+4]# collisionsenemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)for enemy in enemy_hit_list:self.health -= 1#print(self.health)plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)for p in plat_hit_list:self.collide_delta = 0 # stop jumpingself.movey = 0if self.rect.y > p.rect.y:self.rect.y = p.rect.y+tyelse:self.rect.y = p.rect.y-ty ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)for g in ground_hit_list:self.movey = 0self.rect.y = worldy-ty-tyself.collide_delta = 0 # stop jumpingif self.rect.y > g.rect.y:self.health -=1print(self.health) if self.collide_delta < 6 and self.jump_delta < 6:self.jump_delta = 6*2self.movey -= 33# how high to jumpself.collide_delta += 6self.jump_delta+= 6 class Enemy(pygame.sprite.Sprite):'''Spawn an enemy'''def __init__(self,x,y,img):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load(os.path.join('images',img))self.movey = 0#self.image.convert_alpha()#self.image.set_colorkey(ALPHA)self.rect = self.image.get_rect()self.rect.x = xself.rect.y = yself.counter = 0 def move(self):'''enemy movement'''distance = 80speed = 8self.movey += 3.2 if self.counter >= 0 and self.counter <= distance:self.rect.x += speedelif self.counter >= distance and self.counter <= distance*2:self.rect.x -= speedelse:self.counter = 0 self.counter += 1if not self.rect.y >= worldy-ty-ty:self.rect.y += self.moveyplat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)for p in plat_hit_list:self.movey = 0if self.rect.y > p.rect.y:self.rect.y = p.rect.y+tyelse:self.rect.y = p.rect.y-tyground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)for g in ground_hit_list:self.rect.y = worldy-ty-ty class Level():def bad(lvl,eloc):if lvl == 1:enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemyenemy_list = pygame.sprite.Group() # create enemy groupenemy_list.add(enemy)# add enemy to group if lvl == 2:print("Level " + str(lvl) )return enemy_listdef loot(lvl,lloc):print(lvl)def ground(lvl,gloc,tx,ty):ground_list = pygame.sprite.Group()i=0if lvl == 1:while i < len(gloc):ground = Platform(gloc,worldy-ty,tx,ty,'ground.png')ground_list.add(ground)i=i+1if lvl == 2:print("Level " + str(lvl) )return ground_listdef platform(lvl,tx,ty):plat_list = pygame.sprite.Group()ploc = []i=0if lvl == 1:ploc.append((0,worldy-ty-128,3))ploc.append((300,worldy-ty-256,3))ploc.append((500,worldy-ty-128,4))while i < len(ploc):j=0while j <= ploc[2]:plat = Platform((ploc[0]+(j*tx)),ploc[1],tx,ty,'ground.png')plat_list.add(plat)j=j+1print('run' + str(i) + str(ploc))i=i+1if lvl == 2:print("Level " + str(lvl) )return plat_list'''Setup'''worldx = 960worldy = 720fps = 40 # frame rateani = 4# animation cyclesclock = pygame.time.Clock()pygame.init()main = TrueBLUE= (25,25,200)BLACK = (23,23,23 )WHITE = (254,254,254)ALPHA = (0,255,0)world = pygame.display.set_mode([worldx,worldy])backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()backdropbox = world.get_rect()player = Player() # spawn playerplayer.rect.x = 0player.rect.y = 0player_list = pygame.sprite.Group()player_list.add(player)steps = 10forwardx = 600backwardx = 230eloc = []eloc = [200,20]gloc = []#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]tx = 64 #tile sizety = 64 #tile sizei=0while i <= (worldx/tx)+tx:gloc.append(i*tx)i=i+1enemy_list = Level.bad( 1, eloc )ground_list = Level.ground( 1,gloc,tx,ty )plat_list = Level.platform( 1,tx,ty )'''Main loop'''while main == True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit(); sys.exit()main = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT or event.key == ord('a'):print("LEFT")player.control(-steps,0)if event.key == pygame.K_RIGHT or event.key == ord('d'):print("RIGHT")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 == pygame.K_UP or event.key == ord('w'):player.jump(plat_list)if event.key == ord('q'):pygame.quit()sys.exit()main = False# scroll the world forwardif player.rect.x >= forwardx:scroll = player.rect.x - forwardxplayer.rect.x = forwardxfor p in plat_list:p.rect.x -= scrollfor e in enemy_list:e.rect.x -= scroll # scroll the world backwardif player.rect.x <= backwardx:scroll = backwardx - player.rect.xplayer.rect.x = backwardxfor p in plat_list:p.rect.x += scrollfor e in enemy_list:e.rect.x += scrollworld.blit(backdrop, backdropbox)player.gravity() # check gravityplayer.update()player_list.draw(world) #refresh player positionenemy_list.draw(world)# refresh enemiesground_list.draw(world)# refresh enemiesplat_list.draw(world) # refresh platformsfor e in enemy_list:e.move()pygame.display.flip()clock.tick(fps)

via: https://opensource.com/article/19/12/python-platformer-game-run

作者: Seth Kenlon 选题: lujun9972 译者: robsean 校对: wxy

本文由 LCTT 原创编译, Linux中国 荣誉推出

点击“了解更多”可访问文内链接