上一节我们创建了一个按钮,现在我们要把按钮利用起来,现在我们需要三个界面:

  1. 游戏主界面:提供游戏的开始和退出
  2. 游戏界面:显示贪吃蛇以及游戏
  3. 游戏失败界面:贪吃蛇死亡后显示的界面

回想一下界面的整个流程,现在我们需要开始正式写了,我们需要一个主程序,来控制各种界面的切换,以及需要三个界面,控制界面的显示等事务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class View:
screen = None

"""
界面初始化
"""
def __init__(self, screen):
self.screen = screen

"""
界面绘制处理
"""
def on_draw(self):
pass

"""
界面事件分发
"""
def on_event(self, event):
pass

一个界面至少要包含两个方法,用来处理绘制和事件,现在我们来写第一个界面,这个界面为主界面,用来显示开始游戏和退出按键,以及显示一个游戏大图, 实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class MainView(View):

logo = None
btn_start = None
btn_exit = None
context = None

def __init__(self, context):
self.btn_start = Button('Start Game', self._on_start)
self.btn_exit = Button('Exit Game', self._on_exit)
self.context = context
self.logo = pygame.image.load('img/logo.png')
w, h = self.logo.get_size()
# 调整界面适应 Logo 大小以及显示按钮
self.context.screen = pygame.display.set_mode(
(int(w * 1.5), int(h * 2)), 0, 32)
# 设置界面标题
pygame.display.set_caption('Python Snake Game v1.0')
View.__init__(self, context.screen)

def on_draw(self):
# 绘制界面
self._on_draw()
# 绘制按钮
self.btn_start.on_draw(self.context.screen)
self.btn_exit.on_draw(self.context.screen)

def on_event(self, event):
# 监控各种事件
self.btn_start.on_event(event)
self.btn_exit.on_event(event)

def _on_exit(self):
# 控制退出状态
print('exit game')
self.context.running = False

def _on_start(self):
# 切换界面到游戏界面
print('start game')
self.context.view = GameView(self.context)

def _on_draw(self):
'''
计算各个按钮的位置以及Logo的位置
'''
s_w, s_h = self.context.screen.get_size()
l_w, l_h = self.logo.get_size()
x, y, bs_w, bs_h = self.btn_start.get_box()
x, y, be_w, be_h = self.btn_exit.get_box()
y_start = l_h + 50
'''
界面元素排版
'''
self.btn_start.pos = (s_w/2 - bs_w / 2, y_start)
self.btn_exit.pos = (s_w/2 - be_w / 2, y_start + bs_h + 4)
self.context.screen.blit(self.logo, (s_w/2-l_w/2, s_h/2-l_h/2))

为了使界面能够正常显示,我们添加一个 Game 类来控制游戏以及界面的显示,控制界面的显示与操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import pygame
from pygame import QUIT
from pygameui import Button
from views import MainView


class Game:
# 运行状态
running = True
GAME_START = 0
GAME_OVER = 1
# 屏幕状态
screen = None
# 显示界面
view = None
# 运行时钟
clock = None

def __init__(self):
pygame.init()
# 初始化基础界面
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((300, 150), 0, 32)
self.view = MainView(self)

def run(self):
while self.running:
for event in pygame.event.get():
# 分发界面事件
self.view.on_event(event)
if event.type == QUIT:
self.running = False
self.screen.fill((0xff, 0xff, 0xff))
# 调用界面显示
self.view.on_draw()
pygame.display.flip()
self.clock.tick(60)


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

全部代码: https://github.com/DXkite/python-snake-game-demo/tree/master/07-snake-frame

运行界面