Loot in Python platformer
你的獎勵將會顯示出來,但是當你的玩家碰到它們時,它們不會做任何事情,當你的玩家經過它們時,它們也不會滾動。接下來解決這些問題。
滾動獎勵
像平台一樣,當玩家在遊戲世界中移動時,獎勵必須滾動。邏輯與平台滾動相同。要向前滾動獎勵物品,添加最後兩行:
for e in enemy_list: e.rect.x -= scroll for l in loot_list: l.rect.x -= scroll
要向後滾動,請添加最後兩行:
for e in enemy_list: e.rect.x += scroll for l in loot_list: l.rect.x += scroll
再次啓動你的遊戲,看看你的獎勵物品現在表現得像在遊戲世界裏一樣了,而不是僅僅畫在上面。
檢測碰撞
就像平台和敵人一樣,你可以檢查獎勵物品和玩家之間的碰撞。邏輯與其他碰撞相同,除了撞擊不會(必然)影響重力或生命值。取而代之的是,命中會導致獎勵物品會消失並增加玩家的分數。
當你的玩家觸摸到一個獎勵對象時,你可以從 loot_list 中移除該對象。這意味著當你的主循環在 loot_list 中重繪所有獎勵物品時,它不會重繪那個特定的對象,所以看起來玩家已經獲得了獎勵物品。
在 Player 類的 update 函數中的平台碰撞檢測之上添加以下代碼(最後一行僅用于上下文):
loot_hit_list = pygame.sprite.spritecollide(self, loot_list, False) for loot in loot_hit_list: loot_list.remove(loot) self.score += 1 print(self.score) plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
當碰撞發生時,你不僅要把獎勵從它的組中移除,還要給你的玩家一個分數提升。你還沒有創建分數變量,所以請將它添加到你的玩家屬性中,該屬性是在 Player 類的 __init__ 函數中創建的。在下面的代碼中,前兩行是上下文,所以只需添加分數變量:
self.frame = 0 self.health = 10 self.score = 0
當在主循環中調用 update 函數時,需要包括 loot_list:
player.gravity() player.update()
如你所見,你已經掌握了所有的基本知識。你現在要做的就是用新的方式使用你所知道的。
在下一篇文章中還有一些提示,但是與此同時,用你學到的知識來制作一些簡單的單關卡遊戲。限制你試圖創造的東西的範圍是很重要的,這樣你就不會埋沒自己。這也使得最終的成品看起來和感覺上更容易完成。
以下是迄今爲止你爲這個 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 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.collide_delta = 0 self.jump_delta = 6 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 jump(self,platform_list): self.jump_delta = 0
def gravity(self): self.movey += 3.2 # how fast player falls if self.rect.y > worldy and self.movey >= 0: self.movey = 0 self.rect.y = worldy-ty def control(self,x,y): ”’ control player movement ”’ self.movex += x self.movey += y def update(self): ”’ Update sprite position ”’ self.rect.x = self.rect.x + self.movex self.rect.y = self.rect.y + self.movey
# moving left if self.movex < 0: self.frame += 1 if self.frame > ani*3: self.frame = 0 self.image = self.images[self.frame//ani]
# moving right if self.movex > 0: self.frame += 1 if self.frame > ani*3: self.frame = 0 self.image = self.images[(self.frame//ani)+4]
# collisions enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False) for enemy in enemy_hit_list: self.health -= 1 #print(self.health)
loot_hit_list = pygame.sprite.spritecollide(self, loot_list, False) for loot in loot_hit_list: loot_list.remove(loot) self.score += 1 print(self.score)
plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False) for p in plat_hit_list: self.collide_delta = 0 # stop jumping self.movey = 0 if self.rect.y > p.rect.y: self.rect.y = p.rect.y+ty else: 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 = 0 self.rect.y = worldy-ty-ty self.collide_delta = 0 # stop jumping if self.rect.y > g.rect.y: self.health -=1 print(self.health) if self.collide_delta < 6 and self.jump_delta < 6: self.jump_delta = 6*2 self.movey -= 33 # how high to jump self.collide_delta += 6 self.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 = x self.rect.y = y self.counter = 0
def move(self): ”’ enemy movement ”’ distance = 80 speed = 8
self.movey += 3.2 if self.counter >= 0 and self.counter <= distance: self.rect.x += speed elif self.counter >= distance and self.counter <= distance*2: self.rect.x -= speed else: self.counter = 0 self.counter += 1
if not self.rect.y >= worldy-ty-ty: self.rect.y += self.movey
plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False) for p in plat_hit_list: self.movey = 0 if self.rect.y > p.rect.y: self.rect.y = p.rect.y+ty else: self.rect.y = p.rect.y-ty
ground_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 enemy enemy_list = pygame.sprite.Group() # create enemy group enemy_list.add(enemy) # add enemy to group if lvl == 2: print(“Level ” + str(lvl) )
return enemy_list
def loot(lvl,tx,ty): if lvl == 1: loot_list = pygame.sprite.Group() loot = Platform(200,ty*7,tx,ty, ‘loot_1.png’) loot_list.add(loot)
if lvl == 2: print(lvl)
return loot_list
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,’ground.png’) ground_list.add(ground) i=i+1
if lvl == 2: print(“Level ” + str(lvl) )
return ground_list
def platform(lvl,tx,ty): plat_list = pygame.sprite.Group() ploc = [] i=0 if lvl == 1: ploc.append((20,worldy-ty-128,3)) ploc.append((300,worldy-ty-256,3)) ploc.append((500,worldy-ty-128,4))
while i < len(ploc): j=0 while j <= ploc[i][2]: plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,’ground.png’) plat_list.add(plat) j=j+1 print(‘run’ + str(i) + str(ploc[i])) i=i+1
if lvl == 2: print(“Level ” + str(lvl) )
return plat_list
”’ Setup ”’ worldx = 960 worldy = 720
fps = 40 # frame rate ani = 4 # animation cycles clock = pygame.time.Clock() pygame.init() main = True
BLUE = (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 player player.rect.x = 0 player.rect.y = 0 player_list = pygame.sprite.Group() player_list.add(player) steps = 10 forwardx = 600 backwardx = 230
eloc = [] eloc = [200,20] gloc = [] #gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630] tx = 64 #tile size ty = 64 #tile size
i=0 while i <= (worldx/tx)+tx: gloc.append(i*tx) i=i+1
enemy_list = Level.bad( 1, eloc ) ground_list = Level.ground( 1,gloc,tx,ty ) plat_list = Level.platform( 1,tx,ty ) loot_list = Level.loot(1,tx,ty)
”’ 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’): 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 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 for l in loot_list: l.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 for l in loot_list: l.rect.x += scroll
world.blit(backdrop, backdropbox) player.gravity() # check gravity player.update() player_list.draw(world) #refresh player position enemy_list.draw(world) # refresh enemies ground_list.draw(world) # refresh enemies plat_list.draw(world) # refresh platforms loot_list.draw(world) # refresh loot
for e in enemy_list: e.move() pygame.display.flip() clock.tick(fps)
via: https://opensource.com/article/20/1/loot-python-platformer-game
作者: Seth Kenlon 選題: lujun9972 譯者: heguangzhi 校對: wxy
本文由 LCTT 原創編譯, Linux中國 榮譽推出
點擊“了解更多”可訪問文內鏈接