python之pygame模块实现飞机大战完整代码

1. 引言

飞机大战是一款经典的街机游戏,今天我们将利用Python语言中的pygame模块来实现这个游戏的完整代码。在本文中,我们将会从游戏的需求入手,一步步地实现游戏的各个细节,具体实现过程中需要用到的知识点也会在文章中进行讲解。未来读者可以根据本文编写自己的飞机大战游戏。

2. 游戏的设计理念

在开始编写代码之前,我们需要先明确我们这个游戏的设计理念,也就是我们要编写什么样的游戏。

首先,游戏的核心玩法是玩家操作飞机进行击杀敌人,同时在尽可能长的时间内存活下去,最后得到尽可能高的得分。

其次,游戏需要拥有良好的音效和画面,以便更好地营造出游戏的氛围。

综上所述,我们需要编写一个操作简单但高度可玩性的游戏,并且要注重游戏的视听效果。

3. 游戏的实现细节

3.1 游戏窗口

游戏窗口是游戏的入口,玩家将在这个窗口内进行游戏,因此我们需要先创建游戏窗口。

在pygame中,可以通过以下代码来创建一个游戏窗口:

import pygame

pygame.init()

# 设置窗口大小

SCREEN_WIDTH = 480

SCREEN_HEIGHT = 700

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

# 游戏窗口标题

pygame.display.set_caption('打飞机')

其中pygame.init()是必须的初始化操作,它会初始化pygame的各个模块。

这里我们将窗口的大小设置为480*700,游戏窗口的标题为‘打飞机’。

接下来,我们需要在游戏窗口上绘制出游戏的各个元素,这就需要用到pygame库中的绘图相关函数。

3.2 游戏元素

3.2.1 背景图片

游戏开始时,我们需要将游戏窗口的背景设置为一张背景图片,在窗口的基础上绘制。

# 加载背景图片

bg = pygame.image.load('images/background.png')

# 将背景图片绘制在窗口上

screen.blit(bg, (0, 0))

这里我们将窗口的背景图片设置为‘background.png’,这个图片我们需要先下载到本地,并且将其放置在一个images文件夹中。

blit()函数的作用是将一个图像绘制在另一个图像上,第一个参数是要绘制的图像,第二个参数是图像的坐标,这里设置为(0,0),即将这个图像绘制在屏幕的左上角。

3.2.2 飞机元素

飞机是游戏中最重要的元素之一,我们需要给玩家一个可以控制的飞机,并且在游戏进行中,飞机应该呈现出不同的状态,比如移动、发射子弹、被击中等。

# 加载飞机图片,根据需要的大小进行缩放

player_img = pygame.image.load('images/me1.png').convert_alpha()

player_img = pygame.transform.scale(player_img, (50, 50))

# 初始化飞机位置

player_rect = player_img.get_rect()

player_rect.left, player_rect.top = (SCREEN_WIDTH - player_rect.width) // 2, SCREEN_HEIGHT - player_rect.height - 50

# 绘制飞机

screen.blit(player_img, player_rect)

我们将飞机图片设置为‘me1.png’,同样需要将这个图片放到images文件夹下。另外,我们使用convert_alpha()函数将图像进行透明处理,同时使用transform.scale()函数对其进行缩放。

在初始化飞机位置后,我们需要使用blit()函数将飞机图像绘制在游戏窗口上。

3.2.3 子弹元素

在飞机大战游戏中,子弹是飞机发射的武器,也是击落敌机的主要手段之一。

我们需要在程序中定义一个Bullet类,用于生成子弹,并且在游戏进行中,不断地更新子弹的状态。

# 子弹类的定义

class Bullet(pygame.sprite.Sprite):

def __init__(self, bullet_img, init_pos):

pygame.sprite.Sprite.__init__(self)

self.image = bullet_img

self.rect = self.image.get_rect()

self.rect.midbottom = init_pos

self.speed = 10

def update(self):

self.rect.top -= self.speed

这里我们定义了一个Bullet类,该类从pygame.sprite.Sprite类继承而来。Bullet类包含两个属性:image和rect,其分别代表子弹的图像和所在矩形区域。

在Bullet的初始化函数中,我们需要传入一个bullet_img参数,该参数为子弹的图像,同时还需要设置子弹的初始位置和速度。

在Bullet类的update()方法中,我们更新子弹的状态,即将子弹向上移动一定的距离,实现子弹的运动效果。

3.2.4 敌机元素

游戏中的敌机类型和数量是不确定的,我们需要定义一个Enemy类,用于生成不同类型、数量的敌机,并且在游戏进行中,不断地更新敌机的状态。

# 敌机类的定义

class Enemy(pygame.sprite.Sprite):

def __init__(self, enemy_img, init_pos):

pygame.sprite.Sprite.__init__(self)

self.image = enemy_img

self.rect = self.image.get_rect()

self.rect.topleft = init_pos

self.speed = 2

self.down_index = 0

def update(self):

self.rect.top += self.speed

敌机类Enemy也是从pygame.sprite.Sprite类继承下来,通常我们可以把Enemy对象放到一个精灵组中,通过遍历精灵组实现对敌机的控制。在敌机的初始化函数中,我们传入了enemy_img参数,该参数为敌机的图像;同时还需要设置敌机的初始位置和速度。

在Enemy类的update()方法中,我们更新敌机的状态,即将敌机向下移动一定的距离,实现敌机的运动效果。

3.3 游戏流程

我们已经知道了游戏中各个元素的实现方法,那么接下来我们需要将这些元素整合起来,形成一个完整的游戏流程。

整个游戏流程可以分为以下几个步骤:

初始化游戏,并设置游戏窗口的大小和标题。

加载游戏中的各个图片资源。

创建玩家的飞机和子弹精灵组。

创建敌机精灵组。

设置游戏时钟。

在主循环中不断检测玩家的键盘操作,实现飞机的移动和发射子弹。

不断向敌机精灵组中添加新的敌机。

检测玩家飞机和敌机之间的碰撞情况,并调整飞机、敌机、子弹的状态。

更新所有的精灵,包括玩家飞机、子弹和敌机。

将所有的精灵绘制到游戏窗口上。

循环进行以上步骤,直到玩家退出游戏。

3.4 游戏优化

在完成基本的游戏功能之后,我们还需要进一步优化游戏,使游戏更加流畅和易玩。

其中一些优化点包括:

使用rect对象来表示精灵的位置和大小,便于碰撞检测和定位;

使用pygame.sprite.Group()来管理精灵对象,避免重复处理和渲染;

避免在主循环中不断加载和释放图片资源,可以将图片资源预先加载到内存中,便于随时调用;

使用音效和动画等特效来增强游戏的可玩性和体验感。

4. 完整代码

最终的完整代码如下所示:

import pygame

import random

# 定义游戏窗口大小

SCREEN_WIDTH = 480

SCREEN_HEIGHT = 700

# 定义飞机相关参数

PLAYER_INIT_POS = ((SCREEN_WIDTH - 50) // 2, SCREEN_HEIGHT - 100)

PLAYER_SIZE = (50, 50)

PLAYER_IMG_PATH = 'images/me1.png'

PLAYER_SPEED = 5

# 定义子弹相关参数

BULLET_SIZE = (10, 20)

BULLET_IMG_PATH = 'images/bullet1.png'

BULLET_SPEED = 10

# 定义敌机相关参数

ENEMY_SIZE = (50, 50)

ENEMY_IMG_PATH = 'images/enemy1.png'

ENEMY_SPEED = 3

# 初始化pygame

pygame.init()

# 创建游戏窗口

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

pygame.display.set_caption('打飞机')

# 加载图片资源

background_img = pygame.image.load('images/background.png').convert()

player_img = pygame.image.load(PLAYER_IMG_PATH).convert_alpha()

bullet_img = pygame.image.load(BULLET_IMG_PATH).convert_alpha()

enemy_img = pygame.image.load(ENEMY_IMG_PATH).convert_alpha()

# 创建玩家飞机精灵

player_sprite = pygame.sprite.Sprite()

player_sprite.image = pygame.transform.scale(player_img, PLAYER_SIZE)

player_sprite.rect = player_sprite.image.get_rect()

player_sprite.rect.left, player_sprite.rect.top = PLAYER_INIT_POS

player_speed = PLAYER_SPEED

# 创建子弹精灵组

bullet_group = pygame.sprite.Group()

# 创建敌机精灵组

enemy_group = pygame.sprite.Group()

# 创建游戏时钟

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_LEFT]:

player_sprite.rect.left -= player_speed

if keys[pygame.K_RIGHT]:

player_sprite.rect.left += player_speed

if keys[pygame.K_UP]:

player_sprite.rect.top -= player_speed

if keys[pygame.K_DOWN]:

player_sprite.rect.top += player_speed

if keys[pygame.K_SPACE]:

# 创建新的子弹

bullet_sprite = pygame.sprite.Sprite()

bullet_sprite.image = pygame.transform.scale(bullet_img, BULLET_SIZE)

bullet_sprite.rect = bullet_sprite.image.get_rect()

bullet_sprite.rect.midbottom = player_sprite.rect.midtop

bullet_group.add(bullet_sprite)

# 每隔一段时间向敌机精灵组中添加新的敌机

if random.randint(0, 100) > 90:

enemy_sprite = pygame.sprite.Sprite()

enemy_sprite.image = pygame.transform.scale(enemy_img, ENEMY_SIZE)

enemy_sprite.rect = enemy_sprite.image.get_rect()

enemy_sprite.rect.left = random.randint(0, SCREEN_WIDTH - ENEMY_SIZE[0])

enemy_sprite.rect.top = -ENEMY_SIZE[1]

enemy_group.add(enemy_sprite)

# 检测子弹和敌机是否碰撞

for bullet_sprite in bullet_group:

hit_list = pygame.sprite.spritecollide(bullet_sprite, enemy_group, True)

if len(hit_list) > 0:

bullet_group.remove(bullet_sprite)

# 检测玩家飞机和敌机是否碰撞

hit_list = pygame.sprite.spritecollide(player_sprite, enemy_group, True)

if len(hit_list) > 0:

pygame.quit()

exit()

# 更新所有精灵的状态

player_group = pygame.sprite.Group(player_sprite)

player_group.update()

bullet_group.update()

enemy_group.update()

# 绘制所有精灵

screen.blit(background_img, (0, 0))

player_group.draw(screen)

bullet_group.draw(screen)

enemy_group.draw(screen)

# 更新屏幕

pygame.display.update()

# 控制游戏帧率

clock.tick(60)

5. 总结

通过本文的介绍,我们学习了pygame模块的基本用法,并且通过实现飞机大战游戏,了解了游戏设计和实现的一些基本原理和细节。飞机大战游戏虽然是一款简单的小游戏,但是它也包含了游戏设计和实现的一些常见的要点和难点,对于想要从事游戏开发的初学者来说,有一定的参考和帮助作用。

后端开发标签