游戏玩法
根据神庙逃亡,实现一个人躲避僵尸的小游戏,主要的是精灵、精灵组之间相撞、相交的处理。
游戏开始随机出现一定的僵尸,随机移动,玩家在一位置上,如果僵尸靠近玩家一定距离,则玩家持续掉血。玩家通过上下左右移动躲避僵尸,屏幕会随机刷新一个加血包,玩家吃了就会加一定的血,并在此刷新血包。
property()
这个函数在类中返回新的属性
- property(get,set,del,doc)
参数如上所示,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: # 如果当前事件 大于 最后的时间 + 当前的节奏
- self.frame += 1 # 当前的帧数加一
- 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: # 当前帧数不等于老的一帧
- 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) # 循环箱已有的方向
- 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()
-
精灵移动函数
如果是僵尸遇到墙壁自动反方向走,根据方向改变对应的位置。
- 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)
加载玩家
这个是素材的图,如上所示,奇数行便是对应的方向移动。文件大小是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()

通过改变帧数修改,根据游戏的结束或是否移动,改变对应的事件
- 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:
- # 设置执行的频率
- 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躲避僵尸游戏内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!