python小游戏——散刺修罗场

这是一个为了给逍遥散人庆生做的python小游戏!

    • 前言
    • 正文
      • 动画演示
      • 动画的实现(假)
      • 规范参数
      • 实现附加功能
        • 多种怪兽类型随机出现
        • 按R重来
        • 彩蛋部分——boss出场
    • 源代码
        • 这是没有彩蛋部分的代码
        • 这是有boss彩蛋的代码

python小游戏——散刺修罗场_第1张图片

前言

用的大佬的源代码,用了三天时间稍加改动。之前博主没有接触过任何pygame做游戏的方面,python也只会用海龟画图,其他只会一些c和java,是真的小白!!

在这里放出原大佬的链接,陈泽光的回答:乞丐子大战骑士
上面已经对代码进行了详细的讲解,下面我就只记录我改动的部分和一些收获

正文

动画演示

【散人生贺】我做了一个小游戏给散老师!

动画的实现(假)

很抱歉我最后还是没有实现动画,原主说乞丐子是用的三个一样的图片,只要换掉另外两张就能实现动画效果。类似精灵序列?但是我没有原主的素材自己也不知道具体是什么样的所以就把乞丐子的动图效果改掉了,用的是就是注释了Begger类中的如下两行,换成了一张单独的图片,而不是序列图片

之后我也尝试了用精灵序列,但是基础还是太差了,时间上也来不及(因为从开始做游戏到使用只有3天时间)

class Begger(object):
    #类初始化
    def __init__(self, img, rect, speed):
        # self.ful_img = img
        # self.imgs = [self.ful_img.subsurface(Rect((i*83, 0), (begger_width/3, begger_height)))
        #              for i in range(3)]
        self.imgs = img
        self.rect = rect
        self.speed = speed
        self.num = 0

规范参数

在原主的代码里有部分参数直接写在了代码核心区,设置成了定值,我基本都在基础设置的初始化区或者是新一局游戏的开局设置区做了起名

    # 1.2 - 基础设置区---------------------------------------------
    pygame.init()
    # 初始化

 # 2.2 - 游戏进行区---------------------------------------------
    while 1:
        # 2.2.0游戏开局设置区---------------------------------
        # 初始化kid的移动速度和初始位置

实现附加功能

多种怪兽类型随机出现

这里先用了一个暂时的怪兽矩形,先判断暂时怪兽所在矩形范围是否与前面生成的所有怪兽矩形重合,如果重合则不添加到怪兽列表中,不重合则添加到列表中
这里我给怪兽做了很多属性设定:img、ret、type、width、height。其实后来写完了回过头发现是可以用怪兽类解决的,就不用这里这么麻烦的从这个列表跳到另一个列表

   # 设置怪兽
            # 此处生成0~monster_pro_speed-1的随机数,若生成0则产生一个新的monster,用以控制monster的生成速度
            monster_timer = random.choice(range(monster_pro_speed))
            if play_time > 2 and monster_timer < 1:
                # 确定怪兽种类
                monster_type_temp = random.randint(0, monster_type_num-1)
                monster_img_temp = monsters_img[monster_type_temp]
                monster_width_temp = monsters_width[monster_type_temp]
                monster_height_temp = monsters_height[monster_type_temp]
                monster_temp = [screen_width,
                                 random.randint(monster_height_temp, screen_height - monster_height_temp)]
                                 # random.randint产生区间范围内的随机整数
                monster_temp_rect = pygame.Rect(monsters_img[monster_type_temp].get_rect())
                monster_temp_rect.left = monster_temp[0]
                monster_temp_rect.top = monster_temp[1]

                # 第一只怪兽直接显示
                if len(monsters) == 0:
                    monster_type = monster_type_temp
                    monster_img = monster_img_temp
                    monster_width = monster_width_temp
                    monster_height = monster_height_temp

                    monsters.append(monster_temp)
                    list_monster_type.append(monster_type)
                else:
                    for monster in monsters:
                        monster_type = list_monster_type[monsters.index(monster)]
                        monster_rect = pygame.Rect(monsters_img[monster_type].get_rect())
                        monster_rect.left = monster[0]
                        monster_rect.top = monster[1]
                        # 如果两个monster交叉,则临时的怪兽不存入monsters列表
                        if monster_temp_rect.colliderect(monster_rect):
                            break
                        else:
                            # 如果到达了最后一个monster
                            if monsters.index(monster) == len(monsters)-1:
                                monster_type = monster_type_temp
                                monster_img = monster_img_temp
                                monster_width = monster_width_temp
                                monster_height = monster_height_temp
                                # 将有效的临时怪兽添加至monsters列表
                                monsters.append(monster_temp)
                                list_monster_type.append(monster_type)

            # 显示怪兽
            for monster in monsters:
                monsters_type = list_monster_type[monsters.index(monster)]
                screen.blit(monsters_img[monsters_type], monster)

按R重来

之前的游戏胜利或失败了就只能退出游戏重新进,这里将游戏进行区和游戏结束区写进了一个while循环实现R重来


    # 2.2 - 游戏进行区---------------------------------------------
    while 1:

在原代码最后加上

            # 按r重来
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == K_r:
                        start = 1
                        running = 1
                        start_time = datetime.datetime.now()

彩蛋部分——boss出场

这一段在原游戏胜利的基础上增加了几秒钟出现了一个moster_boss,这个boss是打不死的,只是运动到墙的位置就直接跳转到胜利界面。
这一段代码写的有点糟糕,大部分都是之前重复的代码,直接在游戏成功的部分写了一遍人物运动、怪兽运动、子弹命中、游戏操作这些部分。这个功能的实现在游戏层面上基本没有意义,只是作为散人生贺视频的彩蛋环节
因为代码重复过多,这里只放了彩蛋部分的开头和结尾

            # 坚持指定时间
            # if pygame.time.get_ticks() >= fin_time * 1000:
            if play_time >= fin_time:
                # running = 0
                win = 1
                # 3 monster_boss彩蛋部分---------------------------------------------
                while 1:
                    # 3.1 - 彩蛋显示区-----------------------------------
                    screen.fill(white)
                    screen.blit(paper, (0, 0))

                    # 显示城墙
                    # 判断血量少于75则刺儿受伤
 
                    # boss到达刺儿位置则胜利
                    if monster_boss_rect.left < (wall_width + distance):
                        running = 0
                        break

——————————————————————————————————————————————————————

源代码

这是没有彩蛋部分的代码

# 0 - 模块区
import os
import sys
import math
import random
import pygame
import datetime
from pygame.locals import *
import time

class Begger(object):
    #类初始化
    def __init__(self, img, rect, speed):
        # self.ful_img = img
        # self.imgs = [self.ful_img.subsurface(Rect((i*83, 0), (begger_width/3, begger_height)))
        #              for i in range(3)]
        self.imgs = img
        self.rect = rect
        self.speed = speed
        self.num = 0

    # 用wasd控制kid移动
    def update(self, screen, press_keys):
        if press_keys[K_a]:
            self.rect.left -= self.speed
            # 限制左边界
            if self.rect.left <= 0:
                self.rect.left = 0
        if press_keys[K_d]:
            self.rect.left += self.speed
            # 限制右边界
            if self.rect.right >= 200:
                self.rect.right = 200
        if press_keys[K_w]:
            self.rect.top -= self.speed
            # 限制上边界
            if self.rect.top <= 0:
                  self.rect.top = 0
        if press_keys[K_s]:
            self.rect.top += self.speed
            # 限制下边界
            if self.rect.bottom >= 640:
                  self.rect.bottom = 640

        #??
        # self.num += 1
        # if self.num % 3 == 0:
        #     self.num = 0
        return [(self.rect.left + self.rect.right)/2, (self.rect.top + self.rect.bottom)/2], self.imgs


# 主要的工作区域
if __name__ == '__main__':

    # 1 - 设置区-------------------------------------------------------------
    # 1.1 - 窗口设置区---------------------------------------------
    white = (255, 255, 255)
    screen_width, screen_height = 1024, 600
    os.environ['SDL_VIDEO_CENTERED'] = '1'
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Pas_Game")

    # 1.2 - 基础设置区---------------------------------------------
    pygame.init()

    start = 0
    win = 0
    running = 0

    # 200里外建造城墙
    distance = 200

    # 健康值初始化,设置健康值最大值
    health_value_max = 194

    # 设置结束时间,获取当前时间
    fin_time = 20
    start_time = datetime.datetime.now()

    # 初始化kid的移动速度和初始位置
    bg_speed = 2

    # 初始化怪兽的前进速度、产生速度
    monster_speed = 1
    monster_pro_speed = 150

    # 子弹速度为1.5,限制最多存在4个子弹
    wave_speed = 1.5
    wave_max = 7

    # 1.3游戏图片加载---------------------------------------------
    # 游戏素材地址
    fig_path = r'D:\PycharmProjects\untitled1\resources\images/'

    # 读背景图片
    paper = pygame.image.load(fig_path + 'paper.png').convert_alpha()

    # 完整的刺儿
    wall = pygame.image.load(fig_path + 'wall.png').convert_alpha()
    wall_width = wall.get_width()
    wall_height = wall.get_height()

    # 受伤的刺儿
    wall_cry = pygame.image.load(fig_path + 'walls.png').convert_alpha()
    wall_cry_width = wall_cry.get_width()
    wall_cry_height = wall_cry.get_height()

    # kid
    begger = pygame.image.load(fig_path + 'kid.png').convert_alpha()
    begger_width = begger.get_width()
    begger_height = begger.get_height()

    # 子弹
    sub_wave = pygame.image.load(fig_path + 'waves.png').convert_alpha()
    # 能量波随时间渐弱
    # sub_wave = waves.subsurface(Rect((0, 0), (waves.get_width() / 5, waves.get_height())))
    sub_wave_width = sub_wave.get_width()
    sub_wave_height = sub_wave.get_height()

    # 怪兽
    monster1_img = pygame.image.load(fig_path + 'monster1.png').convert_alpha()
    monster1_width = monster1_img.get_width()
    monster1_height = monster1_img.get_height()
    monster2_img = pygame.image.load(fig_path + 'monster2.png').convert_alpha()
    monster2_width = monster2_img.get_width()
    monster2_height = monster2_img.get_height()
    monster3_img = pygame.image.load(fig_path + 'monster3.png').convert_alpha()
    monster3_width = monster3_img.get_width()
    monster3_height = monster3_img.get_height()
    monster4_img = pygame.image.load(fig_path + 'monster4.png').convert_alpha()
    monster4_width = monster4_img.get_width()
    monster4_height = monster4_img.get_height()
    monster5_img = pygame.image.load(fig_path + 'monster5.png').convert_alpha()
    monster5_width = monster5_img.get_width()
    monster5_height = monster5_img.get_height()
    monster6_img = pygame.image.load(fig_path + 'monster6.png').convert_alpha()
    monster6_width = monster6_img.get_width()
    monster6_height = monster6_img.get_height()

    monsters_img = [monster1_img, monster2_img, monster3_img, monster4_img, monster5_img, monster6_img]
    monsters_width = [monster1_width, monster2_width, monster3_width, monster4_width, monster5_width, monster6_width]
    monsters_height =[monster1_height, monster2_height, monster3_height, monster4_height, monster5_height, monster6_height]
    monster_type_num = len(monsters_img)

    # 血条
    health_bar_img = pygame.image.load(fig_path + "health_bar.png")
    health_bar_height = health_bar_img.get_height()
    health_imgs = pygame.image.load(fig_path + "health.png")
    health_img = health_imgs
    health_height = health_img.get_height()

    # 游戏胜利与游戏结束图片
    victory = pygame.image.load(fig_path + 'victory.png')
    game_over = pygame.image.load(fig_path + 'game_over.png')
    game_over_width = game_over.get_width()
    game_over_height = game_over.get_height()

    # 游戏开始封面
    start_img = pygame.image.load(fig_path + 'start.png').convert_alpha()


    # 2 - 游戏区--------------------------------------------------------------
    # 游戏开始
    while not start:
        screen.fill(white)
        screen.blit(start_img, (0, 0))

        pygame.font.init()
        # pygame.font.Font选择字体样式和大小
        font = pygame.font.Font(None, 40)
        # font.render显示文本内容,是否开启抗锯齿(即是否光滑),文本颜色
        text = font.render("Press Space to Start !",
                           True, (255,251,240)) # 乳白色
        text_Rect = text.get_rect()
        text_Rect.centerx = screen.get_rect().centerx
        text_Rect.centery = screen.get_rect().centery + 250
        screen.blit(text, text_Rect)

        pygame.display.flip()

        # 获取键盘事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == K_SPACE:
                    start = 1
                    running = 1
                    # 背景音乐
                    # pygame.mixer.music.load(fig_path + "Checkpoint.mp3")
                    # pygame.mixer.music.play(1, 0.0)
                    # pygame.mixer.music.set_volume(0.15)
                    start_time = datetime.datetime.now()

    # 2.2 - 游戏进行区---------------------------------------------
    while 1:
        # 2.2.0游戏开局设置区---------------------------------
        # 初始化kid的移动速度和初始位置
        rect_bg = Rect(50, 50, 133, 142)
        begger_pos = []
        # 建立一个新的Begger类对象
        bg = Begger(begger, rect_bg, bg_speed)

        # 初始化怪兽的位置
        monsters = []
        list_monster_type = []
        # 这里的type列表用来存放新生成怪兽的类型,我觉得其实可以和位置合并为同一个变量,类似c的结构体但是我不会

        # 初始化子弹位置
        wave_set = []

        # 初始化血量
        health_value = health_value_max
        health_img = health_imgs

        while running:
            # 2.2.1 - 游戏显示区-------------------------------
            screen.fill(white)
            screen.blit(paper, (0, 0))

            # 显示城墙
            # 判断血量少于75则刺儿受伤
            if health_value <= 75:
                for height in range(0, screen_height, wall_cry_height):
                    screen.blit(wall_cry, (distance, height))
            else:
                for height in range(0, screen_height, wall_height):
                    screen.blit(wall, (distance, height))

            # kid随鼠标移动而旋转
            press_keys = pygame.key.get_pressed()
            begger_pos, begger_img = bg.update(screen, press_keys)

            position = pygame.mouse.get_pos()
            angle = math.atan2(position[1] - (begger_pos[1] + begger_height),
                               position[0] - (begger_pos[0] + begger_width))
            begger_rot = pygame.transform.rotate(begger_img, 360 - angle * 57.29)
            begger_pos1 = (begger_pos[0] - begger_rot.get_rect().width / 2,
                           begger_pos[1] - begger_rot.get_rect().height / 2)
            screen.blit(begger_rot, begger_pos1)

            # 设置子弹
            for wave in wave_set:
                index = 0
                vel_x = math.cos(wave[0]) * wave_speed
                vel_y = math.sin(wave[0]) * wave_speed
                wave[1] += vel_x
                wave[2] += vel_y
                if wave[1] < - sub_wave_width or wave[1] > screen_width \
                        or wave[2] < - sub_wave_height or wave[2] > screen_height:
                    wave_set.pop(index) # pop移除列表index位置的对象
                index += 1

                for projectile in wave_set:
                    # wave1 = pygame.transform.rotate(sub_wave, 360 - projectile[0] * 57.29)
                    # .rotate(surface, angle)返回一个旋转后的surface对象,默认逆时针旋转,angle小于0时则顺时针, 此处子弹素材为中心对称可不旋转
                    screen.blit(sub_wave, (projectile[1], projectile[2]))

            # 设置怪兽
            # 此处生成0~monster_pro_speed-1的随机数,若生成0则产生一个新的monster,用以控制monster的生成速度
            monster_timer = random.choice(range(monster_pro_speed))
            if monster_timer < 1:

                # 确定怪兽种类
                monster_type_temp = random.randint(0, monster_type_num-1)
                monster_img_temp = monsters_img[monster_type_temp]
                monster_width_temp = monsters_width[monster_type_temp]
                monster_height_temp = monsters_height[monster_type_temp]
                monster_temp = [screen_width,
                                 random.randint(monster_height_temp, screen_height - monster_height_temp)]
                                 # random.randint产生区间范围内的随机整数
                monster_temp_rect = pygame.Rect(monsters_img[monster_type_temp].get_rect())
                monster_temp_rect.left = monster_temp[0]
                monster_temp_rect.top = monster_temp[1]

                # 第一只怪兽直接显示
                if len(monsters) == 0:
                    monster_type = monster_type_temp
                    monster_img = monster_img_temp
                    monster_width = monster_width_temp
                    monster_height = monster_height_temp

                    monsters.append(monster_temp)
                    list_monster_type.append(monster_type)
                else:
                    for monster in monsters:
                        monster_type = list_monster_type[monsters.index(monster)]
                        monster_rect = pygame.Rect(monsters_img[monster_type].get_rect())
                        monster_rect.left = monster[0]
                        monster_rect.top = monster[1]
                        # 如果两个monster交叉,则临时的怪兽不存入monsters列表
                        if monster_temp_rect.colliderect(monster_rect):
                            break
                        else:
                            # 如果到达了最后一个monster
                            if monsters.index(monster) == len(monsters)-1:
                                monster_type = monster_type_temp
                                monster_img = monster_img_temp
                                monster_width = monster_width_temp
                                monster_height = monster_height_temp
                                # 将有效的临时怪兽添加至monsters列表
                                monsters.append(monster_temp)
                                list_monster_type.append(monster_type)

            # 显示怪兽
            for monster in monsters:
                monsters_type = list_monster_type[monsters.index(monster)]
                screen.blit(monsters_img[monsters_type], monster)

            index = 0

            # 如果子弹碰到苹果则打击成功,如果苹果接触到刺儿测扣除自身20-40健康值
            for monster in monsters:
                monsters_type = list_monster_type[monsters.index(monster)]
                if monster[0] < - monsters_width[monsters_type]:
                    monsters.pop(index)
                    list_monster_type.pop(index)
                # 怪兽移动
                monster[0] -= monster_speed
                monster_rect = pygame.Rect(monsters_img[monsters_type].get_rect())
                monster_rect.top = monster[1]
                monster_rect.left = monster[0]
                # 怪兽到达刺儿位置则扣除血条20-40
                if monster_rect.left < wall_width + distance:
                    health_value -= random.randint(20, 40)
                    monsters.pop(index)
                    list_monster_type.pop(index)
                index1 = 0
                for wave in wave_set:
                    wave_rect = pygame.Rect(sub_wave.get_rect())
                    wave_rect.left = wave[1]
                    wave_rect.top = wave[2]
                    # 检查怪兽和子弹两个矩形块是否交叉,交叉则移除两个矩形块
                    if monster_rect.colliderect(wave_rect):
                        wave_set.pop(index1)
                        try:
                            monsters.pop(index)
                            list_monster_type.pop(index)
                        except IndexError as error:
                            print("IndexError: " + str(error))
                    index1 += 1
                index += 1

            # 血条和时间显示
            font = pygame.font.Font(None, 42)
            cur_time = datetime.datetime.now()
            play_time = (cur_time - start_time).seconds
            # 时间显示
            if play_time % 60 < 10:
                time_str = ":0"
            else:
                time_str = ":"
            survived_text = font.render(
                str(play_time // 60) +
                time_str +
                str(play_time % 60),
                True, (0, 0, 0)
            )
            text_Rect = survived_text.get_rect()
            text_Rect.topright = [screen_width - 5, 5]
            screen.blit(survived_text, text_Rect)

            # 设置血条框的位置
            health_bar_img = pygame.transform.scale(health_bar_img,
                                                    (health_value_max+2, health_bar_height))
            screen.blit(health_bar_img, [0, 5])

            # 设置血条的位置
            if health_value < 0:
                health_value = 0
            health_img = pygame.transform.scale(health_img,
                                                (health_value, health_height))
            screen.blit(health_img, [1, 7])

            pygame.display.flip()
            #
            # 2.2.2 - 游戏操作区---------------------------
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                # 发射子弹
                if event.type == pygame.MOUSEBUTTONDOWN and len(wave_set) < wave_max:
                    position = pygame.mouse.get_pos()
                    wave_set.append([math.atan2(position[1] - (begger_pos1[1] + begger_height/2 + begger_height),
                                                position[0] - (begger_pos1[0] + begger_width + begger_width)),
                                     begger_pos1[0] + begger_width, begger_pos1[1] + begger_height/2])

            # if pygame.time.get_ticks() >= fin_time * 1000:
            if play_time >= fin_time:
                running = 0
                win = 1
            if health_value == 0:
                running = 0
                win = 0

        # 游戏结束成功或失败
        while not running and start:
            pygame.mixer.music.stop()
            if win:
                screen.blit(victory, (0, 0))
                pygame.font.init()
                font = pygame.font.Font(None, 84)
                text = font.render("Victory !",
                                   True, (250, 50, 200))
                text_Rect = text.get_rect()
                text_Rect.centerx = screen.get_rect().centerx + 20
                text_Rect.centery = screen.get_rect().centery - 250
                screen.blit(text, text_Rect)
            if not win:
                screen.blit(game_over, ((screen_width-game_over_width)/2, (screen_height-game_over_height)/2))

            pygame.display.flip()

            # 按r重来
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == K_r:
                        start = 1
                        running = 1
                        start_time = datetime.datetime.now()

这是有boss彩蛋的代码

# 0 - 模块区
import os
import sys
import math
import random
import pygame
import datetime
from pygame.locals import *
import time

class Begger(object):
    #类初始化
    def __init__(self, img, rect, speed):
        # self.ful_img = img
        # self.imgs = [self.ful_img.subsurface(Rect((i*83, 0), (begger_width/3, begger_height)))
        #              for i in range(3)]
        self.imgs = img
        self.rect = rect
        self.speed = speed
        self.num = 0

    # 用wasd控制kid移动
    def update(self, screen, press_keys):
        if press_keys[K_a]:
            self.rect.left -= self.speed
            # 限制左边界
            if self.rect.left <= 0:
                self.rect.left = 0
        if press_keys[K_d]:
            self.rect.left += self.speed
            # 限制右边界
            if self.rect.right >= 200:
                self.rect.right = 200
        if press_keys[K_w]:
            self.rect.top -= self.speed
            # 限制上边界
            if self.rect.top <= 0:
                  self.rect.top = 0
        if press_keys[K_s]:
            self.rect.top += self.speed
            # 限制下边界
            if self.rect.bottom >= 640:
                  self.rect.bottom = 640

        #??
        # self.num += 1
        # if self.num % 3 == 0:
        #     self.num = 0
        return [(self.rect.left + self.rect.right)/2, (self.rect.top + self.rect.bottom)/2], self.imgs


# 主要的工作区域
if __name__ == '__main__':

    # 1 - 设置区-------------------------------------------------------------
    # 1.1 - 窗口设置区---------------------------------------------
    white = (255, 255, 255)
    screen_width, screen_height = 1024, 600
    os.environ['SDL_VIDEO_CENTERED'] = '1'
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Pas_Game")

    # 1.2 - 基础设置区---------------------------------------------
    pygame.init()
    # 初始化
    start = 0
    win = 0
    running = 0

    # 200里外建造城墙
    distance = 200

    # 健康值初始化,设置健康值最大值
    health_value_max = 194

    # 设置结束时间,获取当前时间
    fin_time = 20
    start_time = datetime.datetime.now()

    # 初始化kid的移动速度和初始位置
    bg_speed = 2

    # 初始化怪兽的前进速度、产生速度(越小越快)
    monster_speed = 1.3
    monster_pro_speed = 120

    # 子弹速度为1.5,限制最多存在7个子弹
    wave_speed = 1.5
    wave_max = 7

    # 1.3游戏图片加载---------------------------------------------
    # 游戏素材地址
    fig_path = r'D:\PycharmProjects\untitled1\resources\images/'

    # 读背景图片
    paper = pygame.image.load(fig_path + 'paper.png').convert_alpha()

    # 完整的刺儿
    wall = pygame.image.load(fig_path + 'wall.png').convert_alpha()
    wall_width = wall.get_width()
    wall_height = wall.get_height()

    # 受伤的刺儿
    wall_cry = pygame.image.load(fig_path + 'walls.png').convert_alpha()
    wall_cry_width = wall_cry.get_width()
    wall_cry_height = wall_cry.get_height()

    # kid
    begger = pygame.image.load(fig_path + 'kid.png').convert_alpha()
    begger_width = begger.get_width()
    begger_height = begger.get_height()

    # 子弹
    sub_wave = pygame.image.load(fig_path + 'waves.png').convert_alpha()
    # 能量波随时间渐弱
    # sub_wave = waves.subsurface(Rect((0, 0), (waves.get_width() / 5, waves.get_height())))
    sub_wave_width = sub_wave.get_width()
    sub_wave_height = sub_wave.get_height()

    # 怪兽
    monster1_img = pygame.image.load(fig_path + 'monster1.png').convert_alpha()
    monster1_width = monster1_img.get_width()
    monster1_height = monster1_img.get_height()
    monster2_img = pygame.image.load(fig_path + 'monster2.png').convert_alpha()
    monster2_width = monster2_img.get_width()
    monster2_height = monster2_img.get_height()
    monster3_img = pygame.image.load(fig_path + 'monster3.png').convert_alpha()
    monster3_width = monster3_img.get_width()
    monster3_height = monster3_img.get_height()
    monster4_img = pygame.image.load(fig_path + 'monster4.png').convert_alpha()
    monster4_width = monster4_img.get_width()
    monster4_height = monster4_img.get_height()
    monster5_img = pygame.image.load(fig_path + 'monster5.png').convert_alpha()
    monster5_width = monster5_img.get_width()
    monster5_height = monster5_img.get_height()
    monster6_img = pygame.image.load(fig_path + 'monster6.png').convert_alpha()
    monster6_width = monster6_img.get_width()
    monster6_height = monster6_img.get_height()
    # 彩蛋boss
    monster_boss_img = pygame.image.load(fig_path + 'monster_boss.png').convert_alpha()
    monster_boss_width = monster_boss_img.get_width()
    monster_boss_height = monster_boss_img.get_height()

    monsters_img = [monster1_img, monster2_img, monster3_img, monster4_img, monster5_img, monster6_img]
    monsters_width = [monster1_width, monster2_width, monster3_width, monster4_width, monster5_width, monster6_width]
    monsters_height =[monster1_height, monster2_height, monster3_height, monster4_height, monster5_height, monster6_height]
    monster_type_num = len(monsters_img)

    # 血条
    health_bar_img = pygame.image.load(fig_path + "health_bar.png")
    health_bar_height = health_bar_img.get_height()
    health_imgs = pygame.image.load(fig_path + "health.png")
    health_img = health_imgs
    health_height = health_img.get_height()

    # 游戏操作提示
    operate_img = pygame.image.load(fig_path + 'operate.png').convert_alpha()

    # 游戏胜利与游戏结束图片
    victory = pygame.image.load(fig_path + 'victory.png')
    victory_width = victory.get_width()
    victory_height = victory.get_height()
    game_over = pygame.image.load(fig_path + 'game_over.png')
    game_over_width = game_over.get_width()
    game_over_height = game_over.get_height()

    # 游戏开始封面
    start_img = pygame.image.load(fig_path + 'start.png').convert_alpha()


    # 2 - 游戏区--------------------------------------------------------------
    # 游戏开始
    while not start:
        screen.fill(white)
        screen.blit(start_img, (0, 0))

        pygame.font.init()
        # pygame.font.Font选择字体样式和大小
        font = pygame.font.Font(None, 40)
        # font.render显示文本内容,是否开启抗锯齿(即是否光滑),文本颜色
        text = font.render("Press Space to Start !",
                           True, (255,251,240)) # 乳白色
        text_Rect = text.get_rect()
        text_Rect.centerx = screen.get_rect().centerx
        text_Rect.centery = screen.get_rect().centery + 250
        screen.blit(text, text_Rect)

        pygame.display.flip()

        # 获取键盘事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == K_SPACE:
                    start = 1
                    running = 1
                    # 背景音乐
                    # pygame.mixer.music.load(fig_path + "Checkpoint.mp3")
                    # pygame.mixer.music.play(1, 0.0)
                    # pygame.mixer.music.set_volume(0.15)
                    start_time = datetime.datetime.now()

    # 2.2 - 游戏进行区---------------------------------------------
    while 1:
        # 2.2.0游戏开局设置区---------------------------------
        # 初始化kid的移动速度和初始位置
        rect_bg = Rect(50, 50, 133, 142)
        begger_pos = []
        # 建立一个新的Begger类对象
        bg = Begger(begger, rect_bg, bg_speed)

        # 初始化怪兽的位置
        monsters = []
        list_monster_type = []
        # 这里的type列表用来存放新生成怪兽的类型,我觉得其实写一个怪兽类,但我也是后来才知道的了

        # 初始化boss位置
        monster_boss = [screen_width, screen_height - monster_boss_height]

        # 初始化子弹位置
        wave_set = []

        # 初始化血量
        health_value = health_value_max
        health_img = health_imgs

        while running:
            # 2.2.1 - 游戏显示区-------------------------------
            screen.fill(white)
            screen.blit(paper, (0, 0))

            # 血条和时间显示
            font = pygame.font.Font(None, 42)
            cur_time = datetime.datetime.now()
            play_time = (cur_time - start_time).seconds
            # 时间显示
            if play_time % 60 < 10:
                time_str = ":0"
            else:
                time_str = ":"
            survived_text = font.render(
                str(play_time // 60) +
                time_str +
                str(play_time % 60),
                True, (0, 0, 0)
            )
            text_Rect = survived_text.get_rect()
            text_Rect.topright = [screen_width - 5, 5]
            screen.blit(survived_text, text_Rect)

            # 设置血条框的位置
            health_bar_img = pygame.transform.scale(health_bar_img,
                                                    (health_value_max + 2, health_bar_height))
            screen.blit(health_bar_img, [0, 5])

            # 设置血条的位置
            if health_value < 0:
                health_value = 0
            health_img = pygame.transform.scale(health_img,
                                                (health_value, health_height))
            screen.blit(health_img, [1, 7])

            if play_time < 3:
                screen.blit(operate_img, [300, 7])
            # 显示城墙
            # 判断血量少于75则刺儿受伤
            if health_value <= 75:
                for height in range(0, screen_height, wall_cry_height):
                    screen.blit(wall_cry, (distance, height))
            else:
                for height in range(0, screen_height, wall_height):
                    screen.blit(wall, (distance, height))

            # kid随鼠标移动而旋转
            press_keys = pygame.key.get_pressed()
            begger_pos, begger_img = bg.update(screen, press_keys)

            position = pygame.mouse.get_pos()
            angle = math.atan2(position[1] - (begger_pos[1] + begger_height),
                               position[0] - (begger_pos[0] + begger_width))
            begger_rot = pygame.transform.rotate(begger_img, 360 - angle * 57.29)
            begger_pos1 = (begger_pos[0] - begger_rot.get_rect().width / 2,
                           begger_pos[1] - begger_rot.get_rect().height / 2)
            screen.blit(begger_rot, begger_pos1)

            # 设置子弹
            for wave in wave_set:
                index = 0
                vel_x = math.cos(wave[0]) * wave_speed
                vel_y = math.sin(wave[0]) * wave_speed
                wave[1] += vel_x
                wave[2] += vel_y
                if wave[1] < - sub_wave_width or wave[1] > screen_width \
                        or wave[2] < - sub_wave_height or wave[2] > screen_height:
                    wave_set.pop(index) # pop移除列表index位置的对象
                index += 1

                for projectile in wave_set:
                    # wave1 = pygame.transform.rotate(sub_wave, 360 - projectile[0] * 57.29)
                    # .rotate(surface, angle)返回一个旋转后的surface对象,默认逆时针旋转,angle小于0时则顺时针, 此处子弹素材为中心对称可不旋转
                    screen.blit(sub_wave, (projectile[1], projectile[2]))

            # 设置怪兽
            # 此处生成0~monster_pro_speed-1的随机数,若生成0则产生一个新的monster,用以控制monster的生成速度
            monster_timer = random.choice(range(monster_pro_speed))
            if play_time > 2 and monster_timer < 1:
                # 确定怪兽种类
                monster_type_temp = random.randint(0, monster_type_num-1)
                monster_img_temp = monsters_img[monster_type_temp]
                monster_width_temp = monsters_width[monster_type_temp]
                monster_height_temp = monsters_height[monster_type_temp]
                monster_temp = [screen_width,
                                 random.randint(monster_height_temp, screen_height - monster_height_temp)]
                                 # random.randint产生区间范围内的随机整数
                monster_temp_rect = pygame.Rect(monsters_img[monster_type_temp].get_rect())
                monster_temp_rect.left = monster_temp[0]
                monster_temp_rect.top = monster_temp[1]

                # 第一只怪兽直接显示
                if len(monsters) == 0:
                    monster_type = monster_type_temp
                    monster_img = monster_img_temp
                    monster_width = monster_width_temp
                    monster_height = monster_height_temp

                    monsters.append(monster_temp)
                    list_monster_type.append(monster_type)
                else:
                    for monster in monsters:
                        monster_type = list_monster_type[monsters.index(monster)]
                        monster_rect = pygame.Rect(monsters_img[monster_type].get_rect())
                        monster_rect.left = monster[0]
                        monster_rect.top = monster[1]
                        # 如果两个monster交叉,则临时的怪兽不存入monsters列表
                        if monster_temp_rect.colliderect(monster_rect):
                            break
                        else:
                            # 如果到达了最后一个monster
                            if monsters.index(monster) == len(monsters)-1:
                                monster_type = monster_type_temp
                                monster_img = monster_img_temp
                                monster_width = monster_width_temp
                                monster_height = monster_height_temp
                                # 将有效的临时怪兽添加至monsters列表
                                monsters.append(monster_temp)
                                list_monster_type.append(monster_type)

            # 显示怪兽
            for monster in monsters:
                monsters_type = list_monster_type[monsters.index(monster)]
                screen.blit(monsters_img[monsters_type], monster)

            index = 0

            # 如果子弹碰到苹果则打击成功,如果苹果接触到刺儿测扣除自身20-40健康值
            for monster in monsters:
                monsters_type = list_monster_type[monsters.index(monster)]
                if monster[0] < - monsters_width[monsters_type]:
                    monsters.pop(index)
                    list_monster_type.pop(index)
                # 怪兽移动
                monster[0] -= monster_speed
                monster_rect = pygame.Rect(monsters_img[monsters_type].get_rect())
                monster_rect.top = monster[1]
                monster_rect.left = monster[0]
                # 怪兽到达刺儿位置则扣除血条30-50
                if monster_rect.left < wall_width + distance:
                    health_value -= random.randint(30, 50)
                    monsters.pop(index)
                    list_monster_type.pop(index)
                index1 = 0
                for wave in wave_set:
                    wave_rect = pygame.Rect(sub_wave.get_rect())
                    wave_rect.left = wave[1]
                    wave_rect.top = wave[2]
                    # 检查苹果和子弹两个矩形块是否交叉,交叉则移除两个矩形块
                    if monster_rect.colliderect(wave_rect):
                        wave_set.pop(index1)
                        try:
                            monsters.pop(index)
                            list_monster_type.pop(index)
                        except IndexError as error:
                            print("IndexError: " + str(error))
                    index1 += 1
                index += 1

            pygame.display.flip()
            #
            # 2.2.2 - 游戏操作区---------------------------
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                # 发射子弹
                if event.type == pygame.MOUSEBUTTONDOWN and len(wave_set) < wave_max:
                    position = pygame.mouse.get_pos()
                    wave_set.append([math.atan2(position[1] - (begger_pos1[1] + begger_height/2 + begger_height),
                                                position[0] - (begger_pos1[0] + begger_width + begger_width)),
                                     begger_pos1[0] + begger_width, begger_pos1[1] + begger_height/2])
            # 血量为0,game_over
            if health_value == 0:
                running = 0
                win = 0

            # 坚持指定时间
            # if pygame.time.get_ticks() >= fin_time * 1000:
            if play_time >= fin_time:
                # running = 0
                win = 1
                # 3 monster_boss彩蛋部分---------------------------------------------
                while 1:
                    # 3.1 - 彩蛋显示区-----------------------------------
                    screen.fill(white)
                    screen.blit(paper, (0, 0))

                    # 显示城墙
                    # 判断血量少于75则刺儿受伤
                    if health_value <= 75:
                        for height in range(0, screen_height, wall_cry_height):
                            screen.blit(wall_cry, (distance, height))
                    else:
                        for height in range(0, screen_height, wall_height):
                            screen.blit(wall, (distance, height))
                    # kid随鼠标移动而旋转
                    press_keys = pygame.key.get_pressed()
                    begger_pos, begger_img = bg.update(screen, press_keys)

                    position = pygame.mouse.get_pos()
                    angle = math.atan2(position[1] - (begger_pos[1] + begger_height),
                                       position[0] - (begger_pos[0] + begger_width))
                    begger_rot = pygame.transform.rotate(begger_img, 360 - angle * 57.29)
                    begger_pos1 = (begger_pos[0] - begger_rot.get_rect().width / 2,
                                   begger_pos[1] - begger_rot.get_rect().height / 2)
                    screen.blit(begger_rot, begger_pos1)

                    # 设置子弹
                    for wave in wave_set:
                        index = 0
                        vel_x = math.cos(wave[0]) * wave_speed
                        vel_y = math.sin(wave[0]) * wave_speed
                        wave[1] += vel_x
                        wave[2] += vel_y
                        if wave[1] < - sub_wave_width or wave[1] > screen_width \
                                or wave[2] < - sub_wave_height or wave[2] > screen_height:
                            wave_set.pop(index)  # pop移除列表index位置的对象
                        index += 1

                        for projectile in wave_set:
                            # wave1 = pygame.transform.rotate(sub_wave, 360 - projectile[0] * 57.29)
                            # .rotate(surface, angle)返回一个旋转后的surface对象,默认逆时针旋转,angle小于0时则顺时针, 此处子弹素材为中心对称可不旋转
                            screen.blit(sub_wave, (projectile[1], projectile[2]))

                    # 怪兽移动
                    monster_boss[0] -= monster_speed
                    monster_boss_rect = pygame.Rect(monster_boss_img.get_rect())
                    monster_boss_rect.top = monster_boss[1]
                    monster_boss_rect.left = monster_boss[0]

                    index2 = 0
                    for wave in wave_set:
                        wave_rect = pygame.Rect(sub_wave.get_rect())
                        wave_rect.left = wave[1]
                        wave_rect.top = wave[2]
                        # 检查怪兽和子弹两个矩形块是否交叉,交叉则移除子弹
                        if monster_boss_rect.colliderect(wave_rect):
                            wave_set.pop(index2)
                        index2 += 1
                    # 显示怪兽
                    screen.blit(monster_boss_img, monster_boss)

                    # 血条和时间显示
                    font = pygame.font.Font(None, 42)
                    cur_time = datetime.datetime.now()
                    play_time = (cur_time - start_time).seconds
                    # 时间显示
                    if play_time % 60 < 10:
                        time_str = ":0"
                    else:
                        time_str = ":"
                    survived_text = font.render(
                        str(play_time // 60) +
                        time_str +
                        str(play_time % 60),
                        True, (0, 0, 0)
                    )
                    text_Rect = survived_text.get_rect()
                    text_Rect.topright = [screen_width - 5, 5]
                    screen.blit(survived_text, text_Rect)

                    # 设置血条框的位置
                    health_bar_img = pygame.transform.scale(health_bar_img,
                                                            (health_value_max + 2, health_bar_height))
                    screen.blit(health_bar_img, [0, 5])

                    # 设置血条的位置
                    if health_value < 0:
                        health_value = 0
                    health_img = pygame.transform.scale(health_img,
                                                        (health_value, health_height))
                    screen.blit(health_img, [1, 7])

                    pygame.display.flip()
                    # 游戏操作
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            pygame.quit()
                            sys.exit()
                        # 发射子弹
                        if event.type == pygame.MOUSEBUTTONDOWN and len(wave_set) < wave_max:
                            position = pygame.mouse.get_pos()
                            wave_set.append(
                                [math.atan2(position[1] - (begger_pos1[1] + begger_height / 2 + begger_height),
                                            position[0] - (begger_pos1[0] + begger_width + begger_width)),
                                 begger_pos1[0] + begger_width, begger_pos1[1] + begger_height / 2])

                    # boss到达刺儿位置则胜利
                    if monster_boss_rect.left < (wall_width + distance):
                        running = 0
                        break

        # 游戏结束成功或失败
        while not running and start:
            pygame.mixer.music.stop()
            if win:
                screen.fill(white)
                screen.blit(victory, (0, (screen_height - victory_height) / 2))
                # pygame.font.init()
                # font = pygame.font.Font(None, 84)
                # text = font.render("Victory !",
                #                    True, (250, 50, 200))
                # text_Rect = text.get_rect()
                # text_Rect.centerx = screen.get_rect().centerx + 20
                # text_Rect.centery = screen.get_rect().centery - 250
                # screen.blit(text, text_Rect)
            if not win:
                screen.blit(game_over, ((screen_width-game_over_width)/2, (screen_height-game_over_height)/2))

            pygame.display.flip()

            # 按r重来
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == K_r:
                        start = 1
                        running = 1
                        start_time = datetime.datetime.now()

你可能感兴趣的:(python单机小游戏,python,pygame)