角色和背景遮挡半透明效果的实现

2024-08-27 04:08

本文主要是介绍角色和背景遮挡半透明效果的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里讲的是关于2D游戏的角色和背景以及物体之间的遮挡关系,用半透明角色处理的讨论和实现方式。这里主要是讨论关于页游《火影忍者》里对于角色和背景物体之间的遮挡处理方式。同时也实现了和他一样的效果(可能)。具体是没分析火影的代码,只是猜测了它的原理然后进行实现的。其他的几种实现方式则简单的讨论,一笔带过(如果有人有兴趣,可以留言,我再单独写篇Blog和相关例子来) 
实现语言:ActionScript3.0(传统的显示处理,Stage3D可以做到有些不一样,所以不在讨论范围) 
心急的读者可以直接从第三点开始看我们今天的主题实现内容。

一、需要实现遮挡关系的原因

个人推测和分析,不妥之处请之处讨论。 
1. 因为AS3传统显示2D图像的时候,没有zbuff缓冲这个概念,所以显示图像的层次关系,是按照addChild的顺序来的. 
2. 为了实现最大的渲染效率,一般美术会把游戏场景渲染成大的一张图片,然后再切割成小块进行加载显示。整个场景的所有元件,包括背景、树、建筑、河流等等,都是渲染出一张图。 
那么问题来了,建筑和背景树等物体都渲染地图上,那人物走过来的时候,这个时候的遮挡关系怎么处理呢?所以就会衍生出各种处理这种遮挡关系的技术了。

二、角色物体遮挡的几种做法

首先简单讨论几种实现方式。 
1. 和角色同层,根据深度重新设置addChild 
这是比较消耗性能的做法,也是早期很多游戏的做法,表现效果也很好。同时也是一些3D游戏场景的做法(3D有zbuff缓冲)。出一个地图编辑器,然后把导入背景,把各种元件(树、建筑等等)拖到场景去,最后导出。在游戏中人物就和元件参与深度排序,处理遮挡关系。 
现在一般是采用后面的两种做法了,在一些特别需要表现力的时候,才会单独做成元件,不然都是合在背景里了。 
这里写图片描述 
2. 地图编辑器打格子表明走到的角色半透 
这个是页游红极一时的做法,大部分rpg和arpg都是这么做的。比如《凡人修真2》和雄霸页游天下的《传奇霸业》,下面传奇霸业的表现效果(刚截的图)。 
这里写图片描述 
具体的实现方式大概走格子走到这个建筑的时候,会检测格子的属性,如果带有半透效果的参数,则设置角色的alpha值。 
3. 背建筑遮挡的部分才半透,效果高大尚。 
读者:这个是3D做法吧! 
当然不是了,通过2D图像混合一样可以做到。(原理估计也是3D那一套。就是提供的遮罩图来擦出下面的的图片)。这个算是比较新颖的做法,目前我就看腾讯的《火影忍者》,其他的就暂时没去查看了(我自己做的游戏是采用这个最新的做法,潮流嘛)。 
开始还担心性能会比较大损耗,做了简单测试,发现没什么影响。先看火影里的表现效果吧 
这里写图片描述 
仔细看红框里的那个角色,可以发现角色被那个柱子挡住的一半是半透明效果,没挡住的就是原来的颜色。简直酷毙了! 
立马把火影的缓存搞下来,发现它是加了背景遮罩图,然后类似3D混合图形的做法实现的。后来会详细地讲。(啰嗦了这么久,终于开始正题了)

三、火影的角色遮挡半透实现分析

仔细分析了火影的新手村场景,从缓存了除了提取出背景之外,还有另外一些黑色的古怪图片。背景还是跟其他游戏的做法,古怪的是那个黑色怪图。发现是背景里的一些建筑物的黑色图。下面是缩略图。 
这里写图片描述 
刚开始还以为是逐像素匹配,自己手动实现的(可以做到的),但是效率会残不忍堵。另外想到的就是3D里 
常用的图像混合处理了。查下AS3的Bitmap的API,还真查找到了。这里只列出会用到的API。

DisplayObject.blendMode属性
BlendMode 类中的一个值,用于指定要使用的混合模式。
  • 1
  • 2

用到了BlendMode类的两个属性

LAYER : String = "layer"
[静态] 强制为该显示对象创建一个透明度组。
  • 1
  • 2
ERASE : String = "erase"
[静态] 根据显示对象的 Alpha 值擦除背景。
  • 1
  • 2

其他的API也有趣,有兴趣的同学可以试试。

四、角色遮挡半透的实现的例子资源

整理了一下相关使用到的资源。实际上问过美术,美术说出这个遮罩图非常容易。我们也实际出了相关的资源。 
1. 背景图 
把火影的背景图给拼起来,合成一张1274 * 768的大背景图方便测试 
2. 透明背景遮罩图 
同样把透明遮罩剪切出和背景对应部分截取出来,然后对好位置。这个图的透明度决定了角色的显示效果 
3. 角色资源图 
这里写图片描述

五、简单的代码实现原理过程

  1. 背景层独立出来,不参与图像混合
  2. 角色和透明遮罩单独一个容器层,但是这两种都在同一个容器A中
  3. 容器A的blendMode属性设置为:
//强制为该显示对象创建一个透明度组
blendMode = BlendMode.LAYER;
  • 1
  • 2
  1. 角色容器不用设置blendMode,因为在容器A中设置就可以了
  2. 透明遮罩这个Bitmap需要设置
blendMode = BlendMode.ERASE;
  • 1

确保透明遮罩Bitmap在角色容器的上层就可以了。下面是具体的代码实现过程。

六、详细的代码

看代码实现起来非常简单,代码也非常简洁

package
{import flash.display.Bitmap;import flash.display.BlendMode;import flash.display.Sprite;import flash.events.Event;import flash.events.MouseEvent;/*** 地图透明角色测试例子* @author sodaChen* Date:2017-2-16*/[SWF(width="1274",height="768")]public class AlphaMapTest extends Sprite{/** 背景 **/[Embed(source = "res/alpha/bg.jpg")]private var bgClass:Class;/** 透明遮罩背景 **/[Embed(source = "res/alpha/alphaBg.png")]private var alphaBgClass:Class;/** 角色 **/[Embed(source = "res/alpha/role.png")]private var roleClass:Class;/** 角色容器 ,用来存放角色和透明图像的**/private var roleContainer:Sprite;/** 角色层,只放角色 **/private var roleLayer:Sprite;public function AlphaMapTest(){super();addEventListener(Event.ADDED_TO_STAGE,onStage);}private function onStage(evt:Event):void{//添加背景addChild(new bgClass());//添加角色容器roleContainer = new Sprite();//强制为该显示对象创建一个透明度组roleContainer.blendMode = BlendMode.LAYER;addChild(roleContainer);//创建角色层,其实角色可以不用单独容器,但是必须保证alphaBg在所有角色的最上面roleLayer = new Sprite();roleContainer.addChild(roleLayer);//创建角色并添加到角色容器中createRole(300,120);createRole(230,550);//不会被遮挡的角色createRole(400,200);//根据显示对象的 Alpha 值擦除背景.这个透明图像必须在最顶层,确保下面的角色会被擦出var alphaBg:Bitmap = new alphaBgClass();alphaBg.blendMode = BlendMode.ERASE;roleContainer.addChild(alphaBg);}//创建角色private function createRole(roleX:int,roleY:int):void{var role:Sprite = new Sprite();var roleBitmap:Bitmap = new roleClass();role.x = roleX;role.y = roleY;role.addChild(roleBitmap);roleLayer.addChild(role);role.addEventListener(MouseEvent.MOUSE_DOWN,onMouse);role.addEventListener(MouseEvent.MOUSE_UP,onMouse);}private function onMouse(evt:MouseEvent):void{var role:Sprite = evt.currentTarget as Sprite;if(evt.type == MouseEvent.MOUSE_DOWN)role.startDrag();elserole.stopDrag();}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

最终实现的效果图: 
这里写图片描述
例子代码下载: 
2DAS3游戏地图角色遮罩

版权声明:本文为博主原创文章,转载必须声明出处和作者。地址:http://blog.csdn.net/sujun10 作者:弃天笑

这篇关于角色和背景遮挡半透明效果的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110593

相关文章

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体