python小游戏——飞机大战(1)

一、 环境配置

1、技术与环境

技术:Python+Pygame模块
环境:JetBrains PyCharm Community Edition 2019.1.3 x64windows10

2、Pygame模块配置

见博客:
pygame模块配置(命令行配置、PyCharm配置、解决PyCharm新建项目需要重新配置问题
https://blog.csdn.net/lyz21/article/details/96483543

二、实现步骤

1、显示界面

在进行游戏设计之前,先画出来一个界面,之后再在界面上进行操作。背景图片名为background.png,目录为项目resources\images\background.png下,本节完成结果显示如下:
在这里插入图片描述
代码:

import pygame
from sys import exit

'''初始化界面'''
# 窗口分辨率
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 640
# 载入背景图片
background_img = pygame.image.load('resources/images/background.png')
# 初始化pygame
pygame.init()
# 初始化窗口
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
# 设置窗口标题
pygame.display.set_caption('飞机大战')

'''事件循环'''
while True:
    # 绘制背景
    screen.blit(background_img, (0, 0))
    # 更新屏幕
    pygame.display.update()
    # 处理按键
    for event in pygame.event.get():
    	# 游戏退出
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

2、添加飞机

界面显示出来,我们在上面添加玩家飞机。
首先封装一个玩家类:

class Hero():
    def __init__(self, hero_surface, hero_init_position):
        self.image = hero_surface
        self.rect = self.image.get_rect()  # get_rect返回一个矩形rect对象
        self.rect.topleft = hero_init_position  # 矩形位置(定左上角的位置)

添加玩家战斗机

'载入飞机图片'
# 玩家战斗机
player_plane_image = pygame.image.load('resources/images/feiji.png')

创建玩家

# 创建玩家
hero = Hero(player_plane_image, [200, 400])

在主事件循环中绘制玩家飞机

    # 绘制玩家飞机
    screen.blit(hero.image, hero.rect)

3、让飞机变成动态

为了让飞机看起来更形象,我们利用图片切割,对飞机进行动态处理。原理是把一张图片根据位置取出特定区域的图像,形成若干张不同的图片,加载图片时这几张图片循环加载,营造出动态的样子。这里为了简便,只切割两张图片切换。
加载并切割图片,切割好的图片用列表存储,方便进行切换:

'载入玩家战斗机'
# 玩家战斗机图片
player_plane_image = pygame.image.load('resources/images/feiji.png')
# 取出不带火焰的飞机部分
player_plane_imageA = player_plane_image.subsurface(pygame.Rect(0, 0, 102, 89))
# 取出带火焰的飞机部分
player_plane_imageB = player_plane_image.subsurface(pygame.Rect(0, 0, 102, 109))
# 用列表存储图像
player_plane_images = []
player_plane_images.append(player_plane_imageA)
player_plane_images.append(player_plane_imageB)

因为要切换图片,所以需要记录循环数,根据循环数进行图片切换:

# 计数,根据计数做一些定时操作
tick = 0

在主循环中进行图片切换:

    # 根据计数切换飞机图片
    if tick % 41 == 0:
        hero.image = player_plane_images[tick % 2]
    # 绘制玩家飞机
    screen.blit(hero.image, hero.rect)
    # 更新计数
    tick = tick + 1

完成后的样子:
在这里插入图片描述

4、移动飞机

在Hero类设定移动速度:

self.speed = 2

并添加move方法:

    def move(self, offset):
        self.rect.left = self.rect.left + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
        self.rect.top = self.rect.top + offset[pygame.K_DOWN] - offset[pygame.K_UP]

用字典存储上、下、左、右四个按键,值为移动值

# 设置按键状态,用字典存储。字典中存储的键是前后左右四个按键值,后面数字对相应该方向移动距离
offset = {pygame.K_LEFT: 0, pygame.K_RIGHT: 0, pygame.K_UP: 0, pygame.K_DOWN: 0}

在按键监听中处理按键事件

        # 按键按下
        if event.type == pygame.KEYDOWN:
            # 是否在offset字典中,即按下的是否是前后左右四个键
            if event.key in offset:
                # 在的话,将该方向的移动值设置为相应的值
                offset[event.key] = hero.speed
        # 按键松开
        if event.type == pygame.KEYUP:
            # 是否在offset字典中,即按下的是否是前后左右四个键
            if event.key in offset:
                # 在的话,将该方向的移动值归0
                offset[event.key]=0

在主循环中调用Hero的移动方法:

    # 调用移动方法
    hero.move(offset)

5、设置飞机移动范围

更改move方法:

    def move(self, offset):
        x = self.rect.left + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
        y = self.rect.top + offset[pygame.K_DOWN] - offset[pygame.K_UP]
        # 若最左边坐标小于0,即出左边界,设为0
        if x < 0:
            self.rect.left = 0
        # 若最左边坐标大于界面宽度-飞机宽度,即出右边界,设为右边界值
        elif x > SCREEN_WIDTH - self.rect.width:
            self.rect.left = SCREEN_WIDTH - self.rect.width
        # 其他即为正常情况
        else:
            self.rect.left = x
        # 若最上边坐标小于0,即出上边界,设为0
        if y < 0:
            self.rect.top = 0
        # 若最上边坐标大于界面高度-飞机高度,即出下边界,设为下边界值
        elif y > SCREEN_HEIGHT - self.rect.height:
            self.rect.top = SCREEN_HEIGHT - self.rect.height
        # 其他视为正常情况
        else:
            self.rect.top = y

三、总结

1、目前完成界面状态

在这里插入图片描述

2、目前目录

在这里插入图片描述

3、目前代码

GameMain.py

import pygame
from sys import exit
from Hero import Hero

# 计数,根据计数做一些定时操作
tick = 0
# 设置按键状态,用字典存储。字典中存储的键是前后左右四个按键值,后面数字对相应该方向移动距离
offset = {pygame.K_LEFT: 0, pygame.K_RIGHT: 0, pygame.K_UP: 0, pygame.K_DOWN: 0}
'''初始化界面'''
# 窗口分辨率
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 640
# 载入背景图片
background_img = pygame.image.load('resources/images/background.png')
'载入玩家战斗机'
# 玩家战斗机图片
player_plane_image = pygame.image.load('resources/images/feiji.png')
# 取出不带火焰的飞机部分
player_plane_imageA = player_plane_image.subsurface(pygame.Rect(0, 0, 102, 89))
# 取出带火焰的飞机部分
player_plane_imageB = player_plane_image.subsurface(pygame.Rect(0, 0, 102, 109))
# 用列表存储图像
player_plane_images = []
player_plane_images.append(player_plane_imageA)
player_plane_images.append(player_plane_imageB)
# 玩家飞机出现位置
hero_position = [200, 400]
# 创建玩家
hero = Hero(player_plane_image, hero_position)
# 初始化pygame
pygame.init()
# 初始化窗口
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
# 设置窗口标题
pygame.display.set_caption('飞机大战')

'''事件循环'''
while True:
    # 绘制背景
    screen.blit(background_img, (0, 0))
    # 根据计数切换飞机图片
    if tick % 41 == 0:
        hero.image = player_plane_images[tick % 2]
    # 绘制玩家飞机
    screen.blit(hero.image, hero.rect)
    # 更新计数
    tick = tick + 1
    # 更新屏幕
    pygame.display.update()
    # 处理按键
    for event in pygame.event.get():
        # 游戏退出
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        # 按键按下
        if event.type == pygame.KEYDOWN:
            # 是否在offset字典中,即按下的是否是前后左右四个键
            if event.key in offset:
                # 在的话,将该方向的移动值设置为相应的值
                offset[event.key] = hero.speed
        # 按键松开
        if event.type == pygame.KEYUP:
            # 是否在offset字典中,即按下的是否是前后左右四个键
            if event.key in offset:
                # 在的话,将该方向的移动值归0
                offset[event.key]=0
    # 调用移动方法
    hero.move(offset)

Hero.py

    def move(self, offset):
        x = self.rect.left + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
        y = self.rect.top + offset[pygame.K_DOWN] - offset[pygame.K_UP]
        # 若最左边坐标小于0,即出左边界,设为0
        if x < 0:
            self.rect.left = 0
        # 若最左边坐标大于界面宽度-飞机宽度,即出右边界,设为右边界值
        elif x > SCREEN_WIDTH - self.rect.width:
            self.rect.left = SCREEN_WIDTH - self.rect.width
        # 其他即为正常情况
        else:
            self.rect.left = x
        # 若最上边坐标小于0,即出上边界,设为0
        if y < 0:
            self.rect.top = 0
        # 若最上边坐标大于界面高度-飞机高度,即出下边界,设为下边界值
        elif y > SCREEN_HEIGHT - self.rect.height:
            self.rect.top = SCREEN_HEIGHT - self.rect.height
        # 其他视为正常情况
        else:
            self.rect.top = y

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值