【python】飞机大战小游戏练习


前言:本篇是作为博主学习python语言之后的练习,CSDN上关于飞机大战游戏的代码很多,本篇的代码也只是其中一种思路,希望对大家的学习有所帮助

一、前提准备

  • 运行环境:pycharm,安装教程:http://www.javatiku.cn/pycharm.html
  • 使用的类库 pygame, 联网的情况下,pycharm内的终端命令行输入:
    pip install pygame
  • 使用素材图片(游戏的加载图片,我会放在上传的代码文件内)
  • python基础(至少学完类与对象)

完整代码下载:【python】飞机大战小游戏代码

提醒:本篇大部分是pygame库的使用,讲解很少


二、制作步骤

1、库的导入与初始化

#导入模块
import pygame

#对pygame进行实例化
pygame.init()

2、窗口操作

#导入模块
import pygame

#对pygame进行实例化
pygame.init()

#创立窗口 set_mode(400, 400)
pygame.display.set_mode([400, 400])

#设置游戏标题
pygame.display.set_caption("飞机大战")

#加载本地图片
pygame.image.load("res/app.ico")

3、键盘按键监听相关操作

#导入模块
import pygame
import sys

#对pygame进行实例化
pygame.init()

#创立窗口 set_mode(400, 400)
pygame.display.set_mode([400, 400])

#设置游戏标题
pygame.display.set_caption("飞机大战")

#加载本地图片
load_image = pygame.image.load("res/app.ico")

#设置窗口图片
pygame.display.set_icon(load_image)

#在死循环中监听事件
while True:
    #获取所有监听事件,监听的事件放入列表内
    event_list = pygame.event.get()
    #循环遍历列表
    for event in event_list:
        if event.type == pygame.QUIT:
            #退出游戏
            pygame.quit()
            #退出程序
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                # 退出游戏
                pygame.quit()
                # 退出程序
                sys.exit()
    #监听键盘长按事件
    passed_keys = pygame.key.get_pressed()

    #判断是否是向上按键长按
    if passed_keys[pygame.K_UP] or passed_keys[pygame.K_w]:
        print("向上")

    #判断是否是向下按键长按
    if passed_keys[pygame.K_DOWN] or passed_keys[pygame.K_s]:
        print("向下")

    # 判断是否是向左按键长按
    if passed_keys[pygame.K_LEFT] or passed_keys[pygame.K_a]:
        print("向左")

    #判断是否是向右按键长按
    if passed_keys[pygame.K_RIGHT] or passed_keys[pygame.K_d]:
        print("向右")

实现效果:
在这里插入图片描述


4、添加游戏背景

#导入模块
import pygame
import sys

#对pygame进行实例化
pygame.init()

#创立窗口 set_mode(400, 400)
window = pygame.display.set_mode([512, 768])

#设置游戏标题
pygame.display.set_caption("飞机大战")

#加载本地图片
load_image = pygame.image.load("res/app.ico")

#设置窗口图片
pygame.display.set_icon(load_image)

#加载游戏背景
bg_image = pygame.image.load("res/img_bg_level_2.jpg")

#添加到游戏内
window.blit(bg_image, (0, 0))

#刷新窗口
pygame.display.update()

#在死循环中监听事件
while True:
    #获取所有监听事件,监听的事件放入列表内
    event_list = pygame.event.get()
    #循环遍历列表
    for event in event_list:
        if event.type == pygame.QUIT:
            #退出游戏
            pygame.quit()
            #退出程序
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                # 退出游戏
                pygame.quit()
                # 退出程序
                sys.exit()
    #监听键盘长按事件
    passed_keys = pygame.key.get_pressed()

    #判断是否是向上按键长按
    if passed_keys[pygame.K_UP] or passed_keys[pygame.K_w]:
        print("向上")

    #判断是否是向下按键长按
    if passed_keys[pygame.K_DOWN] or passed_keys[pygame.K_s]:
        print("向下")

    # 判断是否是向左按键长按
    if passed_keys[pygame.K_LEFT] or passed_keys[pygame.K_a]:
        print("向左")

    #判断是否是向右按键长按
    if passed_keys[pygame.K_RIGHT] or passed_keys[pygame.K_d]:
        print("向右")

实现效果:
在这里插入图片描述


5、加载玩家飞机

#导入模块
import pygame
import sys

#对pygame进行实例化
pygame.init()

#创立窗口 set_mode(400, 400)
window = pygame.display.set_mode([512, 768])

#设置游戏标题
pygame.display.set_caption("飞机大战")

#加载本地图片
load_image = pygame.image.load("res/app.ico")

#设置窗口图片
pygame.display.set_icon(load_image)

#加载游戏背景
bg_image = pygame.image.load("res/img_bg_level_2.jpg")

#加载飞机背景
hero_image = pygame.image.load("res/hero2.png")

#添加到游戏内
window.blit(bg_image, (0, 0))
window.blit(hero_image, (0, 0))

#刷新窗口
pygame.display.update()

#在死循环中监听事件
while True:
    #获取所有监听事件,监听的事件放入列表内
    event_list = pygame.event.get()
    #循环遍历列表
    for event in event_list:
        if event.type == pygame.QUIT:
            #退出游戏
            pygame.quit()
            #退出程序
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                # 退出游戏
                pygame.quit()
                # 退出程序
                sys.exit()
    #监听键盘长按事件
    passed_keys = pygame.key.get_pressed()

    #判断是否是向上按键长按
    if passed_keys[pygame.K_UP] or passed_keys[pygame.K_w]:
        print("向上")

    #判断是否是向下按键长按
    if passed_keys[pygame.K_DOWN] or passed_keys[pygame.K_s]:
        print("向下")

    # 判断是否是向左按键长按
    if passed_keys[pygame.K_LEFT] or passed_keys[pygame.K_a]:
        print("向左")

    #判断是否是向右按键长按
    if passed_keys[pygame.K_RIGHT] or passed_keys[pygame.K_d]:
        print("向右")

实现效果:
在这里插入图片描述


6、获取玩家飞机矩阵

得到飞机图片长宽与游戏背景上的坐标

# 获取玩家飞机矩阵
hero_iamge_rect = hero_image.get_rect()
#hero_iamge_rect[0]:x轴坐标
#hero_iamge_rect[1]:y轴坐标
#hero_iamge_rect[2]:飞机图片的长
#hero_iamge_rect[3]:飞机图片的宽

三、完整代码编写

游戏背景类编写

game_map.py:

import pygame, sys ,random

WINDOW_WIDTH, WINDOW_HEIGHT = 512, 768

class GameMap(object):

    #定义地图初始化
    def __init__(self):

        #获取五张图片中的任何一张图片
        self.num = str(random.randint(1, 5))

        #加载游戏背景
        self.img1 = pygame.image.load("res/img_bg_level_" + self.num + ".jpg")
        self.img2 = pygame.image.load("res/img_bg_level_" + self.num + ".jpg")

        #设置游戏背景的Y轴
        self.img1_y = -WINDOW_HEIGHT
        self.img2_y = 0

        #游戏背景滑动速度
        self.speed = 0.5

    #游戏背景向下滑动
    def move_down(self):
        if self.img1_y >= 0:
            self.img1_y = -WINDOW_HEIGHT
            self.img2_y = 0

        self.img1_y += self.speed
        self.img2_y += self.speed

子弹类的编写

plane_bullet:

import pygame, sys

WINDOW_WIDTH, WINDOW_HEIGHT = 512, 768


#自定义子弹类
class PlaneBullet(object):

    def __init__(self):
        #加载子弹图片
        self.img = pygame.image.load("res/bullet_10.png")
        #获取子弹矩阵
        self.img_rect = self.img.get_rect()
        #设置子弹状态
        self.is_shot = False
        #设置子弹状态
        self.speed = 1

    #子弹向上移动
    def move_up(self):
        self.img_rect[1] -= self.speed

        #判断子弹是否完全到窗口外
        if self.img_rect[1] <= - self.img_rect[3]:
            #子弹回归未发射状态
            self.is_shot = False

玩家飞机类的编写

hero_plane.py:

import pygame, sys ,random, plane_bullet

WINDOW_WIDTH, WINDOW_HEIGHT = 512, 768

#自定义飞机类
class HeroPlane(object):

    #初始化飞机类
    def __init__(self):
        #加载飞机图片
        self.img = pygame.image.load('res/hero2.png')
        #获取飞机矩阵
        self.img_rect = self.img.get_rect()
        #设置飞机初始位置
        self.img_rect.move_ip((WINDOW_WIDTH - self.img_rect[2])/2, WINDOW_HEIGHT - self.img_rect[3] -50)

        #飞机移动速度
        self.speed = 1

        #定义子弹夹
        self.bullet_list = [plane_bullet.PlaneBullet() for i in range(6)]

    #飞机向上
    def move_up(self):
        #边缘检测
        if self.img_rect[1] >= 0:
            self.img_rect.move_ip(0, -self.speed)

    # 飞机向下
    def move_down(self):
        # 边缘检测
        if self.img_rect[1] < WINDOW_HEIGHT - self.img_rect[3]:
            self.img_rect.move_ip(0, self.speed)

    # 飞机向左
    def move_left(self):
        # 边缘检测
        if self.img_rect[0] > 0:
            self.img_rect.move_ip(-self.speed, 0)

    # 飞机向右
    def move_right(self):
        # 边缘检测
        if self.img_rect[0] < WINDOW_WIDTH - self.img_rect[2]:
            self.img_rect.move_ip(self.speed, 0)

    #发射子弹
    def shot(self):
        for bullet in self.bullet_list:
            if not bullet.is_shot:
                bullet.img_rect[0] = self.img_rect[0] + ((self.img_rect[2] - bullet.img_rect[2])/2)
                bullet.img_rect[1] = self.img_rect[1] - self.img_rect[3]

                bullet.is_shot = True
                #一次只发射一颗子弹
                break

敌机类的编写

enemy_plane.py:

import pygame, random

WINDOW_WIDTH, WINDOW_HEIGHT = 512, 768

#定义一个敌机类
class Enemy_plane(object):

    def __init__(self):
        #获取随机数,根据素材敌机图片决定
        self.num = str(random.randint(1, 6))

        #加载敌机图片
        self.img =  pygame.image.load("res/img-plane_" + self.num + ".png")

        #得到敌机图片矩阵
        self.img_rect = self.img.get_rect()
        self.reset()

    #设置敌机速度与位置
    def reset(self):
        #设置敌机位置
        self.img_rect[0] = random.randint(0, WINDOW_WIDTH-self.img_rect[3])
        self.img_rect[1] = -self.img_rect[3]

        #设置敌机速度
        self.speed = random.randint(1, 2)

    def move_down(self):
        self.img_rect.move_ip(0, self.speed)
        #如果敌机跑到屏幕外后,重置敌机
        if self.img_rect[1] >= WINDOW_HEIGHT:
            self.reset()

得分类的编写

game_score.py:

import pygame, random

#自定义得分类
class GameScore(object):

    # 记录分数
    __cls_scoce = 0

    def __init__(self, font_size):
        #设置字体和大小
        self.font = pygame.font.SysFont("SimHei", font_size)
        ## render(text(文本内容), antialias(抗锯齿), color(RGB)),返回文字对象
        self.text_obj = self.font.render("分数:0", 1, (255, 255, 255))

    def set_text_obj(self):
        #加分
        GameScore.__cls_scoce += 5
        #设置颜色随机值
        r = random.randint(0, 255)
        g = random.randint(0, 255)
        b = random.randint(0, 255)

        #重新赋值
        self.text_obj = self.font.render("分数:%d" %GameScore.__cls_scoce, 1, (r, g, b))

整合类以及运行

game_main.py:

import pygame, sys ,random, enemy_plane, game_map, game_score, hero_plane, plane_bullet

WINDOW_WIDTH, WINDOW_HEIGHT = 512, 768

#自定义游戏窗口管理类
class GameWindow(object):
    def __init__(self):
        # 对pygame进行实例化
        pygame.init()

        pygame.mixer.music.load("./res/bg2.ogg")

        # 循环播放背景音乐
        pygame.mixer.music.play(-1)

        # 加载音效
        self.boom_sound = pygame.mixer.Sound("./res/baozha.ogg")

        # 创立窗口 set_mode(400, 400)
        self.window = pygame.display.set_mode([512, 768])

        # 设置游戏标题
        pygame.display.set_caption("飞机大战")

        # 加载本地图片
        self.load_image = pygame.image.load("res/app.ico")

        # 设置loge图片
        pygame.display.set_icon(self.load_image)

        # 游戏背景类设置
        self.map = game_map.GameMap()

        # 玩家飞机添加
        self.hero_plane = hero_plane.HeroPlane()

        #创建敌机对象
        self.enemy_list = [enemy_plane.Enemy_plane() for i in range(6)]

        #创建得分对象
        self.score = game_score.GameScore(35)

    # 处理各类矩阵坐标移动
    def __action(self):
        #地图移动
        self.map.move_down()
        #子弹移动
        for bullet in self.hero_plane.bullet_list:
            if bullet.is_shot:
                bullet.move_up()
        #敌机移动
        for enemy in self.enemy_list :
            enemy.move_down()

    #根据矩阵坐标进行重新绘制
    def __draw(self):
        #游戏地图绘制
        self.window.blit(self.map.img1, (0, self.map.img1_y))
        self.window.blit(self.map.img2, (0, self.map.img2_y))
        #游戏玩家飞机绘制
        self.window.blit(self.hero_plane.img, (self.hero_plane.img_rect[0], self.hero_plane.img_rect[1]))
        #子弹绘制
        for bullet in self.hero_plane.bullet_list:
            if bullet.is_shot:
                self.window.blit(bullet.img, (bullet.img_rect[0], bullet.img_rect[1]))
        #敌机位置绘制
        for enemy in self.enemy_list:
            self.window.blit(enemy.img, (enemy.img_rect[0], enemy.img_rect[1]))

        #敌机与子弹碰撞事件判断
        self.__bullet_hit_enemy()

        # 添加文字
        self.window.blit(self.score.text_obj, (10, 10))
    #事件监听处理
    def __event(self):
        # 获取所有监听事件,监听的事件放入列表内
        event_list = pygame.event.get()
        # 循环遍历列表
        for event in event_list:
            if event.type == pygame.QUIT:
                self.game_over()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.game_over()
                if event.key == pygame.K_SPACE:
                    self.hero_plane.shot()
        # 监听键盘长按事件
        passed_keys = pygame.key.get_pressed()

        # 判断是否是向上按键长按
        if passed_keys[pygame.K_UP] or passed_keys[pygame.K_w]:
            self.hero_plane.move_up()

        # 判断是否是向下按键长按
        if passed_keys[pygame.K_DOWN] or passed_keys[pygame.K_s]:
            self.hero_plane.move_down()

        # 判断是否是向左按键长按
        if passed_keys[pygame.K_LEFT] or passed_keys[pygame.K_a]:
            self.hero_plane.move_left()

        # 判断是否是向右按键长按
        if passed_keys[pygame.K_RIGHT] or passed_keys[pygame.K_d]:
            self.hero_plane.move_right()

    #更新游戏画面
    def __update(self):
        pygame.display.update()

    #敌机与子弹碰撞事件
    def __bullet_hit_enemy(self):
        #遍历子弹
        for bullet in self.hero_plane.bullet_list:
            if bullet.is_shot:
                #遍历敌机
                for enemy in self.enemy_list:
                    #判读是否碰撞
                    flag = pygame.Rect.colliderect(bullet.img_rect, enemy.img_rect)
                    #如果碰撞
                    if flag:
                        #子弹消失
                        bullet.is_shot = False
                        #敌机消失
                        enemy.reset()
                        #播放音效
                        self.boom_sound.play()
                        #得分增加
                        self.score.set_text_obj()

    #退出游戏
    def game_over(self):
        # 退出游戏
        pygame.quit()
        # 退出程序
        sys.exit()

    #运行游戏
    def run(self):
        while True:
            self.__action()
            self.__draw()
            self.__event()
            self.__update()

#主函数
def main():
    game_window = GameWindow()
    game_window.run()

if __name__ == '__main__':
    main()

四、游戏效果

在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

修成真

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

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

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

打赏作者

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

抵扣说明:

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

余额充值