使你的 Python 遊戲玩家能夠向前和向後跑
使用 Pygame 模組來使你的 Python 平臺開啟側滾效果,來讓你的玩家自由奔跑。
這是仍在進行中的關於使用 Pygame 模組來在 Python 3 中在建立電腦遊戲的第九部分。先前的文章是:
- 通過構建一個簡單的擲骰子游戲去學習怎麼用 Python 程式設計
- 使用 Python 和 Pygame 模組構建一個遊戲框架
- 如何在你的 Python 遊戲中新增一個玩家
- 用 Pygame 使你的遊戲角色移動起來
- 如何向你的 Python 遊戲中新增一個敵人
- 在 Pygame 遊戲中放置平臺
- 在你的 Python 遊戲中模擬引力
- 為你的 Python 平臺類遊戲新增跳躍功能
在這一系列關於使用 Pygame 模組來在 Python 3 中建立電腦遊戲的先前文章中,你已經設計了你的關卡設計佈局,但是你的關卡的一些部分可能已近超出你的螢幕的可視區域。在平臺類遊戲中,這個問題的普遍解決方案是,像術語“側滾”表明的一樣,滾動。
滾動的關鍵是當玩家精靈接近屏的幕邊緣時,使在玩家精靈周圍的平臺移動。這樣給予一種錯覺,螢幕是一個在遊戲世界中穿梭追拍的攝像機
。
這個滾動技巧需要兩個在螢幕邊緣的絕對區域,在絕對區域內的點處,在世界滾動期間,你的化身靜止不動。
在側滾動條中放置卷軸
如果你希望你的玩家能夠後退,你需要一個觸發點來向前和向後。這兩個點僅僅是兩個變數。設定它們各個距各個螢幕邊緣大約 100 或 200 畫素。在你的設定部分中建立變數。在下面的程式碼中,前兩行用於上下文說明,所以僅需要新增這行後的程式碼:
player_list.add(player)
steps = 10
forwardX = 600
backwardX = 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()
啟動你的遊戲,並嘗試它。
滾動像預期的一樣工作,但是你可能注意到一個發生的小問題,當你滾動你的玩家和非玩家精靈周圍的世界時:敵人精靈不隨同世界滾動。除非你要你的敵人精靈要無休止地追逐你的玩家,你需要修改敵人程式碼,以便當你的玩家快速撤退時,敵人被留在後面。
敵人卷軸
在你的主迴圈中,你必須對卷軸平臺為你的敵人的位置的應用相同的規則。因為你的遊戲世界將(很可能)有不止一個敵人在其中,該規則應該被應用於你的敵人列表,而不是一個單獨的敵人精靈。這是分組類似元素到列表中的優點之一。
前兩行用於上下文註釋,所以只需新增這兩行後面的程式碼到你的主迴圈中:
# 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 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)
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,lloc):
print(lvl)
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((0,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 )
'''
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
# 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
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
for 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
訂閱“Linux 中國”官方小程式來檢視
相關文章
- 遊戲體驗:情緒與情感——你的遊戲能騙到玩家的眼淚嗎?遊戲
- 純靠“刷爆”的動作Roguelike遊戲,能夠吸引你嗎?遊戲
- 只有遊戲夠潤滑,玩家才玩得爽遊戲
- 使Snowflake的客戶能夠通過Snowflake平臺
- 如何介紹你的遊戲,以使玩家覺得遊戲很酷?遊戲
- 用 Pygame 使你的遊戲角色移動起來GAM遊戲
- 遊戲玩家的道德遊戲
- Kotaku:遊戲或許能夠增進人們的友誼遊戲
- 被玩家戲稱“膽子夠肥”的疊紙新遊,何以值得期待?
- 如何在你的 Python 遊戲中新增一個玩家Python遊戲
- APawn類,新增軸對映,使能夠控制APawn移動
- 玩家留存和付費的秘密:遊戲體驗遊戲
- 6G願景和使能技術,邁向可靠且有彈性的系統
- 拳頭遊戲做了個Galgame後,玩家高潮了遊戲GAM
- 遊戲暗示對於遊戲玩家的影響遊戲
- 如何找到能幫你賣貨的遊戲主播? YouTube和Twitch遊戲主播推廣策略(上)遊戲
- 遊戲教會玩家的技能,在工作中也能派上用場?遊戲
- 玩家大量封號、遊戲公司壞賬:遊戲黑卡充值背後的暗黑市場遊戲
- 任天堂的生意經:讓玩家替你打造終生遊戲遊戲
- 面向前端的後端模式(BFF)前端後端模式
- EA:雲技術能讓遊戲行業新增10億玩家遊戲行業
- 2019之後,遊戲能改變世界嗎?遊戲
- 在Roguelike遊戲裡,為什麼賣道具的工具人也能暴打玩家?遊戲
- 遊戲直播“搶跑”元宇宙遊戲元宇宙
- 74%的玩家傾向於雲遊戲採取訂閱制 而非直接購買遊戲
- 手機遊戲玩家遊戲消費的策略選擇遊戲
- Newzoo:221億美元遊戲市場背後的日本玩家:遊戲動機、行為及資料遊戲
- 在遊戲劇情寫作中,如何使你的章節目的達到高潮?遊戲
- 微軟想讓Win10能夠全面相容Xbox One遊戲微軟Win10遊戲
- 你有多愛遊戲,遊戲就有多愛你,聊聊遊戲中的情感寄託和情感表達遊戲
- 04:遊戲主角哪裡跑?終於給遊戲視窗換背景啦#python遊戲程式設計#紅傘傘遊戲Python程式設計
- 遊戲基礎知識——遊戲的“自我賦權”和“非自我賦權”傾向遊戲
- 玩家喜愛、設計師為難,PVP遊戲還能怎麼做好?遊戲
- 除了吸引玩家,直播還能幫助開發者把遊戲做得更好遊戲
- 防沉迷新政下,遊戲廠商喊出聚焦70、80後玩家遊戲
- 搞懂了這套“遊戲付費體系” 還愁沒有玩家為你的遊戲掏錢嗎?遊戲
- Stream Hatchet:2021年遊戲觀眾和玩家報告遊戲
- 今年CJ,“老玩家”帶你探祕遊戲出海七宗最遊戲