项目源码地址:https://github.com/zxf20180725/pygame-jxzj,求赞求星星~

工作太忙啦,没啥时间更新博客,大家有什么疑问,欢迎加q群讨论,刚创的:812095339

1.添加网格线

为了让大家能更直观的感受到地图是一个个小格子,我在GameMap类中又新增了一个绘制网格线的方法:

    def draw_grid(self, screen_surf):"""画网格"""for x in range(self.w):for y in range(self.h):if self[x][y] == 0:  # 不是障碍,画空心的矩形pygame.draw.rect(screen_surf, (255, 255, 255), (self.x + x * 32, self.y + y * 32, 32, 32), 1)else:  # 是障碍,画黑色实心的矩形pygame.draw.rect(screen_surf, (0, 0, 0), (self.x + x * 32 + 1, self.y + y * 32 + 1, 30, 30), 0)

功能很简单:不是障碍就绘制空心矩形,是障碍就绘制实心矩形。我们在绘图函数中调用:

    def update(self):while True:self.clock.tick(self.fps)# TODO:逻辑更新self.event_handler()# TODO:画面更新self.game_map.draw_bottom(self.screen_surf)Sprite.draw(self.screen_surf, self.hero, 100, 100, 0, 0)Sprite.draw(self.screen_surf, self.hero, 210, 120, 1, 1)Sprite.draw(self.screen_surf, self.hero, 300, 100, 2, 2)self.game_map.draw_top(self.screen_surf)self.game_map.draw_grid(self.screen_surf)pygame.display.update()

画风突然鬼畜起来了,哈哈~

其中黑色的格子就是障碍啦。

2.人物行走类

在寻路之前,先得把我们的行走功能(动画效果、人物面向)搞定。人物行走的逻辑相对之前的代码是要复杂一些的,所以动手写代码之前,得好好分析几个问题。

1.角色id:我们使用的是一张集成了所有角色的精灵图,但是不同的角色在图片中的位置都各不相同。这时,我们就需要一个角色id来确定每个角色在图片中的位置。如何优雅的设计人物id呢?我们先看一张图:

我将每一帧都进行了编号0~95。那么第一个角色的id就是0,第二个角色id是3,第三个是6,第四个是9,第五个是48...

可以发现,我把每个角色第一帧的编号当作了它的id,而不是直接让角色id按照1,2,3,4,5...的顺序排下去。

这样做的好处是什么呢?

我们来回忆一下之前封装的Sprite.draw:

draw(dest, source, x, y, cell_x, cell_y, cell_w=32, cell_h=32)

cell_x和cell_y代表精灵图中的列和行

所以,我们就可以直接通过角色id计算出角色第一帧的cell_x和cell_y。

cell_x=角色id%12 ,因为每行有12列,所以对12取余是列数

cell_y=角色id//12,每行12个,所以除以12就是行数

2.只算出来第一帧可不行,每个角色一共4*3=12帧,怎么确定角色当前是12帧的哪一帧呢?

我们可以用一个方向变量dir记录角色当前的方向,取值范围是0~3(一共4个方向),再用一个当前帧变量frame记录角色在当前方向的第几帧,取值范围是0~2(每个方向有3帧)。

所以角色在移动过程中的列和行就是:

cell_x=角色id%12+frame

cell_y=角色id//12+dir

3.人物移动逻辑

假设我们已知:1.角色在地图中的格子的行cur_my和列cur_mx  2.角色下一步将要去的格子的行next_my和列next_mx

那么角色当前的绘图坐标是:cur_x=cur_mx*32,cur_y=cur_my*32。

角色的下一步格子的绘图坐标就是:dest_x=next_mx*32,dest_y=next_my*32。

因为一个格子是32*32的,所以实际的绘图坐标需要*32。

然后,我们需要在游戏主循环里不断的去执行以下逻辑:

如果cur_x大于dest_x,那么cur_x-=2,其中这个2代表每次主循环角色移动的像素。

如果cur_x小于dest_x,那么cur_x+=2。

cur_y也是同理

当cur_x==dest_x并且cur_y==dest_y的时候,就代表角色已经移动到目标位置了。

理解了上面说的三个问题之后(没理解就配合下面的代码再思考一遍),我们就可以开始编写人物行走类了,在core.py中增加:


class CharWalk:"""人物行走类 char是character的缩写"""DIR_DOWN = 0DIR_LEFT = 1DIR_RIGHT = 2DIR_UP = 3def __init__(self, hero_surf, char_id, dir, mx, my):""":param hero_surf: 精灵图的surface:param char_id: 角色id:param dir: 角色方向:param mx: 角色所在的小格子坐标:param my: 角色所在的小格子坐标"""self.hero_surf = hero_surfself.char_id = char_idself.dir = dirself.mx = mxself.my = myself.is_walking = False  # 角色是否正在移动self.frame = 1  # 角色当前帧self.x = mx * 32  # 角色相对于地图的坐标self.y = my * 32# 角色下一步需要去的格子self.next_mx = 0self.next_my = 0# 步长self.step = 2  # 每帧移动的像素def draw(self, screen_surf, map_x, map_y):cell_x = self.char_id % 12 + int(self.frame)cell_y = self.char_id // 12 + self.dirSprite.draw(screen_surf, self.hero_surf, map_x + self.x, map_y + self.y, cell_x, cell_y)def goto(self, x, y):""":param x: 目标点:param y: 目标点"""self.next_mx = xself.next_my = y# 设置人物面向if self.next_mx > self.mx:self.dir = CharWalk.DIR_RIGHTelif self.next_mx < self.mx:self.dir = CharWalk.DIR_LEFTif self.next_my > self.my:self.dir = CharWalk.DIR_DOWNelif self.next_my < self.my:self.dir = CharWalk.DIR_UPself.is_walking = Truedef move(self):if not self.is_walking:returndest_x = self.next_mx * 32dest_y = self.next_my * 32# 向目标位置靠近if self.x < dest_x:self.x += self.stepif self.x >= dest_x:self.x = dest_xelif self.x > dest_x:self.x -= self.stepif self.x <= dest_x:self.x = dest_xif self.y < dest_y:self.y += self.stepif self.y >= dest_y:self.y = dest_yelif self.y > dest_y:self.y -= self.stepif self.y <= dest_y:self.y = dest_y# 改变当前帧self.frame = (self.frame + 0.1) % 3# 角色当前位置self.mx = int(self.x / 32)self.my = int(self.y / 32)# 到达了目标点if self.x == dest_x and self.y == dest_y:self.frame = 1self.is_walking = False

其中,self.x和self.y就是问题分析中的cur_x,cur_y。

在draw函数中,传入了两个参数map_x和map_y,这是地图的绘图坐标,我们的self.x,self.y都是相对于地图的,所以要加上地图绘图坐标才是实际的角色绘图坐标。

这个类的代码也不是很多,大家一定要理解透彻哦~

最后我们来看一下效果,让我们的0号角色从(5,10)走到(14,10):

在__init_game中创建我们的角色:

    def __init_game(self):"""我们游戏的一些初始化操作"""self.hero = pygame.image.load('./img/character/hero.png').convert_alpha()self.map_bottom = pygame.image.load('./img/map/0.png').convert_alpha()self.map_top = pygame.image.load('./img/map/0_top.png').convert_alpha()self.game_map = GameMap(self.map_bottom, self.map_top, 0, 0)self.game_map.load_walk_file('./img/map/0.map')self.role = CharWalk(self.hero, 0, CharWalk.DIR_DOWN, 5, 10)self.role.goto(14, 10)

别忘了,在绘图函数中显示角色:

    def update(self):while True:self.clock.tick(self.fps)# 逻辑更新self.role.move()self.event_handler()# 画面更新self.game_map.draw_bottom(self.screen_surf)self.role.draw(self.screen_surf, self.game_map.x, self.game_map.y)self.game_map.draw_top(self.screen_surf)pygame.display.update()

运行效果:

本章完,请完全理解本章内容后再继续阅读后续章节喔~

有问题可以直接在评论中留言。

pygame网络游戏_4_2:人物行走_角色移动效果相关推荐

  1. Array王锐大神力作:osg与PhysX结合系列内容——第5节 角色动画效果(上)

    [Array王锐大神力作]osg与PhysX结合系列内容--角色动画效果(上) 物理引擎先放一边 动画库ozz-animation 动画资源管理 载入和预处理动画 合并到OSG显示 物理引擎先放一边 ...

  2. Array王锐力作:osg与PhysX结合系列内容——第5节 角色动画效果(下)

    [Array王锐大神力作]osg与PhysX结合系列内容--角色动画效果(下) 角色动作的过渡切换 角色动画高级技巧 构建测试场景并运行 数据驱动的角色运动 角色动作的过渡切换 我们在研究下一步的高级 ...

  3. unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect

    unity_NGUI系统学习(十)_PlaySound添加声音_添加打字机效果TypewriterEffect<7/10/2017> 1.因为要实现声音的交互,首先你得给目标对象添加一个B ...

  4. Unity3D游戏开发之仿仙剑奇侠传角色控制效果

    在上一篇文章中,我们从Unity3D为我们提供的相机原型实现了非编码式的小地图,如果结合GUI在这个小地图下面绘制一些背景贴图,相信整体的效果会更好一些.博主希望这个问题大家能够自己去做更深入的研究, ...

  5. pygame网络游戏_1:简介

    工作太忙啦,没啥时间更新博客,大家有什么疑问,欢迎加q群讨论,刚创的:812095339 1.文章简介 三年前,我和一位网友一起开发了一款网络游戏<间隙之间>.当初,只是想实现我的游戏梦, ...

  6. pygame的mask测试_作者:李兴球

    """ mask测试,mask就是膜或罩的意思,可以从一个图片创建一个mask,但要转换alpha的,否则就失去了意义. 我们可以想像给一个透明的图片覆一层膜,也就是ma ...

  7. pygame网络游戏_4_1:人物行走_地图设计

    项目源码地址:https://github.com/zxf20180725/pygame-jxzj,求赞求星星~ 工作太忙啦,没啥时间更新博客,大家有什么疑问,欢迎加q群讨论,刚创的:81209533 ...

  8. python方向键控制角色_用python和pygame游戏编程入门-控制角色移动

    在上一节中我们知道了事件,以及如何捕捉键盘事件进行响应,本届我们结合第一节何上一节的内容,做一个用键盘控制角色移动的功能,代码如下: #!/usr/bin/env python #指定图像文件名称 b ...

  9. pygame网络游戏_5_5:网络编程_游戏客户端【终章!】

    项目源码地址:https://github.com/zxf20180725/pygame-jxzj,求赞求星星~ 1.本章效果 2.回顾 哎呀呀,好久没更新了,这几天一直在搞我的pygame新项目仙剑 ...

最新文章

  1. 一文详解点云分割算法
  2. Exchange Server 2016管理系列课件33.通讯组仲裁
  3. Log binomial 回归在队列中的应用
  4. W3C api 抓取
  5. 数据结构与算法-- 广度优先打印二叉树
  6. 字符集_第07期:有关 MySQL 字符集的 SQL 语句
  7. 引用自己创建的css样式表_如何使用CSS创建联系表
  8. O2O、C2C、B2B、B2C的区别
  9. MongoDB副本集学习(三):性能和优化相关
  10. VB.NET rdlc 报表的使用
  11. 2018年最好的8款杀毒软件
  12. canvas 画空心圆 实心圆
  13. python实现雪花飘落效果_python实现雪花飘落效果实例讲解
  14. python爬取自如房间信息(一)
  15. C语言写货郎问题(贪心算法)
  16. java创建动态二维数组
  17. 探究C++:虚函数表究竟怎么回事?
  18. Centos7.6下Ceph搭建
  19. 华硕电脑黑屏 怎么按都开不了机解决方法
  20. 猫鸡米问题java_人猫鸡米渡河问题的数学模型.doc

热门文章

  1. android使用httpCanary抓包并解决不能联网问题
  2. 无法启动游戏 因为计算机,WeGame只需五步即可解决游戏无法启动的问题!
  3. 软件测试电视机怎么测试,现在不怕被骗!教你终极电视测试技巧
  4. Lua点号和冒号区别
  5. java水果忍者7723_水果忍者java手机版下载|
  6. 美国科技公司实习生薪酬:最高月薪7500美元
  7. 考研经历——跨考惊险逆袭C9院校
  8. 2021雅虎百度指数批量查询软件【多线程】
  9. TP6 ------withSearch使用
  10. 物流中转站---最短距离和