游戏玩法

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

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

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

利用Pygame制作躲避僵尸游戏的更多相关文章

  1. jQuery实现简单的抽奖游戏

    这篇文章主要为大家详细介绍了jQuery实现简单的抽奖游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  3. Java实现空指针后的猜拳游戏

    “java.lang.NullPointerException” 空指针异常可以说是Java程序最容易出现的异常了,小编写了一个 IDEA 插件,每当程序出现空指针异常时就会弹出一个“猜拳游戏”窗口,该窗口不能直接关闭,只有当你游戏获胜时,窗口才会自动关闭

  4. 基于Python自制视觉桌上冰球小游戏

    这篇文章主要和大家分享一下如何使用 mediapipe+opencv 制作桌上冰球的交互式小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

  5. Python Pygame实战之趣味篮球游戏的实现

    这篇文章主要为大家分享了一个基于Python和Pygame实现的一个趣味篮球游戏,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下

  6. Vue+TailWindcss实现一个简单的闯关小游戏

    本文将利用Vue+TailWindcss实现一个简单的闯关小游戏,玩家须躲避敌人与陷阱到达终点且拥有多个关卡,感兴趣的小伙伴可以了解一下

  7. Python pygame 项目实战事件监听

    这篇文章主要介绍了Python pygame 项目实战事件监听,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

  8. Android 实现抖音小游戏潜艇大挑战的思路详解

    《潜水艇大挑战》是抖音上的一款小游戏,最近特别火爆,很多小伙伴都玩过。接下来通过本文给大家分享Android 手撸抖音小游戏潜艇大挑战的思路,需要的朋友可以参考下

  9. 教你使用python做一个“罚点球”小游戏

    这篇文章主要介绍了用python做一个“罚点球”小游戏,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  10. 基于Python编写一个中秋节嫦娥投食小游戏

    今天给大家带来的是给玉兔投喂月饼的小游戏。八月十五中秋夜晚,让我们对着月亮许愿:希望我们在意和在意我们的人,诸邪避退、百事无忌、平安喜乐、万事胜意。提前祝大家中秋节快乐

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部