脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - 利用Pygame制作躲避僵尸游戏

利用Pygame制作躲避僵尸游戏

2023-02-20 13:40我的天才女友 Python

本文参考了神庙逃亡,利用Pygame实现一个人躲避僵尸的小游戏,主要的是精灵、精灵组之间相撞、相交的处理,感兴趣的可以了解一下

游戏玩法

根据神庙逃亡,实现一个人躲避僵尸的小游戏,主要的是精灵、精灵组之间相撞、相交的处理。

游戏开始随机出现一定的僵尸,随机移动,玩家在一位置上,如果僵尸靠近玩家一定距离,则玩家持续掉血。玩家通过上下左右移动躲避僵尸,屏幕会随机刷新一个加血包,玩家吃了就会加一定的血,并在此刷新血包。

 

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)

 

初始画面

和原来一样,先建立简单的画面。

利用Pygame制作躲避僵尸游戏

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张。

利用Pygame制作躲避僵尸游戏

加载玩家

# 玩家
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()

利用Pygame制作躲避僵尸游戏

通过改变帧数修改,根据游戏的结束或是否移动,改变对应的事件

    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)

利用Pygame制作躲避僵尸游戏

 

添加血包

血包就是单纯的一个图的展示。

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)

利用Pygame制作躲避僵尸游戏

 

精灵相互碰撞事件

主要是僵尸和人 、人和血包之间的相撞事件

    # 相撞事件
  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躲避僵尸游戏内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_40801987/article/details/124995037

延伸 · 阅读

精彩推荐
  • PythonPython使用pickle模块储存对象操作示例

    Python使用pickle模块储存对象操作示例

    这篇文章主要介绍了Python使用pickle模块储存对象操作,结合实例形式分析了Python使用pickle模块针对文件读写与转换的相关操作技巧,需要的朋友可以参考下...

    bbtl_ast7262021-03-28
  • Python浅谈Python2、Python3相对路径、绝对路径导入方法

    浅谈Python2、Python3相对路径、绝对路径导入方法

    今天小编就为大家分享一篇浅谈Python2、Python3相对路径、绝对路径导入方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    ShellCollector6932021-03-08
  • Pythonpython使用PyGame模块播放声音的方法

    python使用PyGame模块播放声音的方法

    这篇文章主要介绍了python使用PyGame模块播放声音的方法,实例分析了PyGame模块的使用技巧,需要的朋友可以参考下...

    igoo9782020-07-03
  • Python浅析Python3爬虫登录模拟

    浅析Python3爬虫登录模拟

    本篇文章通过学习python爬虫相关知识点来分析Python3爬虫登录模拟的原理以及相关代码分析,对此有兴趣的朋友参考下。...

    WhiteBlackCat4182021-01-12
  • Pythonpython 全角半角互换的实现示例

    python 全角半角互换的实现示例

    全角、半角的的不一致会导致信息抽取不一致,本文主要介绍了python 全角半角互换的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作...

    王大呀呀7892022-11-16
  • Python浅谈python 类方法/静态方法

    浅谈python 类方法/静态方法

    这篇文章主要介绍了python 类方法/静态方法的相关资料,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下...

    聂发俊7832020-09-18
  • Pythonpython 爬取国内小说网站

    python 爬取国内小说网站

    国内小说网站的结构,大概都如出一辙,改改地址,就差不多了,有此需求的朋友可以参考下本文的爬虫写法...

    勤劳上班的卑微小张11922021-11-25
  • Pythonpython for循环如何实现控制步长

    python for循环如何实现控制步长

    这篇文章主要介绍了python for循环如何实现控制步长,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    星之所望5002022-12-24