用python的tkinter做游戏(五)—— 魔塔 篇

好久没更新了,今天继续:用python自带的tkinter做游戏系列的第五弹,魔塔 篇

之前的四篇博文介绍的分别是贪食蛇和俄罗斯方块,推箱子的简易版和推箱子的重制版。
用python自带的tkinter做游戏(一)—— 贪吃蛇 篇
用python自带的tkinter做游戏(二)—— 俄罗斯方块 篇
用python自带的tkinter做游戏(三)—— 推箱子简易版 篇
用python自带的tkinter做游戏(四)—— 重制版 篇

首先我再次申明一下,本人是业余编程爱好者,没经过什么正规的编程学习,代码习惯比较凌乱,让各位大神们见笑了,也望新手们能共勉。所以本文尽量不秀代码,主要还是谈谈制作的思路(魔塔的代码已上传至网盘,下载链接见文末)。

一,总体设计思路


原本是打算做一个日式的RPG游戏(类似 勇者斗恶龙),后来心血来潮,改做了魔塔,所以在地图的设计上沿用了原本的设定。魔塔的地图设计比较简单,和之前的推箱子类似,这次我就简单说说RPG里的地图设计思路。

当然了,这个地图设计思路也是我自己瞎琢磨出来了,应该还有更好的方案,欢迎对此有兴趣的朋友可与我交流交流~

大多数RPG游戏,特别是早期日式的,比如勇者斗恶龙,地图都比较简单,上下左右操控的主角行动即可。
用python的tkinter做游戏(五)—— 魔塔 篇_第1张图片
有几个需要注意的点就是:

  1. 人物在行走时会显示底部的画面,就是说人物图片的底色是透明的,那不是png就是gif文件。
  2. 人物有时候会被遮盖住,比如在树的后方或者房子的后方。这样的话游戏画面至少会有三层,底层是背景地图,中间的是活动的人物图, 顶层的是遮盖物,当然了,顶层的图片也必须是支持透明的png或gif的文件。
  3. 一般游戏的地图会比较大,远大于屏幕,这时候移动人物的时候,如果人物在屏幕正中间的时候其实移动的是背景图片。关于这点,在上期的推箱子里也有展示。所以需要掌握三组很重要的坐标,分别是人物在地图中的XY坐标,人物在屏幕中的XY坐标和地图的XY坐标。
  4. 移动是有区域限制的,比如前方是房屋或山体之类的,那按下移动键的时候,走路的步伐移动值就等于0,等于是原地踏步了。
  5. 地图的切换。设定一个区域,当人物移动进此区域的时候就切换至指定的地图。

当然了,魔塔这类的游戏是属于固定的小地图,而且人物的移动距离是以单元格为单位的,此类的地图还是用推箱子的数组矩阵地图制作比较方便。

魔塔的背景图展示:
用python的tkinter做游戏(五)—— 魔塔 篇_第2张图片
既然RPG地图我做的都差不多了,就直接拿来做魔塔了,也不需要修改啥,就是把移动距离扩大到和人物长宽一致就行,这样人物也是一格一格的移动。就是有点大材小用,魔塔游戏里没有层的概念,也没有大地图,不过我在魔塔的第三层里加入了底层的图片和顶层的图片供测试用,各位可以亲自体会一下。

为了实现存档和读取的功能,我把游戏数据单独放在Game_Data.py文件内的game_data这个字典里,也方便修改游戏内的各项参数和文本。

顺便提一句,本魔塔我只设计了三层,后面的也懒得弄了,反正该有的功能都有了,除了些极其特殊功能的道具需要增加些代码,其它简单的道具可直接在game_data里实现,相当于一个魔塔编辑器了。

二,人物动作和移动


魔塔里的人物造型和普通RPG里的差不多,四个方向,每个方向四张图,一共就是十六张图,如下图。

用python的tkinter做游戏(五)—— 魔塔 篇_第3张图片
原始的图片就是一张整图,含有了十六种造型。但游戏中玩家只会看到这张图的十六分之一的大小,如果想要只显示图片的局部部分,可以在原本的canvas之上再新增一个和人物大小一致的canvas,通过图片的坐标变动来切换不同的人物造型。

不过之前提到了,游戏中是有层的概念,是需要利用图片的透明来实现。但tkinter里的canvas是不支持透明的,想要实现这个透明效果,唯一的办法就是在这个人物canvas里再放入一张同样的背景图,通过坐标的变动来匹配背景图,再加上还有底层和顶层的图片,这个方案超级超级麻烦。

所以本人最终还是放弃了这个方案,换了一种思路,直接用PIL这个库来切割图片,直接分割成十六张小图。为此,本人写了两个函数,一个函数是把一张图片平均地切割成十六张,还有一个函数是截取图片中的任意区域。然后又写了一个函数,等退出游戏后就删除这些切割出来的小图,符合环保理念。。。

人物造型搞定了,再来看看如何移动。根据之前三组坐标(人物在地图中的XY坐标,人物在屏幕中的XY坐标和地图的XY坐标)的对比,来决定是移动人物还是移动背景图。然后根据人物在地图中的XY坐标,移动距离和人物长宽这几个数据,可以推算出人物下一步的四个区域(上下左右四个方向)里是啥内容,再配合按键的方向,如果下一步是限制区域的话,那移动距离就改为零,让人物原地踏步不再前进,下一步区域如果是道具的话,就可以实现拾取道具的功能了。

三,游戏内容

魔塔这个游戏,主要就是通过拾取道具来变化数值,如比画面中消除了一把黄钥匙,手里就多了一把黄钥匙,消除了一个血瓶,就加多少血,原理很简单。开门也是,消除了门,减一把相应的钥匙。不过开门有个动画效果,其实和人物动画差不多,只不过只展示一遍,播放一遍后就消失,不像人物是一直反复循环的播放。开假墙也是,游戏中我是设计了减50血可以开假墙,也可以改成0血,无条件开假墙。

在这里需要注意的是,除了血量外,数值都不能低于0,而血量必须要大于0,至少得是1 。如果发生了这类情况,那还得重新恢复数值并跳过,这样钥匙数量为0的时候就无法开门了。

打怪的原理也很简单,根据人物和怪物的各项属性,简单的数学题就能算出伤害值。如果打不过怪物,分两种情况,一种是不破防,还有一种就是血不够。具体的怪物信息在游戏获得图鉴后可以查看。

用python的tkinter做游戏(五)—— 魔塔 篇_第4张图片
游戏中的两大神器,除了图鉴外还有一个就是跳跃神器,可以方便上下楼,原理也很简单,每上一层楼就记住该楼层,使之成为能去的最高楼层。

用python的tkinter做游戏(五)—— 魔塔 篇_第5张图片

四,菜单

游戏内还需要设计菜单,不光是系统菜单,还有商店里的选项菜单。

用python的tkinter做游戏(五)—— 魔塔 篇_第6张图片
用python的tkinter做游戏(五)—— 魔塔 篇_第7张图片
关于菜单的设计,本人没什么经验,网上也没搜索到相关的教程,做的比较死板,只能说是能用,应该还有更好的方案。
和NPC的对话也是,做的比较草率。对话内容限定在四句话之内,而且有字数限制。只能凑合着用用。
本还想弄个游戏封面的,因为菜单的设计不是很理想,也懒得弄了。

五,音效

不用pygame做游戏,最大的弊端就是音乐是个问题。虽然用 winsound 也可以发声,缺点也很明显,只能用wav也就算了,还不支持同时发声。比如背景音乐播放着,吃了一把钥匙产生了效果音,这时背景音乐就停止了。

关于这个问题,本人捣鼓了好久也没搞定,多线程或别的什么的,都不行。要么就是本人水平有限,或者就是winsound根本就不支持同时发声,无奈。

最终的妥协方案就是,给效果音限定个时间,结束后继续播放背景音乐,勉强也能用,只能算是个无奈之举。

原本的计划是每层会对应一个背景音乐,现在也搞得没心思弄了,就全部统一播放一样的背景音乐吧。

六,结束语

虽然还存在着不少的遗憾,但游戏完整度至少也有90%以上,除了些少量的特殊道具或事件需要增加些代码,其余的都可以在game_data里实现。只是设计游戏太繁琐,也懒的去弄了,有兴趣的朋友可以自行研究研究,也欢迎来与本人交流(WX: znix116)。

因为还含有图片和音乐,所以全部打包上传至网盘了,有兴趣的朋友可以下载去看看。谢谢捧场~~~

魔塔0.1版本
链接:https://pan.baidu.com/s/1fITZ6IoeMqjWqGUpWl9U9w
提取码:znix

2021.12.29 更新:

没想到这篇博文这么受欢迎,今天就再更新点内容。

补充说明下重启游戏的功能。
这个功能在推箱子这个游戏就有,当时我用的是深度copy。
在魔塔中因为用了pickle来打包实现存档和读取,所以就用pickle先打包一份做备份用,需要的时候就用这个备份还原数据。
退出游戏的时候就删除这个备份,和临时图片一样,不留痕迹。

还有在游戏中按字母P键可以显示辅助线,再按一下隐藏辅助线,方便测试用。

顺便版本也小更新一下,修复了些小bug和其它一些问题。

魔塔0.2版本
链接:https://pan.baidu.com/s/1u4e7z2QQPbGCAs92R00kxA
提取码:znix

2022.03.25 更新:

修复了些BUG,终于把恼人的出错信息给解决了,哈哈!

魔塔0.3版本
链接:https://pan.baidu.com/s/1pMGF6xiQ9CIM64PXhgLTJw
提取码:znix
用python的tkinter做游戏(五)—— 魔塔 篇_第8张图片
用python的tkinter做游戏(五)—— 魔塔 篇_第9张图片
用python的tkinter做游戏(五)—— 魔塔 篇_第10张图片

你可能感兴趣的