“笨办法”学Python 3基础篇

编程入门 行业动态 更新时间:2024-10-11 17:19:23

“笨<a href=https://www.elefans.com/category/jswz/34/1770735.html style=办法”学Python 3基础篇"/>

“笨办法”学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 = nameself.description = descriptionself.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 gameapp = Flask(__name__)@app.route("/")
def index():#this is used to "setup" session with starting valuessession['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-03-11 19:26:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1729726.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:办法   基础   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!