“笨办法”学Python 3基础篇 - 搭建简易的网站
2021/5/7 20:28:23
本文主要是介绍“笨办法”学Python 3基础篇 - 搭建简易的网站,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
“笨办法”学Python 3基础篇系列文章
“笨办法”学Python 3基础篇 第一部分-打印与输入
“笨办法”学Python 3基础篇 第二部分-文件操作
“笨办法”学Python 3基础篇 第三部分-函数
“笨办法”学Python 3基础篇 第四部分-数据容器与程序结构
“笨办法”学Python 3基础篇 第五部分-面向对象的类
“笨办法”学Python 3基础篇 第六部分-项目骨架与自动测试
“笨办法”学Python 3基础篇 第七部分-搭建简易的网站
搭建简易的网站
- “笨办法”学Python 3基础篇系列文章
- 前言
- 7.1 Web框架-flask安装和项目创建
- 7.2 利用面向对象方法设计三体游戏
- 7.3 编写game.py的自动测试脚本
- 7.4 编写HTML模板
- 7.5 创建三体web游戏引擎
- 7.6 游戏运行效果
- 结语
前言
终于来到了本系列的最后一篇了,有点小兴奋。虽然中间间隔了很多时间,但每一次码字都让我懂得了坚持和总结带来的好处,都能够再一次地对原来储存在脑海中某个角落的知识进行重构,变成自己知识大厦中的地基,脑子也在每次总结中进行了一次精神地“按摩”。
在本文中,我将用面向对象的编程方法编写一个对话类的三体小游戏(章北海作为主角),并通过flask创建简单的游戏网站(目前只学到这)。
7.1 Web框架-flask安装和项目创建
要使用网站服务,需要安装一个“Web”框架,减少开发负担。在书中,主要介绍了flask框架的应用。在激活虚拟环境后,通过
pip install flask
实现安装,安装过程如下图:
flask安装完成后,需要创建一个threebody项目,在PowerShell中输入如下命令:
cd projects mkdir threebody cd threebody mkdir bin mkdir threebody mkdir tests mkdir docs mkdir templates new-item -type file .\threebody\__init__.py new-item -type file .\tests\__init__.py
与之前项目创建不同的是,新建了一个名为“templates”的目录,用于存放网站的html模板。
7.2 利用面向对象方法设计三体游戏
在threebody\threebody目录下新建一个game.py作为三体游戏的主程序。整个三体游戏的设计思路是通过场景切换进行的,游戏者通过做出选择进入不同剧情,类似《秋之回忆》之类的游戏。程序的核心为类Scene的设计,代码具体为:
class Scene: """基本场景类""" def __init__(self, name, description): self.name = name self.description = description self.paths = {} def enter(self, direction): return self.paths.get(direction, None) def add_paths(self, paths): self.paths.update(paths)
每个场景作为对象对类Scene进行初始化。初始化时渲染场景的名字和剧情描述,并初始化决定剧情走向的字典paths。通过enter(direction)函数返回direction指定的场景对象,通过add_paths(paths)函数来更新剧情走向字典paths,从而建立不同场景对象的剧情联系。关于剧情的走向脉络如下图所示:
游戏剧情从自然选择号开始,到太空陵墓结束。中间每个场景如果选择错误,就会进入死亡场景(根据剧情不同,死亡场景还需要细分)。在死亡场景中可以通过选择play again重玩游戏。这一剧情流向通过Scene中的add_paths实现。具体代码如下:
natureSelectionFleet.add_paths({ '1': death_1_1, '2': death_1_2, '3': death_1_3, '4': escape, '*': natureSelectionFleet }) escape.add_paths({ '1': death_2, '2': death_2, '3': death_2, '4': control_terminal, '*': escape }) control_terminal.add_paths({ '1': extrasolar, '2': death_3, '3': death_3, '4': death_3, '*': control_terminal }) extrasolar.add_paths({ '1': fleet_earth, '2': death_2, '3': death_4, '*': extrasolar }) fleet_earth.add_paths({ '1': death_2, '2': ultimate_rule_fleet, '3': ultimate_rule_fleet, '*': fleet_earth }) ultimate_rule_fleet.add_paths({ '1': blue_space_fleet, '2': death_6, '3': death_5, '4': death_2, '*': ultimate_rule_fleet }) blue_space_fleet.add_paths({ '1': last_episode, '2': death_6, '*': blue_space_fleet })
这里的*代表玩家的无效输入,无效输入时,剧情场景不切换,停留在原场景中。剩下的工作是设计不同的场景对象,具体的代码为:
#自然选择号死亡场景 death1 = """ 自然选择号在与三体文明'水滴'探测器的激战中被摧毁...... """ death_1_1 = Scene("游戏失败", f""" 原来你也接收了思想钢印。 警卫员! 马上逮捕章北海! {death1} """) death_1_2 = Scene("游戏失败", f""" 章北海,你这个懦夫! 你的内心充分暴露出来了,表面是个人类必胜论者, 内心确是一个失败论者。 警卫员! 马上逮捕章北海! {death1} """) death_1_3 = Scene("游戏失败", f""" 你是云天明? 警卫员! 马上通知地球舰队! {death1} """) death_2 = Scene("游戏失败", death1) death_3 = Scene("游戏失败", f""" 飞船控制失败! {death1} """ ) death_4 = Scene("游戏失败", f""" 东方延绪: 章北海, 我代表星舰地球逮捕你。 全员准备,返航迎击三体人的探测器。 {death1} """) death_5 = Scene("游戏失败", f""" 在更改航线后,遭遇了三体文明的舰队,被击毁... """) death_6 = Scene("游戏失败", f""" 遭遇了黑暗森林法则,被星舰地球中的其它战舰次声波核弹攻击, 全员阵亡! """) #自然选择号 natureSelectionFleet = Scene("自然选择号", """ 东方延绪: 章北海执行舰长,我是自然选择号的舰长东方延绪。欢迎您。 现在我把自然选择号的指挥权交给您。飞船有四种前进模式, 当进入前进4模式时,船员必须进入睡眠仓。现在,我需要 再次确认您是否受到思想钢印的影响,请您回答我这个问题: '人类是否必胜?' [1] 必胜 [2] 必败 [3] 这要取决于我所见到的三体文明 [4] 人的意志胜过一切 """) #逃离太阳系 escape = Scene("自然选择号战舰控制中心", """ 东方延绪: 章北海舰长,现在我交出自然选择号的控制权。据地球舰队传来的最新消息: 三体文明的探测器-水滴-已经抵达太阳系的边缘,15分钟后将与地球舰队接触。 现在飞船等待您发布第一条命令: [1] 前进1 逃离太阳系 [2] 前进2 逃离太阳系 [3] 前进3 逃离太阳系 [4] 前进4 逃离太阳系 """) #飞控终端 control_terminal = Scene("自然选择号战舰飞控终端",""" 警告! 警告! 警告! 飞船进入前进4必须通知所有船员进入深海睡眠模式。请输入飞控密码: [1] Man Always Remember Love Because Of Romance Only [2] If You Give Me A Pivot Point I Could Move The Earth [3] The Sun Rather Than The Earth At The Center Of The Universe [4] Two Heads Are Always Better Than One """) # 太阳系外 extrasolar = Scene("自然选择号战舰",""" 飞船已经飞出了太阳系,身后的蓝色空间号、深空号、终极规律号以及企业号正在追击。 下一步命令是: [1] 延续人类文明,向前飞,向远飞 [2] 掉头击毁追击战舰 [3] 将舰队指挥权交给东方延续舰长 """ ) # 星舰地球 fleet_earth = Scene("星舰地球",""" 地球舰队已经被水滴摧毁....... 五艘战舰必须延续文明的责任,太空将是我们最后的归宿。星舰地球决定: [1] 处决人类的叛徒章北海,回去与水滴战斗 [2] 处决人类的叛徒章北海,继续飞往十八光年外的天鹅座NH558J2 [3] 章北海是英雄,继续飞往十八光年外的天鹅座NH558J2 """ ) #终极规律号 ultimate_rule_fleet = Scene("终极规律号",""" 终极规律号战舰中出现了一种不安的气氛...... 十四光年,飞船的资源是有限的,如何得到补给? 舰长,我们该怎么办? [1] 向其它四艘战舰发射次声波氢弹 [2] 向其它四艘战舰求援,请求补给 [3] 要求星舰地球更改航程,找到补给点 [4] 回地球吧 """ ) #蓝色空间号 blue_space_fleet = Scene("蓝色空间号",""" 警告! 警告! 警告! 终极规律号的次声波氢弹冲击波即将到达.... 防御成功,舰队损伤5%... 等待下一步命令: [1] 发射高能伽马射线激光击毁终极规律号 [2] 逃离 """) #最后的场景 last_episode = Scene("太空陵墓",""" 蓝色空间号带走了所有的燃料和配件,并将自然选择号、企业号、深空号的 残骸切割多段,围城巨石阵,构建了一处太空陵墓,纪念人类第一次体会到 宇宙‘黑暗森林’的可怕。 恭喜你,顺利通过了剧情! """ ) START = 'natureSelectionFleet' # 返回场景名字对应的场景对象 def load_scene(name): return globals().get(name) # 返回场景对象对应的场景名字 def name_scene(scene): for key, value in globals().items(): if value == scene: return key
7.3 编写game.py的自动测试脚本
接下来,将编写game.py的自动测试脚本。在tests\目录下新建game_tests.py,测试工具仍然为nosetests。分别对game.py中Scene的初始化函数、add_paths和enter函数进行测试。具体代码为:
from nose.tools import * from threebody.game import * def test_scene(): gold = Scene("GoldRoom", """This room has gold in it you can grab. There's a door to the north.""") assert_equal(gold.name, "GoldRoom") assert_equal(gold.paths, {}) def test_add_enter_paths(): center = Scene("Center", "Test room in the center.") north = Scene("North", "Test room in the north.") south = Scene("South", "Test room in the south.") center.add_paths({'north': north, 'south': south}) assert_equal(center.enter('north'), north) assert_equal(center.enter("south"), south) def test_game_map(): start_room = load_scene(START) assert_equal(start_room.enter('1'), death_1_1) assert_equal(start_room.enter('2'), death_1_2) assert_equal(start_room.enter('3'), death_1_3) assert_equal(start_room.enter('4'), escape) assert_equal(start_room.enter('*'), natureSelectionFleet)
需要注意的是,在引入特性时,需要从threebody\game.py中引入所有提到的类和全局变量。PowerShell中的测试结果为:
7.4 编写HTML模板
在三体游戏中,我们采用了布局模板和POST表单。在templates\目录下创建show_room.html和layout.html两个文件。布局模板代码为:
<html> <head> <title>三体游戏</title> </head> <body> {% block content %} {% endblock %} </body> </html>
主要包含标题“三体游戏”。POST表单代码为:
{% extends "layout.html" %} {% block content %} <h1>{{ room.name }}</h1> <pre> {{ room.description }} </pre> {% if room.name == "游戏失败"%} <p><a href="/">Play Again?</a></p> {% elif room.name == "太空陵墓" %} <p><a href="/">退出游戏</a></p> {% else %} <p> <form action='/play' method='POST'> - <input type='text' name='action'><input type='SUBMIT'> </form> </p> {% endif %} {% endblock %}
在这个html文件中,首先加载布局模板,其次将场景对象的名字和剧情描述显示在网页上。随后启用 if-else 条件判断语句,当检测到场景名为“游戏失败”的字符串时,在剧情描述底部显示 “play again?”;当检测到场景名为“太空陵墓”的字符串时,在剧情描述底部显示“退出游戏”;否则就显示文本框,等待用户输入信息推动剧情发展。
7.5 创建三体web游戏引擎
游戏引擎的python文件应创建在项目主目录下,即第一个threebody目录下。我创建了一个名为app.py的web引擎文件。主要引用了flask网络框架中的FLASK, session, redirect,url_for, request,render_template特性。当然,为了运行游戏,还需要引入game.py。具体代码如下:
from flask import Flask, session, redirect, url_for, request from flask import render_template from threebody import game app = Flask(__name__) @app.route("/") def index(): #this is used to "setup" session with starting values session['scene_name'] = game.START #利用会话临时存储场景名字 return redirect(url_for("play")) @app.route("/play", methods=['POST', 'GET']) def play(): scene_name = session.get('scene_name') #获得当前场景的名字 if request.method == 'GET': room = game.load_scene(scene_name) #通过场景的名字加载场景对象 return render_template("show_room.html", room=room) else: action = request.form.get('action') if scene_name and action: room = game.load_scene(scene_name) next_scene = room.enter(action) #获取下一个场景的对象 if not next_scene: next_scene = room.enter('*') #将下一个场景的名字存在临时会话中,供web服务器使用 session['scene_name'] = game.name_scene(next_scene) else: session['scene_name'] = game.name_scene(next_scene) return redirect(url_for("play")) # YOU SHOULD CHANGE THIS IF YOU PUT ON THE INTERNET app.secret_key = 'sdjffiweriwuer923riew3shfs' if __name__ == "__main__": app.run()
程序的第一个主要函数为index(), 代表了主目录“/”,使用了session临时会话来存储场景名字,以工下次调用时使用。返回“/play"目录。程序第二个主要函数为play()。在"/play"目录下有两种模式POST或GET,当未获得用户输入时,默认为GET,此时引擎加载show_room.html文件。当用户输入有效信息后,进入post模式,此时引擎根据信息得到下一个剧情场景,并存储在session会话中,返回play目录进行下一场景加载。最后,通过app.run()语句来自动运行web游戏引擎。
7.6 游戏运行效果
在Poweshell中,运行
python app.py
结果为:
此时debug模式是关闭的,如果要打开,则将app.run()修改为app.run(debug = True)。在本地网页端运行时,根据提示,在浏览器上输入localhost:5000/即可。效果如下图:
结语
这是CSDN上自己写的第一个系列的文章,内容虽然没有什么新意,但坚持写作,把自己的思路理的非常清晰,也知道了什么地方还没有掌握。接下来,要沉静一段时间,继续学习,坚持写作。
这篇关于“笨办法”学Python 3基础篇 - 搭建简易的网站的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器
- 2024-11-16四种数据科学Web界面框架快速对比:Rio、Reflex、Streamlit和Plotly Dash
- 2024-11-14获取参数学习:Python编程入门教程