利用Pygame制作躲避僵尸游戲
游戲玩法
根據(jù)神廟逃亡,實現(xiàn)一個人躲避僵尸的小游戲,主要的是精靈、精靈組之間相撞、相交的處理。
游戲開始隨機出現(xiàn)一定的僵尸,隨機移動,玩家在一位置上,如果僵尸靠近玩家一定距離,則玩家持續(xù)掉血。玩家通過上下左右移動躲避僵尸,屏幕會隨機刷新一個加血包,玩家吃了就會加一定的血,并在此刷新血包。
property()
這個函數(shù)在類中返回新的屬性
property(get,set,del,doc)
參數(shù)如上所示,get、set、del分別是獲取設值刪除調用的,doc是描述的。
精靈類
在原來的精靈類中添加方向和屬性即可。
class MySprite(pygame.sprite.Sprite):
def __init__(self, target):
pygame.sprite.Sprite.__init__(self)
self.master_image = None
self.frame = 0
self.old_frame = -1
self.frame_width = 1
self.frame_height = 1
self.first_frame = 0
self.last_frame = 0
self.columns = 1
self.last_time = 0
self.direction = 0
self.classification = "玩家"
def load(self, filename, width, height, columns, direction, classification="玩家"):
# 精靈的屬性
self.classification = classification
# 方向
self.direction = direction
# 載入圖片
# 780 * 300
self.master_image = pygame.image.load(filename).convert_alpha() # 載入圖片
self.frame_width = width
self.frame_height = height
self.rect = Rect(0, 0, width, height)
self.columns = columns
rect = self.master_image.get_rect()
self.last_frame = (rect.width // width) * (rect.height // height) - 1
def update(self, current_time, rate=30): # current_time 更新頻率 為30
if current_time > self.last_time + rate: # 如果當前事件 大于 最后的時間 + 當前的節(jié)奏
self.frame += 1 # 當前的幀數(shù)加一
if self.frame > self.last_frame: # 當前最后一幀 則從第一幀開始
self.frame = self.first_frame # 從0開始
self.last_time = current_time # 將最后幀值為30
# build current frame only if it changed
if self.frame != self.old_frame: # 當前幀數(shù)不等于老的一幀
frame_x = (self.frame % self.columns) * self.frame_width
frame_y = (self.frame // self.columns) * self.frame_height
rect = (frame_x, frame_y, self.frame_width, self.frame_height) # 更新對應的位置
self.image = self.master_image.subsurface(rect) # 循環(huán)箱已有的方向
self.old_frame = self.frame
def __str__(self):
return str(self.frame) + "," + str(self.first_frame) + \
"," + str(self.last_frame) + "," + str(self.frame_width) + \
"," + str(self.frame_height) + "," + str(self.columns)
初始畫面
和原來一樣,先建立簡單的畫面。

import mySprite1
import pygame, sys, random
from pygame.locals import *
def print_text(font, x, y, text, color=(255, 255, 255)):
imgText = font.render(text, True, color)
screen.blit(imgText, (x, y))
# 設置窗口
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("勇闖后半夜")
font = pygame.font.Font(None, 30)
timer = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
key = pygame.key.get_pressed()
if key[K_ESCAPE]:
sys.exit()
screen.fill((50, 50, 100))
pygame.display.update()
精靈移動函數(shù)
如果是僵尸遇到墻壁自動反方向走,根據(jù)方向改變對應的位置。
def reversal_direction(mySprite):
direction = mySprite.direction
if direction == 0:
direction = 4
elif direction == 2:
direction = 6
elif direction == 4:
direction = 0
elif direction == 6:
direction = 2
mySprite.direction = direction
def increment(mySprite, offset=1):
# 上下左右
direction = mySprite.direction
rect = mySprite.rect
if direction == 0:
rect.y -= offset
elif direction == 2:
rect.x += offset
elif direction == 4:
rect.y += offset
elif direction == 6:
rect.x -= offset
# 超出邊界的處理
# 超出邊界flg
boundary = False
if rect.x < 0:
rect.x = 0
boundary = True
if rect.x + mySprite.frame_width > 800:
rect.x = 800 - mySprite.frame_width
boundary = True
if rect.y < 0:
rect.y = 0
boundary = True
if rect.y + mySprite.frame_height > 600:
rect.y = 600 - mySprite.frame_height
boundary = True
# 如果超出邊界而且是僵尸的話 則反轉方向
if boundary and mySprite.classification == "僵尸":
reversal_direction(mySprite)
加載玩家
這個是素材的圖,如上所示,奇數(shù)行便是對應的方向移動。文件大小是768 * 768,可以分為96 * 96的8張。

加載玩家
# 玩家
play_group = pygame.sprite.Group()
play = mySprite1()
play.load("farmer walk.png", 96, 96, 8)
play.direction = -1
play_group.rect.x = 96
play_group.rect.y = 96
play_group.add(play)
play_group.update(ticks, 50)
screen.fill((50, 50, 100))
play_group.draw(screen)
pygame.display.update()

通過改變幀數(shù)修改,根據(jù)游戲的結束或是否移動,改變對應的事件
if not game_over:
play.first_frame = play.direction * play.columns
play.last_frame = play.first_frame + play.columns - 1
if play.frame < play.first_frame:
play.frame = play.first_frame
if not play_moving:
play.frame = play.first_frame = play.last_frame
else:
increment(play)
控制交互
if key[K_ESCAPE]:
sys.exit()
elif key[K_UP]:
play.direction = 0
play_moving = True
elif key[K_DOWN]:
play.direction = 4
play_moving = True
elif key[K_LEFT]:
play.direction = 6
play_moving = True
elif key[K_RIGHT]:
play.direction = 2
play_moving = True
else:
play_moving = False
添加僵尸
# 隨機生成20個僵尸
for n in range(0, 10):
zombie = MySprite()
random_direction = random.randint(0, 3) * 2
zombie.load("zombie walk.png", 96, 96, 8, random_direction, "僵尸")
zombie.rect.x = random.randint(0, 600)
zombie.rect.y = random.randint(0, 500)
print(zombie.rect)
zombie_group.add(zombie)
# 設置僵尸
for z in zombie_group:
z.first_frame = z.direction * z.columns
z.last_frame = z.first_frame + z.columns - 1
if z.frame < z.first_frame:
z.frame = z.first_frame
increment(z)

添加血包
血包就是單純的一個圖的展示。
health = MySprite()
health.load("health.png", 32, 32, 1)
health.rect.x = random.randint(0, 600)
health.rect.y = random.randint(0, 500)
health_group.add(health)

精靈相互碰撞事件
主要是僵尸和人 、人和血包之間的相撞事件
# 相撞事件
attack = None
attack = pygame.sprite.spritecollideany(play, zombie_group)
if attack is not None:
if pygame.sprite.collide_rect_ratio(0.5)(play, attack):
play_health -= 10
attack.rect.x = random.randint(0, 600)
attack.rect.y = random.randint(0, 500)
else:
attack = None
if pygame.sprite.collide_rect_ratio(0.5)(play, health):
play_health += 30
if play_health > 100:
play_health = 100
health.rect.x = random.randint(0, 600)
health.rect.y = random.randint(0, 500)
if play_health <= 0:
game_over = True
# 顯示血量
pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 575, 200, 25))
pygame.draw.rect(screen, (50, 150, 150, 180), Rect(300, 575, play_health * 2, 25))
完整代碼
import pygame, sys, random
from pygame.locals import *
from mySprite1 import *
def print_text(font, x, y, text, color=(255, 255, 255)):
imgText = font.render(text, True, color)
screen.blit(imgText, (x, y))
def reversal_direction(mySprite):
direction = mySprite.direction
if direction == 0:
direction = 4
elif direction == 2:
direction = 6
elif direction == 4:
direction = 0
elif direction == 6:
direction = 2
mySprite.direction = direction
def increment(mySprite, offset=1):
# 上下左右
direction = mySprite.direction
rect = mySprite.rect
if direction == 0:
rect.y -= offset
elif direction == 2:
rect.x += offset
elif direction == 4:
rect.y += offset
elif direction == 6:
rect.x -= offset
# 超出邊界的處理
# 超出邊界flg
boundary = False
if rect.x < 0:
rect.x = 0
boundary = True
if rect.x + mySprite.frame_width > 800:
rect.x = 800 - mySprite.frame_width
boundary = True
if rect.y < 0:
rect.y = 0
boundary = True
if rect.y + mySprite.frame_height > 600:
rect.y = 600 - mySprite.frame_height
boundary = True
# 如果超出邊界而且是僵尸的話 則反轉方向
if boundary and mySprite.classification == "僵尸":
reversal_direction(mySprite)
# 設置窗口
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("勇闖后半夜")
font = pygame.font.Font(None, 30)
timer = pygame.time.Clock()
game_over = False
# 玩家
play_group = pygame.sprite.Group()
play = MySprite()
play.load("farmer walk.png", 96, 96, 8, 4)
play.rect.x = 96
play.rect.y = 96
play_moving = False
play_group.add(play)
play_health = 100
# 僵尸
zombie_group = pygame.sprite.Group()
# 隨機生成20個僵尸
for n in range(0, 10):
zombie = MySprite()
random_direction = random.randint(0, 3) * 2
zombie.load("zombie walk.png", 96, 96, 8, random_direction, "僵尸")
zombie.rect.x = random.randint(0, 600)
zombie.rect.y = random.randint(0, 500)
print(zombie.rect)
zombie_group.add(zombie)
# 血包
health_group = pygame.sprite.Group()
health = MySprite()
health.load("health.png", 32, 32, 1)
health.rect.x = random.randint(0, 600)
health.rect.y = random.randint(0, 500)
health_group.add(health)
while True:
# 設置執(zhí)行的頻率
timer.tick(30)
ticks = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
key = pygame.key.get_pressed()
if key[K_ESCAPE]:
sys.exit()
elif key[K_UP]:
play.direction = 0
play_moving = True
elif key[K_DOWN]:
play.direction = 4
play_moving = True
elif key[K_LEFT]:
play.direction = 6
play_moving = True
elif key[K_RIGHT]:
play.direction = 2
play_moving = True
else:
play_moving = False
if not game_over:
# 設置玩家
play.first_frame = play.direction * play.columns
play.last_frame = play.first_frame + play.columns - 1
if play.frame < play.first_frame:
play.frame = play.first_frame
# 設置僵尸
for z in zombie_group:
z.first_frame = z.direction * z.columns
z.last_frame = z.first_frame + z.columns - 1
if z.frame < z.first_frame:
z.frame = z.first_frame
increment(z)
if not play_moving:
play.frame = play.first_frame = play.last_frame
else:
increment(play)
# 相撞事件
attack = None
attack = pygame.sprite.spritecollideany(play, zombie_group)
if attack is not None:
if pygame.sprite.collide_rect_ratio(0.5)(play, attack):
play_health -= 10
attack.rect.x = random.randint(0, 600)
attack.rect.y = random.randint(0, 500)
else:
attack = None
if pygame.sprite.collide_rect_ratio(0.5)(play, health):
play_health += 30
if play_health > 100:
play_health = 100
health.rect.x = random.randint(0, 600)
health.rect.y = random.randint(0, 500)
if play_health <= 0:
game_over = True
play_group.update(ticks, 50)
zombie_group.update(ticks, 50)
health_group.update(ticks, 50)
screen.fill((50, 50, 100))
play_group.draw(screen)
zombie_group.draw(screen)
health_group.draw(screen)
# 顯示血量
pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 575, 200, 25))
pygame.draw.rect(screen, (50, 150, 150, 180), Rect(300, 575, play_health * 2, 25))
if game_over:
print_text(font, 300, 100, "GAME OVER!!!")
pygame.display.update()
到此這篇關于利用Pygame制作躲避僵尸游戲的文章就介紹到這了,更多相關Pygame躲避僵尸游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Pycharm中python調用另一個文件類或者函數(shù)
本文主要介紹了Pycharm中python調用另一個文件類或者函數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
使用setup.py安裝python包和卸載python包的方法
這篇文章主要介紹了使用setup.py安裝python包和卸載python包的方法,大家參考使用吧2013-11-11
Python人工智能學習PyTorch實現(xiàn)WGAN示例詳解
這篇文章主要為大家介紹了人工智能學習PyTorch實現(xiàn)WGAN的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2021-11-11
Python數(shù)據(jù)結構棧實現(xiàn)進制轉換簡單示例
眾所周知計算機的內(nèi)存都是以二進制的形式進行數(shù)據(jù)存儲,下面這篇文章主要給大家介紹了關于Python數(shù)據(jù)結構棧實現(xiàn)進制轉換的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2023-02-02

