桌游《暗夜之光》PC移植日志(一) 最后更新时间:2021年03月03日 有一天,躺在家里的床上,就想着,好想玩桌游啊,好想玩桌游啊。 但此前,我并没有什么桌游经验。硬要说的话,就是在小学的时候玩过几局大富翁,但那都是十年前的事情了。 看过动漫《如果有妹妹就好了》,很是羡慕里面一群朋友围在一起玩桌游的情形。于是求助贴吧大佬,终于找到了一款名叫《暗夜之光》的桌游。 在看简介的时候就觉得,这游戏特别对我的胃口。于是想尽办法,终于入了一套。玩过几局之后,感觉真的很有意思。 于是,我突发一个想法:我为什么不能把这个游戏移植到电脑上呢?即使不是为了推崇,但是一个盒子的游戏,到处装着走,总感觉不方便,且每次玩游戏,总担心会丢了这个,那个的。 所以我决定把桌游《暗夜之光》移植到电脑上。对于刚刚python入门的我,这既是对自己以往知识的巩固练习,又是给自己一个挑战。 最开始,我做了几个游戏里的类,像是人物,技能,地图等等。整个类的制作非常简单,而我自己也不知道很多东西写在哪个地方合不合适,所以只能慢慢通过后续的开发做出修改。 人物类: ```python class Action: # 人物类: # 属性: # 姓名(name) # 阵营(camp) # 血量(HP) # 攻击力(ATK) # 防御力(DEFE) # 移动力(SPE) # 实力(pow) # 技能(skill) def __init__(self, name, camp, HP, ATK, DEFE, SPE, pow, skill): self.name = name self.camp = camp self.HP = HP self.ATK = ATK self.DEFE = DEFE self.SPE = SPE self.pow = pow self.skill = skill ``` 技能类: ```python class Skill: # 技能类: # 属性: # 技能名(skill_name) # 消耗对象(cse_type)(生命值 / 士气 / 主宰力) # 消耗数(cse) # 距离(dtc) # 方法: # 技能效果 # 对像 def __init__(self, skill_name, cse_type, cse, dtc): self.skill_name = skill_name self.cse_type = cse_type self.cse = cse self.dtc = dtc ``` 地图类: ```python class Map: # 地图块类: # 属性: # 地图块编号(id) # 地形名(map_name):即地图类型。 # 大小(size) # 移动力消耗(SPE) # 战斗掷骰数(ran) # 地图数组(map_array):存储地图位置数据。 # 方法: # 地图元组(map_tuples):生成该地图块所标记的地图位置数据,并存存储到数组中。 # 鼠标判断(mouse_judge):判断鼠标是否在该位置。 # 地形信息反馈 def __init__(self, id, map_name, size, SPE, ran): self.id = id self.map_name = map_name self.size = size self.SPE = SPE self.ran = ran self.map_array = list() def map_tuples(self, x_start, x_end, y_start, y_end): # x_start:表示地图块位置数据的横坐标起始值。 # x_end:表示地图块位置数据的横坐标结束值。 # y_start:表示地图块位置数据的纵坐标起始值。 # y_end:表示地图块位置数据的纵坐标结束值。 for x in range(x_start, x_end + 1): for y in range(y_start, y_end + 1): self.map_array.append((x, y)) def mouse_judge(self, mouse_xy): # mouse_xy:表示鼠标坐标。 if mouse_xy in self.map_array: print("当前鼠标坐标:{}, 当前地形:{}, 地形ID:{}".format(mouse_xy, self.map_name, self.id)) ``` 在开发的过程中,我想到一个问题,鼠标控制怎么办? 这是困扰我很长一段时间的问题。之前我曾写过另一个游戏,非常简单的一个游戏,原本也是应该由鼠标控制的,但是却因为原本的写法会引起程序阻塞,因此不得不放弃鼠标控制的写法换成了用键盘控制。 使用数组来做这个功能!我曾经在一篇博客里看到了对于这个功能写法的介绍,但是我未能理解其写法而放弃。 但就在刚才,我突然想通了这个东西应该怎么写,应该怎么做。于是抱着试一试的心态去写了出来,效果……出乎意料的好。怎么说,这也算是一个巨大的突破。对于后续开发也有了一个振奋作用。 原本的写法: ```python # x:代表一个数值,如range(0,100) # y:代表一个数值,如range(0,100) mouse = pygame.mouse.get_pos() for a in range(0, x): for b in range(0,y): if mouse = (x,y): print("鼠标在该范围!") ``` 这个写法的弊端非常明显了,当鼠标放在这个位置的时候,就会一直进行遍历,影响游戏的程序性能,其次,由于使用了for循环,如果在这里要进行一些需要停止游戏的操作,或是要停止最外层循环的操作,就需要用变量来控制,非常麻烦,且不利于程序运行。 因此,我换成了下面的写法(这里我为了方便,就用了中文命名,实际开发中并没有用中文): ```python #coding: utf-8 import pygame import sys class Map: # 地图块类: # 属性: # 地图块编号(id) # 地形名(map_name):即地图类型 # 大小(size) # 移动力消耗(SPE) # 战斗掷骰数(ran) # 方法: # 地形信息反馈 def __init__(self, id, map_name, size, SPE,ran): self.id = id self.map_name = map_name self.size = size self.SPE = SPE self.ran = ran self.地图数组 = list() def 地图元组(self,横坐标起始,横坐标结束,纵坐标起始,纵坐标结束): for 横坐标 in range(横坐标起始, 横坐标结束+1): for 纵坐标 in range(纵坐标起始,纵坐标结束+1): self.地图数组.append((横坐标, 纵坐标)) def 鼠标判断(self,鼠标坐标): if 鼠标坐标 in self.地图数组: print("当前鼠标坐标:{}, 当前地形:{}, 地形ID:{}".format(鼠标坐标, self.map_name, self.id)) # m1 = Map(1,"平原", 100, 1, 3) # m1.地图元组(0,200,0,200) # print(m1.地图数组) ################################## #####初始化游戏并创建一个对象###### ################################## pygame.init() def run_game(): #################### ######创建屏幕###### #################### pingmu=pygame.display.set_mode((800,800)) #设置界面大小 pygame.display.set_caption("游戏界面") #设置界面标题 #################### ######创建地图###### #################### m1 = Map(1,"平原", 100, 1, 3) m1.地图元组(0,200,0,200) print(m1.地图数组) m2 = Map(2, "山地", 100, 1, 3) m2.地图元组(201, 400, 0, 200) print(m2.地图数组) m3 = Map(3, "平原", 100, 1, 3) m3.地图元组(401, 600, 0, 200) print(m3.地图数组) m4 = Map(4, "山地", 100, 1, 3) m4.地图元组(601, 800, 0, 200) print(m4.地图数组) m5 = Map(5, "平原", 100, 1, 3) m5.地图元组(0, 200, 201, 400) print(m5.地图数组) m6 = Map(6, "山地", 100, 1, 3) m6.地图元组(201, 400, 201, 400) print(m6.地图数组) m7 = Map(7, "平原", 100, 1, 3) m7.地图元组(401, 600, 201, 400) print(m7.地图数组) m8 = Map(8, "山地", 100, 1, 3) m8.地图元组(601, 800, 201, 400) print(m8.地图数组) ###########dddd###### ###开始游戏主循环#### #################### while 1: 鼠标坐标 = pygame.mouse.get_pos() m1.鼠标判断(鼠标坐标) m2.鼠标判断(鼠标坐标) m3.鼠标判断(鼠标坐标) m4.鼠标判断(鼠标坐标) m5.鼠标判断(鼠标坐标) m6.鼠标判断(鼠标坐标) m7.鼠标判断(鼠标坐标) m8.鼠标判断(鼠标坐标) # print(鼠标坐标) for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() pygame.display.update() # 刷新 run_game() ``` 这个写法,虽然在游戏开始的时候会有一段较为明显的停顿,但是在游戏运行起来以后会更加流畅,且相对于上一种写法,问题也并没有那么多。
Comments | NOTHING