MMORPG programming in Silverlight Tutorial (11) Map Mask
I introduce map presentation in the previous chapters. In general, it is enough to simple games; but we need to spend more energy on the map to simulate real world and achieve more realistic effect. This chapter will focus on how to implement map mask.
First, let’s have a look at what a complete map should include.
From the picture above, we can see that the bottom picture is the original map, shown in the game. We have discussed it before. Now let’s put our attention on the top picture. It is a tree, when the sprite moves behind the tree, he will be masked by the tree, so we called it “mask”.
We cut this tree from the original picture, make the image’s background transparent. And last, we add all these picture in the canvas, the sequence from top to bottom is: mask, sprite, map. Make sure all the masks are put in their proper position where they stay before in their original picture.
The principle sound reasonable. Let’s implement it in code now.
In our demo, we use this picture as our map:
Obviously, there are 3 obstructions, I mark them in green grid. And there are two trees in the map, they are both mask, I cut them from the map, and named them Mask1.png and Mask2.png, as follows:
OK, let’s modify the code base on the demo in Chapter 10.
1st, set up 3 obstructions in the method InitMatrix.
for (int y = 22; y <= 24; y++) { for (int x = 5; x <= 16; x++) { //障碍物在矩阵中用0表示 matrix[x, y] = 0; rect = new Rectangle() { Fill = new SolidColorBrush(Colors.Green), Opacity = 0.3, Stroke = new SolidColorBrush(Colors.Gray), Width = gridSize, 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++) { matrix[x, y] = 0; rect = new Rectangle() { Fill = new SolidColorBrush(Colors.Green), Opacity = 0.3, Stroke = new SolidColorBrush(Colors.Gray), Width = gridSize, 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++) { matrix[x, y] = 0; rect = new Rectangle() { Fill = new SolidColorBrush(Colors.Green), Opacity = 0.3, Stroke = new SolidColorBrush(Colors.Gray), Width = gridSize, Height = gridSize }; Carrier.Children.Add(rect); Canvas.SetLeft(rect, x * gridSize); Canvas.SetTop(rect, y * gridSize); } }
2nd, set up two mask.
//create mask 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); }
From the code above, I set the mask1’s ZIndex property to 10000 in the canvas, because the map size is less than 10000 in width and height, the mask will always in front of the sprite.
You can also find I set the mask1.Opacity to 0.7, so if the sprite move behind the tree, he won’t be hidden by the tree completely, we can still see him, because it’s easy to control the sprite, although the sprite image is not so clear, more or less.
OK, press Ctrl+F5, and move the sprite behind the tree, we can see that the sprite was “hidden” from our view.
But, when we move the sprite in front of the tree, we find a strange appearance, the sprite is still be hidden by the tree. So we must modify our code to fix this issue. We need to set sprite’s ZIndex property as the sprite moves in y-coordinate:
double y = Canvas.GetTop(sprite); Canvas.SetZIndex(sprite, (int)y);
And we also need to set the mask’s ZIndex property to its actual value, rather than 10000.
double y = Canvas.GetTop(mask1); Canvas.SetZIndex(mask1, (int)y);
But it is not the right time to do this modification, I will leave this issue until I set up a sprite control, I will set up a DependencyProperty in it and implement this dependency between the top and the ZIndex properties.
BTW, in the game domain, we call this technique that hidden-appear in multiple layers as Painter Algorithm.
Summary: This chapter introduces map mask and part of the Painter Algorithm.
Next chapter, we will focus on another map type, Instance, which can help us to detect the region by picking up the colors. Please focus on it.
Chinese friend, you can also visit this Chinese blog if you feel difficult to read English, http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html, part of my article is base on it.
Demo download: http://silverlightrpg.codeplex.com/releases/view/40978
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
2008-02-28 关于父子类方法的继承
2008-02-28 两道MS的面试题 及答案