使用python中的pygame实现飞机大战(一)

使用python中的pygame实现飞机大战(一)


前言

目的:更好理解python中的pygame,梳理python代码逻辑


一、游戏准备

游戏流程简单,这里不再赘述。安装pygame模块,新增虚拟环境,用来专门搞游戏这类方向的学习。
新建项目飞机大战,准备好需要的音乐图片等。分别创建核心模块game.py,游戏模块moudle.py,配乐music.py,提示信息tips.py文件

二、游戏实现

1.游戏框架搭建

1.窗口与游戏状态实现

代码如下(窗口与游戏状态实现):

import pygame
from 飞机大战.module import *
from 飞机大战.music import *
from 飞机大战.tips import  *
class Game(object):

    def __init__(self):
        # 游戏窗口初始化
        screen = pygame.Rect(0, 0, 480, 700)  # 游戏窗口
        self.mainwindow = pygame.display.set_mode(screen.size)
        pygame.display.set_caption("飞机大战")
        #游戏精灵

        #游戏状态
        self.pause = False
        self.over = False

    def reset(self):#游戏重置
        self.pause = False
        self.over = False
if __name__ == '__main__':
    game = Game()
    print(game.pause,game.over)
    game.over = True
    print(game.pause,game.over)

看一下基本的执行情况:
在这里插入图片描述

2.界面退出

代码如下(ESC与窗口右上角的叉叉):

# 时间:2021/1/1 21:15
# 核心模块
import pygame
from 飞机大战.module import *
from 飞机大战.music import *
from 飞机大战.tips import  *
class Game(object):

    def __init__(self):
        # 游戏窗口初始化
        screen = pygame.Rect(0, 0, 480, 700)  # 游戏窗口
        self.mainwindow = pygame.display.set_mode(screen.size)
        pygame.display.set_caption("飞机大战")
        #游戏精灵

        #游戏状态
        self.pause = False
        self.over = False

    def reset(self):#游戏重置
        self.pause = False
        self.over = False

    def run(self):
        clock = pygame.time.Clock()
        while True:
            if self.event_handler(): #键盘事件监听
                return

            clock.tick(60)# 刷新率

    def event_handler(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:#窗口叉叉退出
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: #ESC退出
                return True


if __name__ == '__main__':
    game = Game()
    game.run()

窗口效果:
游戏退出


3.界面暂停

代码如下(空格暂停与重新载入游戏):

# 时间:2021/1/1 21:15
# 核心模块
import pygame
from 飞机大战.module import *
from 飞机大战.music import *
from 飞机大战.tips import  *
class Game(object):

    def __init__(self):
        # 游戏窗口初始化
        screen = pygame.Rect(0, 0, 480, 700)  # 游戏窗口
        self.mainwindow = pygame.display.set_mode(screen.size)
        pygame.display.set_caption("飞机大战")
        #游戏精灵

        #游戏状态
        self.pause = False
        self.over = False

    def reset(self):#游戏重置
        self.pause = False
        self.over = False

    def run(self):
        clock = pygame.time.Clock()
        if self.pause == False:
            print("游戏开始")
        while True:
            if self.event_handler(): #键盘事件监听
                return
            if self.pause == True:
                print("游戏暂停")
            elif self.over == True:
                print("游戏结束")
            else:
                print("游戏继续")
            pygame.display.update() #刷新界面
            clock.tick(60)# 刷新率

    def event_handler(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:#窗口叉叉退出
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: #ESC退出
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: #空格暂停与游戏重新开始
                if not self.pause:
                    self.pause = not self.pause
                else:
                    self.reset()
        # return False


if __name__ == '__main__':
    game = Game()
    game.run()

结果实验:
在这里插入图片描述


2.精灵与精灵组

正常加载图片太过于繁琐,需要加载图片,确定矩阵位置,对多个组不好管理。为了保证在开发游戏时,能够方便地实现大量图像的绘制工作。pygame的sprite模块专门提供了两个类:精灵Sprite和精灵组Group,类图如下:
在这里插入图片描述

未使用精灵,代码如下:

    def creatimage(self):
        #加载背景、战机图像
        self.backgroundimage = pygame.image.load("./static/images/background.png")
        self.backgroundreact = self.backgroundimage.get_rect()
        self.zhanjiimage = pygame.image.load("./static/images/me1.png")
        self.zhanjireact = self.zhanjiimage.get_rect()
        #战机对齐背景中间
        self.zhanjireact.center =  self.backgroundreact.center

在这里插入图片描述

添加背景精灵,两张图片拼接,展示整个背景,代码如下:

 class Background(GameSprite):
    def __init__(self,outside,*group):
        super(Background, self).__init__("background.png",1,*group)

        if outside:
            self.rect.y = -self.rect.h

    def update(self, *args, **kwargs):
        super(Background, self).update(*args)
        # 背景拼接
        if self.rect.y > self.rect.h:
            self.rect.y = -self.rect.y

在这里插入图片描述
添加按钮精灵,标签精灵,面板指示器代码如下:

class Label(py.sprite.Sprite):
    """标签精灵类"""
    font_path = './static/font/MarkerFelt.ttc'

    def __init__(self,text,size,color,*groups):
        super(Label, self).__init__(*groups)

        # 字体
        py.init()
        self.font = py.font.Font(self.font_path,size)
        self.color = color
        self.image = self.font.render(text,True,self.color)
        self.rect = self.image.get_rect()

    def set_text(self,text):
        """设置文字"""
        self.image = self.font.render(text, True, self.color)
        self.rect = self.image.get_rect()

 class Button(GameSprite):

    def __init__(self,image_names,*groups):
        #image_names是元组,0暂停,1继续
        super(Button, self).__init__(image_names[0],0,*groups)
        self.images = [py.image.load(self.path + image) for image in image_names]

    def switch(self,is_pause):
        self.image = self.images[1 if is_pause else 0]



3.指示器面板

代码如下:

"""面板指示器标签"""
import pygame as py
from 飞机大战.module import *
from 飞机大战.game import *
class Panel(object):

    margin = 10 #间距
    white = (255,255,255)
    gray = (64,64,64)
    screen = py.Rect(0, 0, 480, 700)

    def __init__(self,display_group):
        self.score = 0 #得分
        self.lives = 6 #命数
        self.level = 1 #关卡
        self.best_score = 0 #最佳分数

        # 按钮
        self.status_sprite = Button(("pause.png","resume.png"),display_group)
        self.status_sprite.rect.topleft = (self.margin,self.margin)
        self.bomb_sprite = GameSprite("bomb.png", 0, display_group)  # 生命精灵
        self.bomb_sprite.rect.bottomleft = (self.margin,self.screen.bottom-self.margin )
        self.lives_sprite = GameSprite("life.png", 0, display_group)  # 子弹精灵
        self.lives_sprite.rect.right = self.screen.right-6*self.margin
        self.lives_sprite.rect.bottom = self.screen.bottom-self.margin
        # bullet_sprite.rect.bottomleft = screen.bottomleft
        # lives_sprite.rect.bottomright = screen.bottomright
        # 图像精灵

        # 标签
        self.best_label = Label('Best score:%d'%self.best_score,36,self.white,display_group)
        self.best_label.rect.center = self.screen.center

        self.status_label = Label('Game pause',48,self.white,display_group)
        self.status_label.rect.midbottom = (self.best_label.rect.centerx,
                                            self.best_label.rect.y-2*self.margin)
        self.score_label = Label('Current score:%d'%self.score, 21, self.gray,display_group)
        self.score_label.rect.right = self.screen.right - 2 * self.margin
        self.score_label.rect.top = self.screen.top + 2*self.margin

        self.bomb_label = Label('X 3', 32, self.gray,display_group)
        self.bomb_label.rect.midleft = (self.bomb_sprite.rect.right + self.margin,
                                         self.bomb_sprite.rect.centery)
        self.lives_label = Label('X %d'%self.lives,32,self.gray,display_group)
        self.lives_label.rect.midright = (self.screen.right-self.margin,
                                         self.bomb_sprite.rect.centery)

        # 提示标签
        self.tips_label = Label('Press space to continue',22,self.white,display_group)
        self.tips_label.rect.midtop = (self.best_label.rect.centerx,
                                       self.best_label.rect.bottom + 8*self.margin)

暂时效果:
在这里插入图片描述


三、总结

暂时先到这里面板指示器这里,等有时间继续。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以帮你回答这个问题。首先需要安装pygame模块,可以在命令行输入 pip install pygame 进行安装。然后,使用下面的示例代码,可以实现一个基础版的飞机大战游戏: ``` import pygame import random # 初始化pygame pygame.init() # 设置游戏界面大小、背景颜色 screen_width = 480 screen_height = 700 bg_color = pygame.Color('gray') # 创建游戏窗口 screen = pygame.display.set_mode((screen_width, screen_height)) # 设置游戏标题 pygame.display.set_caption('飞机大战') # 加载背景图 bg = pygame.image.load('images/background.png') # 加载玩家飞机图片 player_img = pygame.image.load('images/player.png') player_rect = player_img.get_rect(center=(screen_width//2, screen_height-100)) # 加载子弹图片 bullet_img = pygame.image.load('images/bullet.png') # 加载敌机图片 enemy_img1 = pygame.image.load('images/enemy1.png') enemy_img2 = pygame.image.load('images/enemy2.png') enemy_img3 = pygame.image.load('images/enemy3.png') enemy_imgs = [enemy_img1, enemy_img2, enemy_img3] # 飞机、子弹及敌机列表 player = pygame.sprite.GroupSingle() player.add(pygame.sprite.Sprite()) player.sprite.image = player_img player.sprite.rect = player_rect bullets = pygame.sprite.Group() enemies = pygame.sprite.Group() # 创建敌机 for i in range(6): enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 设置帧率 clock = pygame.time.Clock() # 定义游戏循环 while True: # 事件检测 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # 玩家移动操作 keys = pygame.key.get_pressed() if keys[pygame.K_UP]: player.sprite.rect.move_ip(0, -5) if keys[pygame.K_DOWN]: player.sprite.rect.move_ip(0, 5) if keys[pygame.K_LEFT]: player.sprite.rect.move_ip(-5, 0) if keys[pygame.K_RIGHT]: player.sprite.rect.move_ip(5, 0) # 玩家边界限制 if player.sprite.rect.left <= 0: player.sprite.rect.left = 0 if player.sprite.rect.right >= screen_width: player.sprite.rect.right = screen_width if player.sprite.rect.top <= 0: player.sprite.rect.top = 0 if player.sprite.rect.bottom >= screen_height: player.sprite.rect.bottom = screen_height # 子弹发射操作 if keys[pygame.K_SPACE]: bullet = pygame.sprite.Sprite() bullet.image = bullet_img bullet.rect = bullet.image.get_rect(center=player.sprite.rect.midtop) bullets.add(bullet) # 子弹移动 for bullet in bullets: bullet.rect.move_ip(0, -5) if bullet.rect.bottom <= 0: bullets.remove(bullet) # 敌机移动 for enemy in enemies: enemy.rect.move_ip(0, 3) if enemy.rect.top >= screen_height: enemy.kill() enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 子弹击敌机 for enemy in pygame.sprite.groupcollide(enemies, bullets, True, True): enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 玩家与敌机碰撞检测 if pygame.sprite.spritecollide(player.sprite, enemies, True): pygame.quit() exit() # 游戏界面显示 screen.blit(bg, (0,0)) player.draw(screen) bullets.draw(screen) enemies.draw(screen) pygame.display.flip() # 设置帧率 clock.tick(60) ``` 希望以上代码对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍旻之泪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值