20193117 实验四《Python程序设计》实验报告

20193117 2019-2020-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级:1931
姓名:韦皓铭
学号:20193117
实验教师:王志强
实验日期:2020年5月20日
必修/选修: 公选课

1.实验内容

  • 运用python中的pygame模块并以所学python知识制作简单的游戏。

2. 实验过程及结果

实验大量查询了网络上编写的例子以及
《Python编程 从零基础到项目实战》中国水利水电出版社
《Python游戏编程入门》人民邮电出版社
中的例子以及教程。

运用Pygame模块编写一个战机游戏

import pygame
import time
pygame.init()
ck = pygame.display.set_mode((800,600))   #  游戏窗口
background = pygame.image.load("images/gui/g1.jpg")
pygame.display.set_caption("雷霆战机")    #  窗口名
clock = pygame.time.Clock()
start_ck = pygame.Surface(ck.get_size())    #   充当开始菜单界面的画布
start_ck2 = pygame.Surface(ck.get_size())  #  充当第一关的画布界面暂时占位
start_ck = start_ck.convert()
start_ck2 = start_ck2.convert()
start_ck=pygame.image.load("images/gui/g1.jpg")
start_ck2.fill((0,255,0))
# 加载各个素材图片 并且赋予变量名
i1 = pygame.image.load("images/gui/a1.png")
i1.convert()
i11 = pygame.image.load("images/gui/a2.png")
i11.convert()

i2 = pygame.image.load("images/gui/b2.png")
i2.convert()
i21 = pygame.image.load("images/gui/b1.png")
i21.convert()

i3 = pygame.image.load('images/gui/m2.png')
i3.convert()
i31 = pygame.image.load('images/gui/m1.png')
i31.convert()

bg = pygame.image.load('images/gui/bj.png')
bg.convert()

以pygame模块创建游戏窗口并且导入图片素材

n1 = True
while n1:
    clock.tick(30)
    buttons = pygame.mouse.get_pressed()
    x1, y1 = pygame.mouse.get_pos()
    if x1 >= 210 and x1 <= 500 and y1 >= 260 and y1 <=300:
        start_ck.blit(i11, (200, 240))
        if buttons[0]:
            n1 = False

    elif x1 >= 227 and x1 <= 555 and y1 >= 381 and y1 <=447:
        start_ck.blit(i21, (200, 360))
        if buttons[0]:
            pygame.quit()
            exit()

    elif x1 >= 227 and x1 <= 555 and y1 >= 501 and y1 <=567:
        start_ck.blit(i31, (200, 480))
    else:
        start_ck.blit(i1, (200, 240))
        start_ck.blit(i2, (200, 360))
        start_ck.blit(i3, (200, 480))

    ck.blit(start_ck,(0,0))
    pygame.display.update()

判定鼠标位置,在响应位置点击进入下一事件

(第三个监听事件原本打算做出设置,但能力问题做不出,暂且保留)

界面样式:

    def main():
        pygame.init()
        pygame.display.set_caption("雷霆战机")
        screen = pygame.display.set_mode((512, 768))
        bggroup = Group()
        bgsprite = BGSprite("images/background/bg1.jpg")
        bggroup.add(bgsprite)
        playergroup = Group()
        playersprite = PlayerSprite("images/hero/hero_b_03.png", [0, 0, 120, 100], [bgsprite.rect.w / 2 - 61, 600], 5,
                                    screen)
        playergroup.add(playersprite)
        enemygroup = Group()
        bullethelpgroup = Group()
        bossgroup = Group()
        pygame.time.set_timer(CREATE_ENEMY, random.randint(500, 1000))
        pygame.time.set_timer(CREATE_BOSS, random.randint(3000, 5000))
        pygame.time.set_timer(CREATE_BULLET_HELP, random.randint(3000, 5000))
        font = pygame.font.Font(None, 32)
        pygame.mixer.init()
        pygame.mixer.music.load("music/NANO-FXXKYIG,Avicii - Levels(NANO-FXXKYIG Bootleg).mp3")
        pygame.mixer.music.play(-1,0)

游戏主函数部分,复制再创建一个游戏使用的窗口

背景素材、玩家操作的精灵、类的区分、背景音乐的导入

           class PlayerSprite(Sprite):  # 玩家战机
        def __init__(self, imagepath, rect, pos, speed, screen):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.image = self.image.subsurface(rect)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.screen = screen
            self.bulletgroup = Group()
            self.score = 0
            self.hp = 100
            self.timer = 300
            self.bullettype = 0
            self.bulletnum = 10

        def move(self):
            keys = pygame.key.get_pressed()
            if keys[locals.K_RIGHT]:
                self.rect.x += self.speed
                if self.rect.x > 412:
                    self.rect.x = 412
            if keys[locals.K_LEFT]:
                self.rect.x -= self.speed
                if self.rect.x < 0:
                    self.rect.x = 0
            if keys[locals.K_UP]:
                self.rect.y -= self.speed
                if self.rect.y < 0:
                    self.rect.y = 0
            if keys[locals.K_DOWN]:
                self.rect.y += self.speed
                if self.rect.y > 702:
                    self.rect.y = 702

        def fire(self):
            self.timer += 1
            if self.timer > 50:
                self.timer = 0
                if self.bullettype == 0:
                    bullet = BulletSprite("images/bullet/bullet1.png", [self.rect.x + 45, self.rect.y - 20], 6, 0)
                    self.bulletgroup.add(bullet)

                    if self.bulletnum <= 0:
                        self.bullettype = 1

        def update(self):
            self.bulletgroup.update()
            self.bulletgroup.draw(self.screen)
            self.move()
            self.fire()

    CREATE_ENEMY = locals.USEREVENT + 1
    CREATE_BOSS = locals.USEREVENT + 2
    CREATE_BULLET_HELP = locals.USEREVENT + 3

玩家战机的类

功能有玩家战机的基础信息,即血量、分数、从键盘接收信息判断玩家机体的移动 update函数负责加载内容

    class EnemySprite(Sprite):  # 敌方战机
        def __init__(self, imagepath, pos, speed, screen, movetype, bullettype, hp):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.xspeed = random.randint(0, speed + 1) * movetype
            self.timer = 0
            self.timer2 = 3
            self.bulletgroup = Group()
            self.screen = screen
            self.bullettype = bullettype
            self.hp = hp

        def update(self):
            self.bulletgroup.update()
            self.bulletgroup.draw(self.screen)
            if self.bullettype == 0:
                self.timer += 0.01
                if self.timer > 1:   # print("敌机发射子弹")
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, 0)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, -1)
                    bullet3 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.bulletgroup.add(bullet3)
                    self.timer = 0
            else:
                self.timer += 0.01
                self.timer2 += 0.01
                if self.timer > 1:
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, -1)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                                [self.rect.x + 120, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.timer = 0
                if self.timer2 > 4:  # BOSS发射导弹
                    bullet = EnemyBulletSprite("images/bullet/boss_bullet.png", [self.rect.x + 80, self.rect.y + 39.5],
                                               -2,
                                               0)
                    self.bulletgroup.add(bullet)
                    self.timer2 = 0
            self.rect.y += self.speed
            self.rect.x += self.xspeed
            if self.rect.x > 400:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.x < 0:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.y > 800:
                self.kill()

        def bomb(self):
            bombimages = ["images/boom/boom01.png",
                          "images/boom/boom02.png",
                          "images/boom/boom03.png",
                          "images/boom/boom04.png",
                          "images/boom/boom05.png",
                          "images/boom/boom06.png",
                          ]
            for i in bombimages:
                self.screen.blit(pygame.image.load(i), (self.rect.x, self.rect.y))
                time.sleep(0.001)
                pygame.display.update()
            self.kill()

敌方战机的类,包括功能有敌方战机的飞行轨迹,子弹弹道类型(共3种) 敌机2种贴图,一个为小型机,一个为boss机,小型机规定飞行轨道有直道和漂浮型,boss机只有直道。

        class BulletSprite(Sprite):  # 玩家子弹精灵租
        def __init__(self, imagepath, pos, speed, direction):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.dir = direction

        def move(self):
            if self.dir == 0:
                self.rect.y -= self.speed


        def update(self):
            self.move()

玩家子弹的发射方向

    class EnemyBulletSprite(Sprite):  # 敌机子弹精灵组
        def __init__(self, imagepath, pos, speed, direction):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            # self.image = self.image.subsurface(rect)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.dir = direction

        def move(self):
            self.rect.y -= self.speed
            if self.rect.y < -40:
                self.kill()

        def move2(self):
            self.rect.y -= self.speed
            self.rect.x -= self.speed / 2
            if self.rect.y < -40:
                self.kill()

        def move3(self):
            self.rect.y -= self.speed
            self.rect.x += self.speed / 2
            if self.rect.y < -40:
                self.kill()

        def update(self):  # 子弹发射方向
            if self.dir == 0:
                self.move()
            elif self.dir == -1:
                self.move2()
            elif self.dir == 1:
                self.move3()

敌机子弹的发射方向

        while True:
            bggroup.update()
            bggroup.draw(screen)

            playergroup.update()
            playergroup.draw(screen)

            enemygroup.update()
            enemygroup.draw(screen)

            bossgroup.update()
            bossgroup.draw(screen)

            bullethelpgroup.update()
            bullethelpgroup.draw(screen)

            screen.blit(font.render("Score:" + str(playersprite.score), True, (255, 0, 0)), (20, 20))
            screen.blit(font.render("HP:" + str(playersprite.hp), True, (255, 0, 0)), (20, 60))

            pygame.display.update()

            check1 = pygame.sprite.groupcollide(playersprite.bulletgroup, enemygroup, True, False)  # 碰撞检测 销毁子弹 销毁敌机
            if check1:
                enemy.hp -= 1
                if enemy.hp <= 0:
                    list(check1.values())[0][0].bomb()
                    playersprite.score += 100
            check11 = pygame.sprite.groupcollide(playersprite.bulletgroup, bossgroup, True, False)  
            if check11:
                boss.hp -= 2
                if boss.hp <= 0:
                    list(check11.values())[0][0].bomb()
                    playersprite.score += 500
            check2 = pygame.sprite.groupcollide(playergroup, enemygroup, False, True)
            if check2:
                list(check2.values())[0][0].bomb()
                playersprite.hp -= 1
            check22 = pygame.sprite.groupcollide(playergroup, bossgroup, False, True)
            if check22:
                list(check22.values())[0][0].bomb()
                playersprite.hp -= 1

            for enemy in enemygroup:
                check3 = pygame.sprite.groupcollide(playergroup, enemy.bulletgroup, False, True)
                if check3:
                    playersprite.hp -= 2
            for boss in bossgroup:
                check33 = pygame.sprite.groupcollide(playergroup, boss.bulletgroup, False, True)
                if check33:
                    playersprite.hp -= 5

            if playersprite.hp <= 0:
                playersprite.kill()
            check4 = pygame.sprite.groupcollide(playergroup, bullethelpgroup, False, True)
            if check4:
                if playersprite.bullettype <= 1:
                    playersprite.bullettype += 1
                    playersprite.bulletnum = 10
                else:
                    playersprite.bulletnum = 10
            playersprite.fire()
            for event in pygame.event.get():

                if event.type == locals.QUIT:
                    pygame.quit()
                    exit()
                if event.type == CREATE_ENEMY:
                    enemy = EnemySprite("images/enemy/enemy1.png", [random.randint(0, 410), -50], 2, screen,
                                        random.randrange(-1, 1, 2), 0, 1)
                    enemygroup.add(enemy)
                if event.type == CREATE_BOSS:
                    boss = EnemySprite("images/enemy/boss.png", [random.randint(0, 410), -50], 1, screen, 0, 1, 15)
                    bossgroup.add(boss)

循环加载敌机模块,设定碰撞检测以及Hp为0时的检测,敌机机体或者玩家机体清除

设定玩家子弹对普通敌机单位和boss敌机单位的伤害

设定boss和普通敌机单位的贴图

设定boss子弹和普通敌机子弹分别对玩家机体hp的伤害

        def update(self):
            self.bulletgroup.update()
            self.bulletgroup.draw(self.screen)
            if self.bullettype == 0:
                self.timer += 0.01
                if self.timer > 1:   # print("敌机发射子弹")
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, 0)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, -1)
                    bullet3 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.bulletgroup.add(bullet3)
                    self.timer = 0
            else:
                self.timer += 0.01
                self.timer2 += 0.01
                if self.timer > 1:
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, -1)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                                [self.rect.x + 120, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.timer = 0
                if self.timer2 > 4:  # BOSS发射导弹
                    bullet = EnemyBulletSprite("images/bullet/boss_bullet.png", [self.rect.x + 80, self.rect.y + 39.5],
                                               -2,
                                               0)
                    self.bulletgroup.add(bullet)
                    self.timer2 = 0
            self.rect.y += self.speed
            self.rect.x += self.xspeed
            if self.rect.x > 400:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.x < 0:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.y > 800:
                self.kill()

        def bomb(self):
            bombimages = ["images/boom/boom01.png",
                          "images/boom/boom02.png",
                          "images/boom/boom03.png",
                          "images/boom/boom04.png",
                          "images/boom/boom05.png",
                          "images/boom/boom06.png",
                          ]
            for i in bombimages:
                self.screen.blit(pygame.image.load(i), (self.rect.x, self.rect.y))
                time.sleep(0.001)
                pygame.display.update()
            self.kill()

加载敌机子弹贴图,以及敌机子弹运动弹道(与上述发射不是一个)

加载敌机Hp为0时的爆炸贴图,才用循环方式爆炸,播放时间0.001s

完整代码块

import pygame
import time
pygame.init()
ck = pygame.display.set_mode((800,600))   #  游戏窗口
background = pygame.image.load("images/gui/g1.jpg")
pygame.display.set_caption("雷霆战机")    #  窗口名
clock = pygame.time.Clock()
start_ck = pygame.Surface(ck.get_size())    #   充当开始菜单界面的画布
start_ck2 = pygame.Surface(ck.get_size())  #  充当第一关的画布界面暂时占位
start_ck = start_ck.convert()
start_ck2 = start_ck2.convert()
start_ck=pygame.image.load("images/gui/g1.jpg")
start_ck2.fill((0,255,0))
# 加载各个素材图片 并且赋予变量名
i1 = pygame.image.load("images/gui/a1.png")
i1.convert()
i11 = pygame.image.load("images/gui/a2.png")
i11.convert()

i2 = pygame.image.load("images/gui/b2.png")
i2.convert()
i21 = pygame.image.load("images/gui/b1.png")
i21.convert()

i3 = pygame.image.load('images/gui/m2.png')
i3.convert()
i31 = pygame.image.load('images/gui/m1.png')
i31.convert()

bg = pygame.image.load('images/gui/bj.png')
bg.convert()

#  以下为选择开始界面鼠标检测结构。
n1 = True
while n1:
    clock.tick(30)
    buttons = pygame.mouse.get_pressed()
    x1, y1 = pygame.mouse.get_pos()
    if x1 >= 210 and x1 <= 500 and y1 >= 260 and y1 <=300:
        start_ck.blit(i11, (200, 240))
        if buttons[0]:
            n1 = False

    elif x1 >= 227 and x1 <= 555 and y1 >= 381 and y1 <=447:
        start_ck.blit(i21, (200, 360))
        if buttons[0]:
            pygame.quit()
            exit()

    elif x1 >= 227 and x1 <= 555 and y1 >= 501 and y1 <=567:
        start_ck.blit(i31, (200, 480))
    else:
        start_ck.blit(i1, (200, 240))
        start_ck.blit(i2, (200, 360))
        start_ck.blit(i3, (200, 480))

    ck.blit(start_ck,(0,0))
    pygame.display.update()

    # 监听事件
    for event in pygame.event.get():

        # 判断事件类型是否是退出事件
        if event.type == pygame.QUIT:
            print("游戏退出...")
            pygame.quit()
            exit()
ck.blit(start_ck2,(0,0))
pygame.display.update()


n2 = True
while n2:
    from pygame import locals
    from sys import exit
    from pygame.sprite import Sprite, Group
    import random, time, math

    class BGSprite(Sprite):  # 背景精灵
        def __init__(self, imagepath):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()


    class EnemySprite(Sprite):  # 敌方战机
        def __init__(self, imagepath, pos, speed, screen, movetype, bullettype, hp):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.xspeed = random.randint(0, speed + 1) * movetype
            self.timer = 0
            self.timer2 = 15
            self.bulletgroup = Group()
            self.screen = screen
            self.bullettype = bullettype
            self.hp = hp

        def update(self):
            self.bulletgroup.update()
            self.bulletgroup.draw(self.screen)
            if self.bullettype == 0:
                self.timer += 0.01
                if self.timer > 1:   # print("敌机发射子弹")
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, 0)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, -1)
                    bullet3 = EnemyBulletSprite("images/bullet/enemy_bullet1.png",
                                                [self.rect.x + 40, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.bulletgroup.add(bullet3)
                    self.timer = 0
            else:
                self.timer += 0.01
                self.timer2 += 0.01
                if self.timer > 1:
                    bullet = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                               [self.rect.x + 40, self.rect.y + 39.5],
                                               -2, -1)
                    bullet2 = EnemyBulletSprite("images/bullet/enemy_bullet2.png",
                                                [self.rect.x + 120, self.rect.y + 39.5],
                                                -2, 1)
                    self.bulletgroup.add(bullet)
                    self.bulletgroup.add(bullet2)
                    self.timer = 0
                if self.timer2 > 4:  # BOSS发射导弹
                    bullet = EnemyBulletSprite("images/bullet/boss_bullet.png", [self.rect.x + 80, self.rect.y + 39.5],
                                               -2,
                                               0)
                    self.bulletgroup.add(bullet)
                    self.timer2 = 0
            self.rect.y += self.speed
            self.rect.x += self.xspeed
            if self.rect.x > 400:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.x < 0:
                self.xspeed *= -1
                self.rect.x += self.xspeed
            if self.rect.y > 800:
                self.kill()

        def bomb(self):
            bombimages = ["images/boom/boom01.png",
                          "images/boom/boom02.png",
                          "images/boom/boom03.png",
                          "images/boom/boom04.png",
                          "images/boom/boom05.png",
                          "images/boom/boom06.png",
                          ]
            for i in bombimages:
                self.screen.blit(pygame.image.load(i), (self.rect.x, self.rect.y))
                time.sleep(0.001)
                pygame.display.update()
            self.kill()





    class BulletSprite(Sprite):  # 玩家子弹精灵租
        def __init__(self, imagepath, pos, speed, direction):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.dir = direction

        def move(self):
            if self.dir == 0:
                self.rect.y -= self.speed


        def update(self):
            self.move()

    class EnemyBulletSprite(Sprite):  # 敌机子弹精灵组
        def __init__(self, imagepath, pos, speed, direction):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.dir = direction

        def move(self):
            self.rect.y -= self.speed
            if self.rect.y < -40:
                self.kill()

        def move2(self):
            self.rect.y -= self.speed
            self.rect.x -= self.speed / 2
            if self.rect.y < -40:
                self.kill()

        def move3(self):
            self.rect.y -= self.speed
            self.rect.x += self.speed / 2
            if self.rect.y < -40:
                self.kill()

        def update(self):  # 子弹发射方向
            if self.dir == 0:
                self.move()
            elif self.dir == -1:
                self.move2()
            elif self.dir == 1:
                self.move3()


    class PlayerSprite(Sprite):  # 玩家战机
        def __init__(self, imagepath, rect, pos, speed, screen):
            super().__init__()
            self.image = pygame.image.load(imagepath)
            self.image = self.image.subsurface(rect)
            self.rect = self.image.get_rect()
            self.rect.x = pos[0]
            self.rect.y = pos[1]
            self.speed = speed
            self.screen = screen
            self.bulletgroup = Group()
            self.score = 0
            self.hp = 100
            self.timer = 300
            self.bullettype = 0
            self.bulletnum = 10

        def move(self):
            keys = pygame.key.get_pressed()
            if keys[locals.K_RIGHT]:
                self.rect.x += self.speed
                if self.rect.x > 412:
                    self.rect.x = 412
            if keys[locals.K_LEFT]:
                self.rect.x -= self.speed
                if self.rect.x < 0:
                    self.rect.x = 0
            if keys[locals.K_UP]:
                self.rect.y -= self.speed
                if self.rect.y < 0:
                    self.rect.y = 0
            if keys[locals.K_DOWN]:
                self.rect.y += self.speed
                if self.rect.y > 702:
                    self.rect.y = 702

        def fire(self):
            self.timer += 1
            if self.timer > 50:
                self.timer = 0
                if self.bullettype == 0:
                    bullet = BulletSprite("images/bullet/bullet1.png", [self.rect.x + 45, self.rect.y - 20], 6, 0)
                    self.bulletgroup.add(bullet)

                    if self.bulletnum <= 0:
                        self.bullettype = 1

        def update(self):
            self.bulletgroup.update()
            self.bulletgroup.draw(self.screen)
            self.move()
            self.fire()

    CREATE_ENEMY = locals.USEREVENT + 1
    CREATE_BOSS = locals.USEREVENT + 2
    CREATE_BULLET_HELP = locals.USEREVENT + 3

    def main():
        pygame.init()
        pygame.display.set_caption("雷霆战机")
        screen = pygame.display.set_mode((512, 768))
        bggroup = Group()
        bgsprite = BGSprite("images/background/bg1.jpg")
        bggroup.add(bgsprite)
        playergroup = Group()
        playersprite = PlayerSprite("images/hero/hero_b_03.png", [0, 0, 120, 100], [bgsprite.rect.w / 2 - 61, 600], 5,
                                    screen)
        playergroup.add(playersprite)
        enemygroup = Group()
        bullethelpgroup = Group()
        bossgroup = Group()
        pygame.time.set_timer(CREATE_ENEMY, random.randint(500, 1000))
        pygame.time.set_timer(CREATE_BOSS, random.randint(3000, 5000))
        pygame.time.set_timer(CREATE_BULLET_HELP, random.randint(3000, 5000))
        font = pygame.font.Font(None, 32)
        pygame.mixer.init()
        pygame.mixer.music.load("music/NANO-FXXKYIG,Avicii - Levels(NANO-FXXKYIG Bootleg).mp3")
        pygame.mixer.music.play(-1,0)

        while True:
            bggroup.update()
            bggroup.draw(screen)

            playergroup.update()
            playergroup.draw(screen)

            enemygroup.update()
            enemygroup.draw(screen)

            bossgroup.update()
            bossgroup.draw(screen)

            bullethelpgroup.update()
            bullethelpgroup.draw(screen)

            screen.blit(font.render("Score:" + str(playersprite.score), True, (255, 0, 0)), (20, 20))
            screen.blit(font.render("HP:" + str(playersprite.hp), True, (255, 0, 0)), (20, 60))

            pygame.display.update()

            check1 = pygame.sprite.groupcollide(playersprite.bulletgroup, enemygroup, True, False)  # 碰撞检测 销毁子弹 销毁敌机
            if check1:
                enemy.hp -= 1
                if enemy.hp <= 0:
                    list(check1.values())[0][0].bomb()
                    playersprite.score += 100
            check11 = pygame.sprite.groupcollide(playersprite.bulletgroup, bossgroup, True, False)  # 碰撞检测 销毁子弹 销毁敌机
            if check11:
                boss.hp -= 2
                if boss.hp <= 0:
                    list(check11.values())[0][0].bomb()
                    playersprite.score += 500
            check2 = pygame.sprite.groupcollide(playergroup, enemygroup, False, True)
            if check2:
                list(check2.values())[0][0].bomb()
                playersprite.hp -= 1
            check22 = pygame.sprite.groupcollide(playergroup, bossgroup, False, True)
            if check22:
                list(check22.values())[0][0].bomb()
                playersprite.hp -= 1

            for enemy in enemygroup:
                check3 = pygame.sprite.groupcollide(playergroup, enemy.bulletgroup, False, True)
                if check3:
                    playersprite.hp -= 2
            for boss in bossgroup:
                check33 = pygame.sprite.groupcollide(playergroup, boss.bulletgroup, False, True)
                if check33:
                    playersprite.hp -= 5

            if playersprite.hp <= 0:
                playersprite.kill()
            check4 = pygame.sprite.groupcollide(playergroup, bullethelpgroup, False, True)
            if check4:
                if playersprite.bullettype <= 1:
                    playersprite.bullettype += 1
                    playersprite.bulletnum = 10
                else:
                    playersprite.bulletnum = 10
            playersprite.fire()
            for event in pygame.event.get():

                if event.type == locals.QUIT:
                    pygame.quit()
                    exit()
                if event.type == CREATE_ENEMY:
                    enemy = EnemySprite("images/enemy/enemy1.png", [random.randint(0, 410), -50], 2, screen,
                                        random.randrange(-1, 1, 2), 0, 1)
                    enemygroup.add(enemy)
                if event.type == CREATE_BOSS:
                    boss = EnemySprite("images/enemy/boss.png", [random.randint(0, 410), -50], 1, screen, 0, 1, 15)
                    bossgroup.add(boss)



    if __name__ == '__main__':
        main()
    clock.tick(30)
    ck.blit(start_ck2, (0, 0))
    start_ck2.blit(bg,(0,0))
    pygame.display.update()
    for event in pygame.event.get():

        # 判断事件类型是否是退出事件
        if event.type == pygame.QUIT:
            print("游戏退出...")
            pygame.quit()
            exit()

视频链接:https://pan.baidu.com/s/1jRVOWeaEN9gDCsheXh7fPw
提取码:bvy3
代码及素材
链接:https://pan.baidu.com/s/1Ri98mYCmO_QdEd3QvHr5nw
提取码:qiqc
gitee连接:https://gitee.com/python_programming/whm20193117/blob/master/实验四

3. 实验过程中遇到的问题和解决过程

pygame中的代码使用和GUI编写。教程里的pygame使用GUI和普通python下的不太一样,需要重新学习编写,教材和网上没有找到能居中的办法,只能通过x轴和y轴编写。
GUI中按键输入需要使用到监听事件,通过监听鼠标点击的区域范围来决定是否触发事件。没有找到什么好方法把按键监听设置得十分精确,代码中的GUI按键有小部分偏离。
编写战机移动以及子弹移动时,《python游戏编程入门》中介绍的方法难以实现,这里通过https://blog.csdn.net/weixin_44033675/article/details/103706961 介绍的方法实现子弹发射方向,并且通过https://blog.csdn.net/hailler1119/article/details/88594578 介绍的操作实现子弹固定移动轨迹
对于子弹的精灵类通过https://www.cnblogs.com/Dark-fire-liehuo/p/9723950.html 介绍的方式进行修改
主控监听则是通过书本教程和https://blog.csdn.net/qq_38038143/article/details/80040710 结合
在本实验需要用到大量的类和继承,通过https://www.jianshu.com/p/94a61766747c 编写类的使用,同时要实现子弹和敌我机体的碰撞判断以及Hp死亡判断,消除机体,也是从该作者了解到
背景音乐的实现来自 https://blog.csdn.net/weixin_42416449/article/details/80913087

其他(感悟、思考等)

本次实现选了个及其有挑战性的项目完成,但是本人能力还是不足,如果不在大量资料查阅和使用下,可能做不出一个一模一样的,在项目的前中期还有许多规划的表现没有实现,如动态的背景(pygame删除了movie模块,想通过单帧循环来完成动态背景但是关于如何做到设置背景一直没有好方法,多数会覆盖图层)还有中途暂停以及结束选项都没有实现。而在网上查询的过程中也了解到,游戏开发不止用到pygame模块,也可以用其他模块来辅助,但是本次实验仅仅使用了pygame,或许使用其他模块辅助很多方法都能实现了。python的学习需要不间断的练习,这次是写过的最长的代码,但是也有很多仅是仿照他人的例子编写,如类的封装继承还是不熟练,pygame模块的使用,甚至有些地方代码的作用可能描述不出来,这些都需要多加学习多加巩固。

在本课程中学习了很多,相比其他主修课程语言,python作为选修课的进度几乎是其他课程的2倍,因此python课能学到比其他课更多内容,但也更加难以巩固学会。需要投入非常多的时间,例如本次期末实验,用于复习前面所学的封装继承占了很多时间,而课余学习GUI(pygame的GUI又有点不太一样)和pygame代码又消耗了不少时间。但是收益还是很多的,首先是自己完成的成就感,虽然该代码中还有许多问题没有找出(主要运行没问题),很多原本想做出的效果但是最后放弃了,代码还残留在里边。但是这同样是对Python知识的巩固,并且学到了许多python课堂上学不到的知识。对课上,老师很亲切的教我们,给了我们许多对未来编程有用的建议,给了我们许多小软件,为我们今后学习提供了不少便利。本学期的python课十分有收获。

参考资料

posted @ 2020-06-14 17:19  20193117韦皓铭  阅读(302)  评论(0编辑  收藏