python 战棋游戏代码实现(1):生物行走和攻击选择

  • 游戏介绍
  • 代码介绍
    • 地图类
    • 确定人物行走范围
    • 人物行走代码
    • 生物状态机实现
  • 完整代码
    • 编译运行

游戏介绍

致敬永远的经典英雄无敌3, 本想在网上找个战棋游戏学习下,无奈没有发现python版本的,那就自己来写一个把。

游戏实现了类似英雄无敌3 中战斗场景的回合制玩法:

  • 对战双方每个生物每一轮有一次行动机会,可以行走或攻击对方。
  • 每个生物属性有:行走范围,速度,生命,伤害,防御,攻击 和 是否是远程兵种。
  • 当把对方生物都消灭时,即胜利。
  • 实现了简单的AI。

python 战棋游戏代码实现(2):六边形地图寻路和显示

生物行走选择截图如下:
图1
图1 中的步兵行走范围属性值是4,表示可以走4个方格,图中背景是深蓝色的方格就是该步兵可以走的方格,不可以直接到斜对角的方格。步兵头顶红色的是血条,当前轮到行动的生物背景方格颜色会变成浅蓝色。

游戏截图如下:
图2
图2中,目前轮到行动的生物是我方的左下角背景为浅蓝色的步兵,可以看到背景为深蓝色的方格为步兵可以行走的范围。背景为绿色的方格为目前选定要行走到得方格。鼠标指向敌方生物,如果敌方生物背景方格颜色变成黄色,表示可以攻击,可以看到允许攻击斜对角的敌人。图中还有石块,表示不能移动到得方格。

下面图3 是第二轮时我方开始行动时的截图。

代码介绍

地图类

source\component\map.py 中的 map类保存地图信息,width 和 height 为地图的宽度和长度,bg_map 设置方格的背景颜色, entity_map 保存哪个方格上有生物。active_entity表示当前要行动的生物。

class Map():def __init__(self, width, height, grid):self.width = widthself.height = heightself.bg_map = [[0 for x in range(self.width)] for y in range(self.height)]self.entity_map = [[None for x in range(self.width)] for y in range(self.height)]self.active_entity = None

updateMap 函数,当我方生物选择行动时,设置生物可行走范围内的方格背景为 c.BG_RANGE 。active_entity 的 inRange 函数判断一个方格是否在行走范围内。

    def updateMap(self):for y in range(self.height):for x in range(self.width):self.bg_map[y][x] = c.BG_EMPTYif self.entity_map[y][x] is not None and self.entity_map[y][x].isDead():self.entity_map[y][x] = Noneif self.active_entity is None or self.active_entity.state != c.IDLE:returnmap_x, map_y = self.active_entity.map_x, self.active_entity.map_yself.bg_map[map_y][map_x] = c.BG_ACTIVEfor y in range(self.height):for x in range(self.width):if not self.isMovable(x,y):continueif self.active_entity.inRange(self, x, y):self.bg_map[y][x] = c.BG_RANGEmouse_x, mouse_y = pg.mouse.get_pos()self.checkMouseMove(mouse_x, mouse_y)

drawBackground 函数根据 bg_map 中每个方格的类型 绘制方格的背景颜色, 然后绘制方格之前的黑色分隔线。

    def drawBackground(self, surface):pg.draw.rect(surface, c.LIGHTYELLOW, pg.Rect(0, 0, c.MAP_WIDTH, c.MAP_HEIGHT))for y in range(self.height):for x in range(self.width):if self.bg_map[y][x] == c.BG_EMPTY:color = c.LIGHTYELLOWelif self.bg_map[y][x] == c.BG_ACTIVE:color = c.SKY_BLUEelif self.bg_map[y][x] == c.BG_RANGE:color = c.NAVYBLUEelif self.bg_map[y][x] == c.BG_SELECT:color = c.GREENelif self.bg_map[y][x] == c.BG_ATTACK:color = c.GOLDpg.draw.rect(surface, color, (x * c.REC_SIZE, y * c.REC_SIZE, c.REC_SIZE, c.REC_SIZE))surface.blit(self.map_image, self.rect)for y in range(self.height):# draw a horizontal linestart_pos = (0, 0 + c.REC_SIZE * y)end_pos = (c.MAP_WIDTH, c.REC_SIZE * y)pg.draw.line(surface, c.BLACK, start_pos, end_pos, 1)for x in range(self.width):# draw a horizontal linestart_pos = (c.REC_SIZE * x, 0) end_pos = (c.REC_SIZE * x, c.MAP_HEIGHT)pg.draw.line(surface, c.BLACK, start_pos, end_pos, 1)

确定人物行走范围

source\component\entity.py 中的entity类保存生物的状态和属性。group表示 生物属于敌我哪一方, map_x 和 map_y 表示初始时生物在地图上的位置。sheet是生物的图像,EntityAttr 类保存生物的所有属性。

class Entity():def __init__(self, group, sheet, map_x, map_y, data):self.group = groupself.group_id = group.group_idself.map_x = map_xself.map_y = map_yself.frames = []self.frame_index = 0self.loadFrames(sheet)self.image = self.frames[self.frame_index]self.rect = self.image.get_rect()self.rect.x = self.map_x * c.REC_SIZE + 5self.rect.y = self.map_y * c.REC_SIZE + 8self.attr = EntityAttr(data)self.health = self.attr.max_healthself.weapon = Noneself.enemy = Noneself.state = c.IDLEself.animate_timer = 0.0self.current_time = 0.0self.move_speed = c.MOVE_SPEED

从图2 可以看到如果在生物的行走范围中有其他生物或石块时,行走范围就不能直接判断出来。
Entity类中 inRange函数使用A寻路算法计算出到某一个方格的距离,判断是否在行走范围内。
A
算法的实现说明可以看我之前的一篇文章 A*算法实现

    def inRange(self, map, map_x, map_y):location = AStarSearch.AStarSearch(map, (self.map_x, self.map_y), (map_x, map_y))if location is not None:_, _, distance = AStarSearch.getFirstStepAndDistance(location)if distance <= self.attr.range:return Truereturn False

人物行走代码

A*算法可以获取从起始位置到目标位置的一条最短路径,所以人物行走就是沿着这个路径从起始位置移动到目标位置。
walkToDestination 函数中 self.rect.x 和 self.rect.y 表示生物当前的坐标位置,self.next_x 和self.next_y 表示路径中下一个方格的坐标位置。

  • 当前的坐标位置和下一个方格的坐标位置相同时,选取路径中下一个方格的坐标位置。
  • 当前的坐标位置和下一个方格的坐标位置不同时,生物就继续行走。
   def walkToDestination(self, map):if self.rect.x == self.next_x and self.rect.y == self.next_y:source = (self.rect.x//c.REC_SIZE, self.rect.y//c.REC_SIZE)dest = (self.dest_x//c.REC_SIZE, self.dest_y//c.REC_SIZE)location = AStarSearch.AStarSearch(map, source, dest)if location is not None:map_x, map_y, _ = AStarSearch.getFirstStepAndDistance(location)self.next_x = map_x * c.REC_SIZE + 5self.next_y = map_y * c.REC_SIZE + 8else:self.state = c.IDLEprint('Error no path to walk to dest(%d,%d)' % (self.next_x, self.next_y))if self.rect.x != self.next_x:self.rect.x += self.move_speed if self.rect.x < self.next_x else -self.move_speedelif self.rect.y != self.next_y:self.rect.y += self.move_speed if self.rect.y < self.next_y else -self.move_speed

生物状态机实现

生物目前有3个状态:

  • c.IDLE:没有轮到该生物行动时,不做任何操作
  • c.WALK:轮到该生物行动时,从目前位置移动到指定的目标位置(self.dest_x, self.dest_y)
  • c.ATTACK: 如果有可攻击的敌人时,按照生物是远程还是近程兵种,进行攻击。
   def update(self, game_info, map):self.current_time = game_info[c.CURRENT_TIME]if self.state == c.WALK:if (self.current_time - self.animate_timer) > 250:if self.frame_index == 0:self.frame_index = 1else:self.frame_index = 0self.animate_timer = self.current_timeif self.rect.x != self.dest_x or self.rect.y != self.dest_y:self.walkToDestination(map)else:map.setEntity(self.map_x, self.map_y, None)self.map_x = self.dest_x // c.REC_SIZEself.map_y = self.dest_y // c.REC_SIZEmap.setEntity(self.map_x, self.map_y, self)if self.enemy is None:self.state = c.IDLEelse:self.state = c.ATTACKelif self.state == c.ATTACK:if self.attr.remote:if self.weapon is None:self.shoot(self.enemy)else:self.weapon.update()if self.weapon.done:self.weapon = Noneself.enemy = Noneself.state = c.IDLEelse:self.putHurt(self.enemy)self.enemy = Noneself.state = c.IDLEif self.state == c.IDLE:self.frame_index = 0

完整代码

游戏实现代码的github链接 战棋游戏
这边是csdn的下载链接 战棋游戏

编译运行

1.编译环境
python3.7 + pygame1.9
2.运行
直接运行根目录下的 main.py
$ python main.py

python 战棋游戏代码实现(1):生物行走和攻击选择相关推荐

  1. python 战棋游戏代码实现(2):六边形地图寻路和显示

    python 战棋游戏代码实现(2):六边形地图寻路和显示 六边形地图介绍 代码介绍 地图六边形显示 A*算法的六边形寻路修改 判断某个点在哪个六边形中 完整代码 编译运行 六边形地图介绍 之前的文章 ...

  2. python 战棋游戏代码实现

    游戏介绍 致敬永远的经典英雄无敌3, 本想在网上找个战棋游戏学习下,无奈没有发现python版本的,那就自己来写一个把. 游戏实现了类似英雄无敌3 中战斗场景的回合制玩法: 对战双方每个生物每一轮有一 ...

  3. HTML5 canvas 实现回合制战棋游戏(1):加载和绘制图形

    HTML5 canvas 实现回合制战棋游戏(1):加载和绘制图形 游戏介绍 完整代码 代码目录 游戏运行 HTML5 canvas 绘制图形 canvas 介绍 绘制函数 加载图片 生物行走动画绘制 ...

  4. 一步一步教你用 Python 开发战棋游戏,仿英雄无敌

    英雄无敌,你从没有玩过的"船"新版本-- 制作人:你自己-- 相信很多人都是从游戏开始接触电脑和编程的.很多人打算学习编程的时候,也都是冲着开发游戏去的,尤其是学习 Python ...

  5. pygame战棋游戏制作之战棋回合切换(五)

    简介 前面我们已经完成了战棋地图的绘制,棋子的设置,光标的设置,接下来我们将要开始实现rpg游戏的灵魂--回合切换. 正文 回合切换主要是通过棋子列表判断,当列表为空时,触发回合切换的函数.因此我们创 ...

  6. UE战棋游戏的制作流程(使用GAS来制作技能系统)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 角色基础功能 GAS插件的使用 配置GameplaySystemAbility 角色的基本属性 创建结构体用于储存GE ...

  7. 酱油带你用cocos2dx3.0完成一款战棋游戏 (曹操传)(一)地图制作篇 1

    这是酱油第一次写博客,所以如果有什么写的不好,大家多多海涵啊.那么废话就不多说了,直接进入正题吧. 制作一款战棋游戏,在酱油看来最大的难度便是 ai的设计以及 实现剧本对游戏整体的控制,当然啦,这都是 ...

  8. 【NOIP模拟赛】战棋游戏

    战棋游戏 Description Rainbow擅长战棋类游戏.著名的战棋游戏有很多,例如<曹操传>.<瓦岗山异闻录>等.在本题中,我们考虑战棋游戏的一个简单版本,基于一下规则 ...

  9. NOIP2018 模拟测试 day1 战棋游戏

    题目: 战棋游戏 Rainbow 擅长玩战棋类游戏.著名的战棋游戏有很多,例如<曹操传>.<瓦岗 山异闻录>等.在本题中,我们考虑战棋游戏的一个简单版本,基于以下规则: ⚫ 地 ...

  10. Java版桌面战棋游戏TLOH The Legend of Heroes 开发预告

    按照本年度计划,年内笔者将继续开发Loonframework,前年及去年写的一些陈旧代码将被替换,有部分架构将重写.但实际上讲,剔除的代码中很多上并非不可用,而仅仅是不够规范,需要重构以满足组件化需要 ...

最新文章

  1. NPOI 导出Excel
  2. vue2.0通过Axios导出excel文件(解决乱码问题)
  3. T-SQL and XML
  4. mysql binlog rotate_binlog rotate引发的MySQL阻塞事件
  5. jeecg扩展字段,非实体属性
  6. ubuntu下安装优化调节软件——ubuntu tweakailurus
  7. python读取与写入配置文件
  8. 什么是Web Server
  9. 二分图 洛谷P2055 [ZJOI2009]假期的宿舍
  10. 米勒-拉宾素性检验(MillerRabbin)算法详解
  11. Android动态生成答题卡,手机扫描答题卡改卷的最佳选择——ZipGrade
  12. (转)高盛报告:人工智能、机器学习和数据将推动未来生产力的发展
  13. 保存360锁屏壁纸批量修改文件后缀名
  14. RANSAC的实现与应用
  15. 如何使用HTML5+CSS3绘制一个QQ 企鹅Logo
  16. 小米面试offer加油
  17. ORACLE 日期加减函数
  18. 微生物16S测序数据的正确打开方式
  19. Linux安装RPM包、查看本机ip和端口、手动配置ip、中标麒麟无法显示ip地址的详细解决方法
  20. Element Plus 虚拟化表格组件的使用(排序、筛选、自定义单元格渲染) - 个人使用总结

热门文章

  1. 中国银行app,H5页面调取支付,并返回状态码。
  2. JAE触摸屏维修JAE人机界面维修UT3-TS5-B
  3. antd 表单通过form.getFieldsValue获取不全tabs组件下表单数据的问题
  4. 给自己定一系列小目标
  5. BZOJ 2429: [HAOI2006]聪明的猴子
  6. zoj3551 Bloodsucker//概率dp
  7. 思维导图 基础篇(03)思维方法-发散/聚合思维
  8. 最简单linux桌面环境,推荐:轻型简易的Linux桌面环境
  9. python添加背景图片_Python实例 tkinter canvas (设置背景图片及文字)
  10. 论我是如何被自己搭建的聊天机器人气死的(自己的搞笑经历)