C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十一)地图遮罩层的实现

    前面的章节主要针对地图表现层进行讲解。通常来说,简单的游戏光有它就足够了;但是为了达到更加真实的光影效果,模拟真实的虚拟世界,我们还得继续在地图上下大工夫。本节将就如何实现地图中的遮罩层,即物体对角色的遮挡进行详细讲解。

    首先我们来看一张比较完善的地图应该包含哪些内容:

    从上图可以看到,我将一张地图引擎结构分成了3层(难道这就是传说中的地图三层架构?汗一个先。。。)。中间的图片代表地图的表现层,也就是我们视觉上直接看到的地图界面。关于它,前面的章节中已有非常多的讲解,这里就不再累述了。接着我们再看最下面那张:地图底层,它由黑白两大颜色组成,似乎还有一圈黄色在右小角呢。有的朋友觉得它很奇怪,似乎摸不着头脑,好象和地图没啥关系吧?其实只要将它和第二张图进行分析比较就会发现,它上面的黑色就是地图中障碍物区域,白色则为可以通行的区域,那黄色呢??还有朋友要问了:前面的章节不是有讲A*寻路吗?通过Matrix[]数组来构建障碍物不是很完美吗?那为什么还要多此一举再为每张地图构造一张同比例的障碍物底层图呢?我只想告诉广大的朋友们:它的作用可大了,尤其尤其在目前的Silverlight游戏开发中,它的作用及拓展性可谓承前启后,用科学发展观的话讲就是:面向对象的思维开发Silverlight游戏。太多太多的悬念,才能有更多的期待,那么关于这张神秘底层图的讲解,请听下回分析。

    读者声音:同志,你也太假了吧,这样就讲完这节啦?BS你一下。

    作者:安啦,怎么可能嘛,这叫倒叙懂不?(啥叫倒叙其实俺也不太。。。?嘿嘿)

  不瞎扯啦,还剩一张图没讲呢,对啦,本节的主角就是它了:地图遮罩层。

  首先来讲讲实现原理吧:我们可以从地图表现层(下文直接就称之地图好了)中看到,遮挡人物的只有一棵树。那么我们想要在此地图上实现遮罩效果,首先就得用Photoshop将这棵树给截出来,当然越精确越好,然后将它单独保存成一张背景透明的图片(通常Windows桌面RPG游戏中会将所有的遮挡物统一规格,例如50*50一张(如大于则分两张、三张等等),然后将全部遮挡物图片放进一个庞大的二进制文件中,显然这对于Silverlight基于网页的游戏是不容许的),如果一张地图上有多个遮挡物,同样将他们都截取出来然后依次命名保存。准备工作做完后,我们就需要将遮罩层的图片放在顶层,将地图放在底层,人物等放在中间层。最后分别将遮罩层的所有图片布局到它们应该遮挡的位置上,这样就完成了所有的遮挡工作了。好了。下面我将用代码来实现它。

    这里我以下图作为地图实例:

    很明显该地图有三处障碍物,两处遮挡物。障碍物我用绿色区域描绘出来了,遮挡物则为两棵数,我用Photoshop将它们分别截取了出来命名为:Mask1.pngMask2.png

  匆忙了点,截得不好可不要见怪哪!谁让这两棵树长得如此奇怪呢?嘿嘿。

    OK,接下我以第九节的代码为基础进行修改,首先构建障碍物:

            //构建障碍物

            for (int y = 22; y <= 24; y++) {

                for (int x = 5; x <= 16; x++) {

                    //障碍物在矩阵中用0表示

                    Matrix[x, y] = 0;

                    rect = new Rectangle();

                    rect.Fill = new SolidColorBrush(Colors.GreenYellow);

                    rect.Opacity = 0.3;

                    rect.Stroke = new SolidColorBrush(Colors.Gray);

                    rect.Width = GridSize;

                    rect.Height = GridSize;

                    Carrier.Children.Add(rect);

                    Canvas.SetLeft(rect, x * GridSize);

                    Canvas.SetTop(rect, y * GridSize);

                }

            }

            for (int y = 11; y <= 14; y++) {

                for (int x = 27; x <= 31; x++) {

                    //障碍物在矩阵中用0表示

                    Matrix[x, y] = 0;

                    rect = new Rectangle();

                    rect.Fill = new SolidColorBrush(Colors.GreenYellow);

                    rect.Opacity = 0.3;

                    rect.Stroke = new SolidColorBrush(Colors.Gray);

                    rect.Width = GridSize;

                    rect.Height = GridSize;

                    Carrier.Children.Add(rect);

                    Canvas.SetLeft(rect, x * GridSize);

                    Canvas.SetTop(rect, y * GridSize);

                }

            }

            for (int y = 18; y <= 21; y++) {

                for (int x = 33; x <= 37; x++) {

                    //障碍物在矩阵中用0表示

                    Matrix[x, y] = 0;

                    rect = new Rectangle();

                    rect.Fill = new SolidColorBrush(Colors.GreenYellow);

                    rect.Opacity = 0.3;

                    rect.Stroke = new SolidColorBrush(Colors.Gray);

                    rect.Width = GridSize;

                    rect.Height = GridSize;

                    Carrier.Children.Add(rect);

                    Canvas.SetLeft(rect, x * GridSize);

                    Canvas.SetTop(rect, y * GridSize);

                }

            }

    三个循环分别构建了上图中的三处障碍物,这几章都对它进行了修改,大家应该再熟悉不过了。接下来就是遮挡物那两棵树了,这里我用Image控件作为遮挡物的容器:

        //创建遮罩层

        Image Mask1 = new Image();

        Image Mask2 = new Image();

        private void InitMask() {

            Mask1.Width = 238;

            Mask1.Height = 244;

            Mask1.Source = new BitmapImage((new Uri(@"Map\Mask1.png", UriKind.Relative)));

            Mask1.Opacity = 0.7;

            Carrier.Children.Add(Mask1);

            Canvas.SetZIndex(Mask1, 10000);

            Canvas.SetLeft(Mask1, 185);

            Canvas.SetTop(Mask1, 220);

            Mask2.Width = 198;

            Mask2.Height = 221;

            Mask2.Source = new BitmapImage((new Uri(@"Map\Mask2.png", UriKind.Relative)));

            Mask2.Opacity = 0.7;

            Carrier.Children.Add(Mask2);

            Canvas.SetZIndex(Mask2, 10000);

            Canvas.SetLeft(Mask2, 466);

            Canvas.SetTop(Mask2, 11);

        }

    这样就将遮挡物加入进了游戏窗体。有了前面那么多章节关于Image控件的使用知识,上面的代码应该不难理解。这里特别要说一下的是为什么要将它们的Opacity设置为0.7:因为这样的遮挡物会有一定的透明度,当角色置身其中时会若隐若现,从而达到真实模拟MMORPG的效果。至于为什么要将遮挡物的Zindex属性设置为10000呢?这关系到游戏运行时地图中不光只有一个角色,还会有非常多的物体及对象角色的存在,它们之间也同样有着相互遮挡与被遮挡的关系。而在WPF/Silverlight游戏中,物体的遮挡顺序一样可以使用画家算法,该算法原理简单描述就是近物遮挡远物,幸运的是在WPF/Silverlight中,我们可以很方便的只要动态更新(一个对象的Zindex属性)=(它的Y属性)即可以巧妙的实现此效果,是不是有点邪恶?嘿嘿。所以要将遮盖物的ZIndex设置得足够大以防止任何一个物体它的Y属性大过遮盖物的Zindex属性,从而造成画面显示BUG

    其他的代码均和第九章的一样,到这,本节的目标已经达到了。那么让我们运行测试一下吧:

  大家可以随便在地图上点击,会发现只要主角有经过这两棵树的地方都会被树以0.7的透明度遮挡,并且障碍物也同样并行存在着,主角如有经过同样会饶过它。障碍物,人物,遮罩层次分明,互不干预,完美默契的并行着。

    至此,地图引擎就基本完成了。下一节将讲解本节开始所提到的神秘第三层,它在WPF/Silverlight游戏辅助方面起着非常大的拓展作用,敬请关注。

WPF/Silverlight
作者:深蓝色右手
出处:http://alamiye010.cnblogs.com/
教程目录及源码下载:点击进入(欢迎加入WPF/Silverlight小组 WPF/Silverlight博客团队)
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/alamiye010/archive/2009/06/17/1505343.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python+selenium自动化】使用pytest+allure2完成自动化测试报告的输出

pytest的pytest-html插件是一个很方便的测试报告&#xff0c;运行自动化测试用例时&#xff0c;pytest后加上参数即可 allure是一个测试报告的框架&#xff0c;相比pytest-html的优势就是“逼格” 他的优点除了好看&#xff0c;还有几点&#xff1a; 1、可以把测试的步骤都加到…

优麒麟在linux下安装教程,在优麒麟Ubuntu Kylin系统中安装百度网盘Linux版.deb的方法...

本文介绍在优麒麟Ubuntu Kylin操作系统中安装百度网盘Linux版.deb的方法&#xff0c;可用在优麒麟及 Ubuntu 19.04/18.04上&#xff0c;当前百度网盘Linux版的版本号是Linux V2.0.1&#xff0c;目前下载只提供rpm格式&#xff0c;可看百度网盘Linux版发布&#xff0c;支持中标麒…

js使用正则实现表单验证

## 定义javascript代码 定义方法 定义正则表达式 布局 转载于:https://www.cnblogs.com/wjy0928/p/10885992.html

吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:设定文本对齐,段落中超出屏幕部分文字自动换行...

<!DOCTYPE html> <html><head><title>菜鸟教程(runoob.com)</title> <meta name"viewport" content"widthdevice-width, initial-scale1" charset"utf-8"><link rel"stylesheet" href"ht…

GDAL读取Shp问题解决:Unable to open EPSG support file gcs.csv

在GIS软件的开发中&#xff0c;经常用到开源库GDAL读取Shp数据&#xff0c;当shp数据中包含投影信息时&#xff0c;可能会遇到“Unable to open EPSG support file gcs.csv”错误提示&#xff0c;该错误是由于没有设置“GDAL_DATA”引起的。 1.Shpefile文件组成 Shapefile文件指…

linux系统扩展名大全,Linux系统文件扩展名学习

Linux系统下的扩展名并不能标识该文件是属于哪一种类型的文件。文件是否可以执行等都跟文件的扩展名无关。因为文件script没有执行权限&#xff0c;所以也就无法执行&#xff0c;sh-3.2# touch ./scriptsh-3.2# ls -lh ./script-rw-r--r-- 1 root root 0 Dec 28 06:15 ./script…

[html] 如何实现多行文字梯形排版?

[html] 如何实现多行文字梯形排版&#xff1f; 可以利用文字会环绕浮动元素的特性来做&#xff1a;HTML:#box {width: 400px;height: 600px;background-color: red; } #box .float-div{float: left; // 浮动起来clear: both; // 这个很重要&#xff0c;不然会排版出错backgrou…

biztalk在用户代码中构造多部分消息

大家知道&#xff0c;biztalk中可以在orchestration调用外部用户代码进行功能扩展&#xff0c;调用外部方法可以把消息作为参数传给外部方法&#xff0c;当然也可能需要外部方法返回一个消息到orchestration。<?xml:namespace prefix o />对于schema类型的消息&#xf…

背景透明度 下拉菜单

下拉菜单 ——————> <style> /* 下拉按钮样式 */ .dropbtn {background-color: #4CAF50;color: white;padding: 16px;font-size: 16px;border: none;cursor: pointer; }/* 容器 <div> - 需要定位下拉内容 */ .dropdown {position: relative;display: inlin…

datavideo切换台说明书_巴掌大三轴稳定器,稳过微云台,试试飞宇VLOGPocket2

几乎全民VLOG的时代&#xff0c;我们随处可见有人举着手机、相机记录生活&#xff0c;甚至还有品牌推出了自带微云台的手机。不过&#xff0c;即便在手机上硬“塞”进一个微云台&#xff0c;效果也始终无法媲美真正的云台&#xff0c;对视频拍摄的提升相对有限&#xff0c;大部…

VSCode中Markdown目录显示异常

更新最新的VSCode之后编辑Markdown文件发现TOC标签的目录格式异常&#xff0c;发现是因为行尾字符导致&#xff0c;必须设置行尾字符进行解决。 转载于:https://www.cnblogs.com/phonecom/p/10904785.html

dlp防泄密系统卸载_怎样做好数据防泄密?奥赛系统早知道

前言大数据是趋势&#xff0c;泄密和数据泄露时常发生。员工离职、文件外传、在线拷贝..... 数据安全已经是每家公司必做功课。企业现状企业垂青“工作经历”和“自带资源”,“高薪挖人”被认为是企业事务快速增长、企业研制效果快速显现、企业快速兴起的捷径。当所“挖”人才来…

30万手表推荐_一年收入20万—30万的小生意,市场上有哪些呢?推荐几个供参考...

目前经济形势不乐观&#xff0c;许多创业者都陷入泥潭中&#xff0c;总是想挣脱&#xff0c;却总是徒劳无功。我认为在这样的时期&#xff0c;如果能静下心来&#xff0c;选择去做一些有前景的小生意&#xff0c;也是一个很好的选择。那么在目前市场上&#xff0c;有哪些能年收…

Dubbo中的监控和管理

一、Dubbo中的监控 1、原理 原理&#xff1a;服务消费者和提供者&#xff0c;在内存中累计调用次数和调用时间&#xff0c;定时每分钟发送一次统计数据到监控中心。 2、搭建监控服务 3、修改配置文件 修改注册中心的地址&#xff1a; 注意&#xff1a;这个有一个client参数&…

管道抛光防锈机器人_全国首创!嵊州企业的这项防锈技术用在了雪龙号上

2019-03-26 14:22 | 浙江新闻客户端 | 记者 金汉青 通讯员 胡吉图片来源于视觉中国近日&#xff0c;嵊州春凯新材料有限公司收到了来自上海铁路局的一批订单&#xff0c;对方要求春凯新材料对合肥工务段的一座高铁桥作钢铁除锈防锈处理。据了解&#xff0c;这将是春凯新材料研发…

jzoj4640. 【GDOI2017模拟7.15】妖怪

Description Input Output Sample Input 3 1 1 1 2 2 2 Sample Output 8.0000 Data Constraint 题解 我还挺喜欢数学的呢 这题一眼看上去不会&#xff0c;化化式子没想到未知数竟然是一个反比例一次函数的样子。 长这样&#xff1a;axbx\frac a xbxxa​bx 当时心态就没了。 原来…

activiti 设置可选处理人_新品速递|高端系列!慧明DF系列线性相位处理专业音箱处理器...

2020年对很多人来说&#xff0c;是特别艰难的一年&#xff0c;一场新冠疫情&#xff0c;可谓把整个演艺行业压得喘不过气&#xff0c;但是尽管如此&#xff0c;我们仍坚决相信行业将会很快复苏&#xff0c;一切终将迎来新的生机与活力。2020年初&#xff0c;哪怕是最困难的时期…

Scrapy 教程(十)-管道与数据库

Scrapy 框架将爬取的数据通过管道进行处理&#xff0c;即 pipelines.py 文件。 管道处理流程 一、定义 item item 表示的是数据结构&#xff0c;定义了数据包括哪些字段 class TianqiItem(scrapy.Item):# define the fields for your item here like:city scrapy.Field() …

地壳中元素含量排名记忆口诀_广州地化所等发现洋内弧大陆地壳成熟新机制

大陆的形成和演化是地球科学研究中广泛关注的前沿科学问题之一。大陆地壳总体上具有安山质到英安质地球化学成分特征&#xff0c;与洋内弧中大洋俯冲作用形成的岩浆岩具有相似的微量元素地球化学特征(如富集大离子亲石元素和亏损高场强元素)&#xff0c;众多学者认为大陆地壳的…

三星+android7.0+字体,三星S7升级安卓7.0新技能:新增分辨率调整功能

三星Galaxy Note 7推出了安卓7.0的升级&#xff0c;此次升级后&#xff0c;三星S7将会增加分辨率调整功能。这个功能可以根据用户的需求和喜好来进行调整&#xff0c;在HD(7201280像素)、FHD(12801920像素)以及QHD(14402560像素)三种不同的分辨率之间自由切换。在过去的一年里&…