python+pygame之飞机大战-第一版功能添加

目录

添加功能1:敌机速度根据分数发生变化

添加功能2:敌机出现频率随分数变化

添加功能3:添加游戏者2

添加功能4:添加音效

完整代码


基于网上下载的源码,并对功能进行添加,以此提高个人应用 pygame开发游戏的能力,添加功能如下:

添加功能1:敌机速度根据分数发生变化

1、改变Enemy()类的初始化调用,增加enemyspeed参数,在调用时传输速度

class Enemy():
    def __init__(self,enemyfilename,enemypos,enemyspeed):

        self.img = pygame.image.load(enemyfilename)
        self.enemy_rect = self.img.get_rect()
        self.enemy_image = self.img.subsurface(self.enemy_rect)
        self.enemy_rect.midbottom = enemypos
        self.speed = enemyspeed

    def move(self):
        self.enemy_rect.bottom += self.speed  #敌机向下运动

2、根据分数确定调用时的速度

#根据分数的多少来控制敌机的速度
                if Score<=5000:
                    enemyspeed = 1
                    
                elif Score<=10000:
                    enemyspeed = 2
                    
                elif Score<=50000:
                    enemyspeed = 3
                    
                else:
                    enemyspeed = 4
                   

3、调用时应用enemyspeed

            if enemy_frequency % ENENY_FREQUENCY_RATE == 0:
                enemypos = [random.randint(30, 630), 0]
                enemyplane = Enemy(enemyfilename, enemypos,enemyspeed)
                #将敌机对象添加到列表中
                enemys.append(enemyplane)

添加功能2:敌机出现频率随分数变化

1、设置敌机出现频率

#设置敌机的出现频率
    ENENY_FREQUENCY_RATE=100

2、根据分数设置刷新频率3

                if Score<=5000:
                    enemyspeed = 1
                    ENENY_FREQUENCY_RATE=100
                elif Score<=10000:
                    enemyspeed = 2
                    ENENY_FREQUENCY_RATE=70
                elif Score<=50000:
                    enemyspeed = 3
                    ENENY_FREQUENCY_RATE=50
                else:
                    enemyspeed = 4
                    ENENY_FREQUENCY_RATE=30

3、根据频率产生敌机

            if enemy_frequency % ENENY_FREQUENCY_RATE == 0:
                enemypos = [random.randint(30, 630), 0]
                enemyplane = Enemy(enemyfilename, enemypos,enemyspeed)
                #将敌机对象添加到列表中
                enemys.append(enemyplane)
            enemy_frequency += 1
            if enemy_frequency >= ENENY_FREQUENCY_RATE:
                enemy_frequency = 0

添加功能3:添加游戏者2

1、指定图片、位置、生成实例,指定子弹图

playplanefilename2="image/hero2.png"
planepos2 = [230, 600]
player2 = play_plane_fly(playplanefilename2, planepos2)
bulletfilename2 = 'image/bullet2.png'
2、设定按键控制
if  key_pressed[K_w]:
    player2.moveup()
if  key_pressed[K_s]:
    player2.movedown()
if  key_pressed[K_a]:
    player2.moveleft()
if  key_pressed[K_d]:
    player2.moveright()

3、加入判断,生成子弹

if not player2.is_hitted:
    player2.shoot(bulletfilename2)

4、让子弹动起来

for i in player2.bullets:
    i.move()
    screen.blit(i.bullet_image,i.bullet_rect)
    #    当子弹飞出屏幕,删除子弹对象
    if i.bullet_rect.bottom <= 0:
        player2.bullets.remove(i)  #从列表中删除数据

5、判断子弹击中敌机情况

                for j in player2.bullets:
                    #    如果击中,分数增加,同时移除该子弹和敌机对象
                    if pygame.Rect.colliderect(j.bullet_rect,i.enemy_rect):  #运用的是rect对象的检测,测试两个矩形是否重叠
                        Score += 100
                        #运行时经常以ValueError: list.remove(x): x not in list跳出,解决
                        if i in enemys: #由于
                            enemys.remove(i)
                        player2.bullets.remove(j)
                        
                        for k in enenys_down:
                            screen.blit(k,i.enemy_rect)

6、判断飞机是否被撞击

                if pygame.Rect.colliderect(player2.plane_rect,i.enemy_rect):
                    #    修改is_hitted的值
                    player2.is_hitted = True
                    enemys.remove(i)
                    break

添加功能4:添加音效

1、添加音效初始化

#初始化声音
    pygame.mixer.init()

2、加载声音文件

#加载声音文件
    sound_bullet = pygame.mixer.Sound("sound/bullet.mp3")
    sound_enemydown = pygame.mixer.Sound("sound/enemy0_down.mp3")
    music = pygame.mixer.music.load("sound/game_music.mp3")

3、播放背景音乐

#播发背景乐
    pygame.mixer.music.play(-1)

4、在需要的位置加入声效

 if bullet_frequency % 30 == 0:
                if not player.is_hitted:
                    player.shoot(bulletfilename)
                    pygame.mixer.Sound.play(sound_bullet)

                if not player2.is_hitted:
                    player2.shoot(bulletfilename2)
                    pygame.mixer.Sound.play(sound_bullet)
            

                     if pygame.Rect.colliderect(j.bullet_rect,i.enemy_rect):  #运用的是rect对象的检测,测试两个矩形是否重叠
                        Score += 100
                        enemys.remove(i)
                        player.bullets.remove(j)
                        pygame.mixer.Sound.play(sound_enemydown)

完整代码

下面附上完整代码,希望对读者有所启发。

#由于源码是从网上下载下来的,在研究过后,为了提高自己的编程能力,对原码进行改进
#添加敌机的速度变化,随分数的变化,速度增加
#添加敌机出现频率的变化,随分数的变化,增加
#添加游戏者2
import pygame
from pygame.locals import *
from sys import exit
import time
import random

#创建子弹类,把子弹的图片转化为图像对象,设定固定的移动速度
class Bullet():
    def __init__(self, bulletfilename, bulletpos):  #定义初始化,参数是图的文件名和位置
        self.bulletimg = pygame.image.load(bulletfilename) #图像
        self.bullet_rect = self.bulletimg.get_rect()#获得rect
        self.bullet_image = self.bulletimg.subsurface(self.bullet_rect) #生成subsurface对象
        self.bullet_rect.midbottom = bulletpos  #设置rect位置
        self.speed = 2 #设置子弹速度
    def move(self):
        self.bullet_rect.top -= self.speed   #子弹的运动是不断的以速度值大小减小

#    创建玩家飞机类,用面向对象的思想来对待
class play_plane_fly():
    def __init__(self,play_image_filename,play_pos):
        self.image = pygame.image.load(play_image_filename)
        self.plane_rect = self.image.get_rect()
        self.play_image = self.image.subsurface(self.plane_rect)
        self.plane_rect.midtop = play_pos
        self.speed = 2
        #子弹是由玩家飞机发射的,所以创建列表,存储子弹对象,使该列表变为该类的属性
        self.bullets = [] #子弹空列表
        self.is_hitted = False #是否被击中

    #生成函数,完成发射子弹动作,同时将每个子弹对象存在列表中
    def shoot(self,bullet_filename):
        bulletobj = Bullet(bullet_filename,self.plane_rect.midtop) #利用Bullet生产
        self.bullets.append(bulletobj) #加入子弹列表

    #定义向上移动方法,当飞机移动到边框位置时,无法移动
    def moveup(self):
        if self.plane_rect.top <= 0:
            self.plane_rect.top = 0
        else:
            self.plane_rect.top -= self.speed

    # 定义向下移动方法,当飞机移动到边框位置时,无法移动
    def movedown(self):
        if self.plane_rect.top >= 700 - self.plane_rect.height:
            self.plane_rect.top = 700 - self.plane_rect.height
        else:
            self.plane_rect.top += self.speed

    #    向右移动,当飞机移动到边框位置时,无法移动
    def moveleft(self):
        if self.plane_rect.left <= -40:
            self.plane_rect.left = -40
        else:
            self.plane_rect.left -= self.speed

    #    向左移动,当飞机移动到边框位置时,无法移动
    def moveright(self):
        if self.plane_rect.left >= 700 - self.plane_rect.width:
            self.plane_rect.left = 700 - self.plane_rect.width
        else:
            self.plane_rect.left += self.speed

#    生成敌机类,设定固定的移动速度
class Enemy():
    def __init__(self,enemyfilename,enemypos,enemyspeed):

        self.img = pygame.image.load(enemyfilename)
        self.enemy_rect = self.img.get_rect()
        self.enemy_image = self.img.subsurface(self.enemy_rect)
        self.enemy_rect.midbottom = enemypos
        self.speed = enemyspeed

    def move(self):
        self.enemy_rect.bottom += self.speed  #敌机向下运动

clock = pygame.time.Clock()
def main():
    #    初始化文字屏幕
    pygame.font.init()
    #    初始化图像屏幕
    pygame.init()
    #初始化声音
    pygame.mixer.init()
    #    设定游戏帧
    clock.tick(50)
    #    设定游戏屏幕大小
    screen = pygame.display.set_mode((660, 700))
    #    设定游戏名称
    pygame.display.set_caption('飞机大战')
    #    加载背景图片,生成图像对象
    background = pygame.image.load('image/background.png').convert()
    backgroundsurface = pygame.transform.scale(background,  (660,  700))
    #    加载游戏结束图片,生成图像对象
    gameover = pygame.image.load('image/gameover.png').convert()
    gameoversurface = pygame.transform.scale(gameover, (660, 700))

    #加载声音文件
    sound_bullet = pygame.mixer.Sound("sound/bullet.mp3")
    sound_enemydown = pygame.mixer.Sound("sound/enemy0_down.mp3")
    music = pygame.mixer.music.load("sound/game_music.mp3")


    #播发背景乐
    pygame.mixer.music.play(-1)

    playplanefilename = 'image/hero1.png'
    playplanefilename2="image/hero2.png"
    planepos = [430,600]
    planepos2 = [230, 600]
    player = play_plane_fly(playplanefilename,planepos) #定义play实例
    player2 = play_plane_fly(playplanefilename2, planepos2)

    bulletfilename = 'image/bullet1.png'
    bulletfilename2 = 'image/bullet2.png'

    # 按频率生成子弹,初始化数字为0
    bullet_frequency = 0

    enemyfilename = 'image/enemy0.png'
    #    按频率生成敌机,初始化数字为0
    enemy_frequency = 0

    # 定义enemys空列表
    enemys = []


    myfont = pygame.font.SysFont("font/Marker Felt.ttf", 40)

    textImage = myfont.render("Score ", True, (0,0,0))
    # 初始化得分为0
    Score = 0

    #用来存敌机的速度
    enemyspeed =1

    #设置敌机的出现频率
    ENENY_FREQUENCY_RATE=100

    # 敌机被子弹击中时的动画,将每张图片的图像对象存在列表中
    enenys_down = []
    enemy0_down = pygame.image.load('image/enemy0_down1.png')
    enemy0_down_rect = enemy0_down.get_rect()
    enemydown0 = enemy0_down.subsurface(enemy0_down_rect)
    enenys_down.append(enemydown0)

    enemy1_down = pygame.image.load('image/enemy0_down2.png')
    enemy1_down_rect = enemy1_down.get_rect()
    enemydown1 = enemy1_down.subsurface(enemy1_down_rect)
    enenys_down.append(enemydown1)

    enemy2_down = pygame.image.load('image/enemy0_down3.png')
    enemy2_down_rect = enemy2_down.get_rect()
    enemydown2 = enemy2_down.subsurface(enemy2_down_rect)
    enenys_down.append(enemydown2)

    enemy3_down = pygame.image.load('image/enemy0_down4.png')
    enemy3_down_rect = enemy3_down.get_rect()
    enemydown3 = enemy3_down.subsurface(enemy3_down_rect)
    enenys_down.append(enemydown3)
    #以上存了四组击中后的图片,实现击中后的飞机爆炸

    while True:
        #    动态显示得分
        score = str(Score)
        myscore = pygame.font.SysFont("font/Marker Felt.ttf", 40)
        scoreImage = myscore.render(score, True, (0, 0, 0))
        # 判断事件,防止卡顿或者意外退出
        for event in pygame.event.get():
            if event.type == pygame.QUIT: #退出事件
                pygame.quit()
                exit()
        key_pressed = pygame.key.get_pressed() #接收输入键
        if key_pressed[K_UP] :
            player.moveup()
        if key_pressed[K_DOWN]:
            player.movedown()
        if key_pressed[K_LEFT]:
            player.moveleft()
        if key_pressed[K_RIGHT] :
            player.moveright()

        if  key_pressed[K_w]:
            player2.moveup()
        if  key_pressed[K_s]:
            player2.movedown()
        if  key_pressed[K_a]:
            player2.moveleft()
        if  key_pressed[K_d]:
            player2.moveright()


        screen.blit(backgroundsurface, (0, 0)) #绑定背景图

        if not player.is_hitted or not player2.is_hitted:  #如果两个游戏对象没有都被击中
            #    按频率生成子弹
            # 通过控制30这个数,来控制发射子弹的间隔,循环30次后发射一个子弹
            #处理英雄死了后,子弹不再发射的问题
            #(处理方法是加入生成子弹的判断,如果被击中后不再产生即可)
            if bullet_frequency % 30 == 0:
                if not player.is_hitted:
                    player.shoot(bulletfilename)
                    pygame.mixer.Sound.play(sound_bullet)

                if not player2.is_hitted:
                    player2.shoot(bulletfilename2)
                    pygame.mixer.Sound.play(sound_bullet)
            bullet_frequency += 1
            if bullet_frequency >= 30:
                bullet_frequency = 0
            # print("bullet_frequency is {0}".format(bullet_frequency)) #试验用的,没有实际意义

            #  让player子弹动起来
            for i in player.bullets:
                i.move()
                screen.blit(i.bullet_image,i.bullet_rect)
                #    当子弹飞出屏幕,删除子弹对象
                if i.bullet_rect.bottom <= 0:
                    player.bullets.remove(i)  #从列表中删除数据
            #让player2的子弹动起来
            for i in player2.bullets:
                i.move()
                screen.blit(i.bullet_image,i.bullet_rect)
                #    当子弹飞出屏幕,删除子弹对象
                if i.bullet_rect.bottom <= 0:
                    player2.bullets.remove(i)  #从列表中删除数据

            #    按频率生成敌机
            #原理同子弹频率一样
            if enemy_frequency % ENENY_FREQUENCY_RATE == 0:
                enemypos = [random.randint(30, 630), 0]
                enemyplane = Enemy(enemyfilename, enemypos,enemyspeed)
                #将敌机对象添加到列表中
                enemys.append(enemyplane)
            enemy_frequency += 1
            if enemy_frequency >= ENENY_FREQUENCY_RATE:
                enemy_frequency = 0
            #    让敌机动起来
            for i in enemys:
                i.move()
                screen.blit(i.enemy_image,i.enemy_rect)
                #    当敌机飞出屏幕,删除敌机对象
                if i.enemy_rect.bottom >= 700:
                    enemys.remove(i)
                #    遍历子弹对象,判断子弹是否击中敌机

                for j in player.bullets:
                    #    如果击中,分数增加,同时移除该子弹和敌机对象
                    if pygame.Rect.colliderect(j.bullet_rect,i.enemy_rect):  #运用的是rect对象的检测,测试两个矩形是否重叠
                        Score += 100
                        enemys.remove(i)
                        player.bullets.remove(j)
                        pygame.mixer.Sound.play(sound_enemydown)
                        for k in enenys_down:
                            screen.blit(k,i.enemy_rect)
                for j in player2.bullets:
                    #    如果击中,分数增加,同时移除该子弹和敌机对象
                    if pygame.Rect.colliderect(j.bullet_rect,i.enemy_rect):  #运用的是rect对象的检测,测试两个矩形是否重叠
                        Score += 100
                        #运行时经常以ValueError: list.remove(x): x not in list跳出,解决
                        if i in enemys: #由于
                            enemys.remove(i)
                        player2.bullets.remove(j)
                        pygame.mixer.Sound.play(sound_enemydown)
                        for k in enenys_down:
                            screen.blit(k,i.enemy_rect)
                #根据分数的多少来控制敌机的速度
                if Score<=5000:
                    enemyspeed = 1
                    ENENY_FREQUENCY_RATE=100
                elif Score<=10000:
                    enemyspeed = 2
                    ENENY_FREQUENCY_RATE=70
                elif Score<=50000:
                    enemyspeed = 3
                    ENENY_FREQUENCY_RATE=50
                else:
                    enemyspeed = 4
                    ENENY_FREQUENCY_RATE=30

                #    遍历敌机对象,判断玩家是否和敌机相撞
                if pygame.Rect.colliderect(player.plane_rect,i.enemy_rect):
                    #    修改is_hitted的值,
                    player.is_hitted = True
                    enemys.remove(i)  #将敌机也干掉
                    break
                if pygame.Rect.colliderect(player2.plane_rect,i.enemy_rect):
                    #    修改is_hitted的值
                    player2.is_hitted = True
                    enemys.remove(i)
                    break
                # if player.is_hitted and player.is_hitted:
                #     break
            #如果被击中话,该飞机不显示,但是子弹仍显示,需要下步处理,(处理方法是加入生成子弹的判断,如果被击中后不再产生即可)
            if not player.is_hitted:
                screen.blit(player.play_image,player.plane_rect)
            if not player2.is_hitted:
                screen.blit(player2.play_image, player2.plane_rect)
            screen.blit(textImage, (0,0))
            screen.blit(scoreImage, (110, 0))
            pygame.display.update()
        #    玩家退出时显示分数和游戏结束
        else:
            screen.blit(gameoversurface,(0,0))
            screen.blit(textImage, (0, 0))
            screen.blit(scoreImage,  (110, 0))
            pygame.display.update()
            time.sleep(2)
            break

main()

猜你喜欢

转载自blog.csdn.net/sygoodman/article/details/124362570