Notification:我不是专门写Python的,只是看到这个拓展有点好玩,有什么不规范的地方,还请批评指正
1. 目录结构
├── action
│ ├── boom.py # 炸弹类
│ ├── game.py # 游戏全局类
│ ├── main.py # 实体入口类
│ ├── plane.py # 飞机类
│ └── target.py # 目标船只类
├── conf
│ ├── score.py # 记分板
│ └── settings.py # 配置文件
├── event
│ └── event_function.py # 事件监控
├── main.py # 入口文件 完成编码后在次页执行run
└── plugs
├── shape_function.py # 在画布上展示图形
└── text_function.py # 在画布上书写文字
2、前提
使用python制作小游戏,需要安装 pygame 拓展,我比较懒,所以一般直接使用pip命令安装,这里也是一样
pip install pygame # 我使用的是anaconda自带的控制台
3、环境
我比较喜欢用jet brains的产品,于是我这里使用的是pycharm
4、思路
此次试水开发的小游戏很简陋,初中的时候,微机课,电脑上只有一个展示平抛运动的小游戏,在这里,我就用最简单的方法重现。
5、编码
5.1、首先是入口文件
# 路径 ./main.py
import pygame
import event.event_function as ef
from conf.settings import Settings
from action.main import Main
# 初始化
pygame.init()
# 读取基础配置
settings = Settings() # 配置文件其实也是个python类(5.2)
# 初始化游戏北京
screen = pygame.display.set_mode((settings.screen_width,settings.screen_height))
# 初始化基础背景色
screen.fill(settings.screen_color)
# 初始化各种对象 这是我的编码习惯(使用一个对象包容其他对象)(5.3)
main = Main()
while True:
#事件监控
ef.main_event(main)
#刷新
screen.fill(settings.screen_color)
#动作
main.action(screen)
#刷新
pygame.display.update()
5.2、然后是配置文件
# 路径 ./conf/settings.py
class Settings:
def __init__(self):
#全局配置
#游戏名
self.game_name = 'Plane Boom'
#游戏屏宽
self.screen_width = 1200
#游戏屏高
self.screen_height = 800
#游戏主背景色
self.screen_color = (0,0,0)
#关于飞机的配置
#飞机水平飞行速度
self.plane_speed = 5
#飞机距离上边界的距离
self.plane_height = 50
#关于飞机投掷炸弹的配置
#炸弹下落的重力加速度(如果太大 不利于监测爆炸事件)
self.boom_g = .5
#系统刷新需要增加的时间
self.boom_time_add = .5
#炸弹的爆炸范围
self.boom_range = 50
#目标船只的配置
#船距离上边界的距离
self.boat_top = 650
#可以生成船的初始水平位置
self.boot_range_start = 300
#可以生成船的结束水平位置
self.boot_range_end = 1200
5.3、所有类的主入口类
# 路径 ./action/main.py
from action.game import Game
from action.target import Target
from action.plane import Plane
from action.boom import Boom
from conf.score import Base
class Main:
def __init__(self):
#初始化所有类 方便对类中属性的修改 同时也保证整个系统之 所有类只有一个对象
self.game = Game() # (5.4)
self.target = Target() # (5.5)
self.plane = Plane() #(5.6)
self.boom = Boom() #(5.7)
self.base = Base() #(5.8)
# 供入口文件调用
def action(self,screen):
self.game.action(screen)
self.target.action(screen)
self.plane.action(screen)
self.boom.action(screen,self)
self.base.action(screen)
5.4、全局类
# 5.4 - 5.7 全部位于action目录下
import plugs.text_function as tf
class Game:
def __init__(self):
# 游戏是否开始
self.open = False
# 主要用来控制游戏的开始与结束
def action(self,screen):
if not self.open:
# 大标题
tf.draw_main_title(screen,'PLANE BOOM')
# 小标题
tf.draw_sub_title(screen,'press space to continue')
if self.open:
# 提示语
tf.draw_tips(screen,'press esc to end the game')
5.5、目标船只类
import random
import plugs.shape_function as sf
from conf.settings import Settings
class Target:
def __init__(self):
#读取配置文件
self.settings = Settings()
# 船的初始位置
self.left = -100
self.top = self.settings.boat_top
#判断是否已经存在一艘船(或者可以理解为本艘船是否存在)
self.has_one = False
def action(self,screen):
# 逻辑:当屏幕上没有小船的时候 则随机一个小船的水平位置 如果有则跳过
if not self.has_one:
self.left = random.uniform(self.settings.boot_range_start,self.settings.boot_range_end)
self.has_one = True
#出现draw的基本都为plugs中的函数
sf.draw_boat(screen,self.left,self.top)
5.6、飞机类
import plugs.shape_function as sf
from conf.settings import Settings
class Plane:
def __init__(self):
#与setting有关的 参考配置文件
self.settings = Settings()
self.speed = self.settings.plane_speed
self.top = self.settings.plane_height
self.left = 0
def action(self,screen):
#逻辑 飞机循环飞行 从左到右
sf.draw_plane(screen,self.left,self.top)
if self.left >= self.settings.screen_width:
self.left = 0
else:
self.left += self.speed
5.7、炸弹类
# 这个类是最复杂的
# 此处假设Boom只能有一个
import plugs.shape_function as sf
from conf.settings import Settings
class Boom:
def __init__(self):
self.settings = Settings()
self.left = -100
self.top = -100
# 判断是否需要创建一颗炸弹
self.init_a_boom = False
# 判断本炸弹是否存在
self.has_one = False
# 炸弹的水平速度
self.speed_x = 0
# 累计下落时间
self.time = 0
# 判断炸弹是否需要爆炸
self.need_explode = False
def action(self,screen,main):
# 初始化一颗炸弹
if self.init_a_boom and not self.has_one:
# 出生位置水平跟随飞机
self.left = main.plane.left
# 不再需要初始化
self.init_a_boom = False
# 已经有了一颗
self.has_one = True
# 获取水平速度
self.speed_x = main.plane.speed
# 获取竖直高度
self.top = main.plane.top
# 后台提示
print('开始投弹')
# 判断是否需要移动炸弹
if self.has_one:
# 水平位移
self.left += self.speed_x
# 竖直位移
self.top = main.plane.top + 0.5*self.settings.boom_g*self.time*self.time
# 时间流逝
self.time += self.settings.boom_time_add
# print(self.top,self.time)
# 刷新炸弹
sf.draw_boom(screen,self.left,self.top)
# print(main.target.top - self.settings.boom_range,self.top,main.target.top - self.settings.boom_range,main.target.top,self.left,main.target.left)
# 炸弹是否击中目标
if (main.target.top - self.settings.boom_range <= self.top <= main.target.top + self.settings.boom_range) and (
main.target.left - self.settings.boom_range <= self.left <= main.target.left + self.settings.boom_range):
# 引爆
self.need_explode = True
print('击中目标')
# 没了
main.target.has_one = False
# 加分
main.base.score += 1
# 炸弹越界或者集中目标需要爆炸
if self.top > self.settings.screen_height or self.need_explode:
# 没了
self.has_one = False
# 等待下一颗炸弹的初始化
self.init_a_boom = False
# 已经爆炸了 为下一次准备
self.need_explode = False
# 时间清零
self.time = 0
print('炸弹爆炸')
5.8、记分板
# ./conf/score
class Base:
def __init__(self):
self.score = 0
def action(self,screen):
import plugs.text_function as tf
tf.draw_score(screen,self.score)
5.9、事件监听
# 监听键盘事件 进行反馈
import pygame
import sys
def main_event(main):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#监控按下按钮事件
if event.type == pygame.KEYDOWN:
press_down(event,main)
# 按下事件
def press_down(event,main):
# 空格
if event.key == pygame.K_SPACE:
print('开始游戏')
main.game.open = True
main.boom.init_a_boom = True
# esc
if event.key == pygame.K_ESCAPE:
print('退出游戏')
main.game.open = False
6、启动
在./main.py文件中右键 run 就可以跳出一个窗体尽兴玩耍了
网友评论