您的位置:首页 > 编程语言 > C#

silverlight & C#实验成果,GDE-silverlight准备开始启动

2010-04-12 10:16 162 查看
GDE-silverlight是我和几个朋友准备在silverlight上开发一款金庸群侠传X版的游戏引擎部分。

之前一直没鼓起干劲搞,这个周末终于得空,把silverlight的几个基本功能自己动手实验了一下。基本弄明白了,准备开始鼓起干劲把GDE-silverlight完成!



感觉silverlight的UI开发还是比之前HGE好多了……之前那个呼呼累啊,梦魇~



非常简单的测试了以下几点

1. 图片加载

2. 之前部分C++代码逻辑上的移植(如寻找移动、攻击区域)

3. 地图单元格绘制

4. 动画(左上角那个爆炸是个动画。。)

5. 复用QXENGINE提供的A*寻路算法,如下图红色部分所示(它这个可以斜着寻路。。到时候需要根据具体要求改)

6. 动态加载控件(如右下的对话框)

7. 加载XML数据(可作为游戏脚本及配置文件)

接下来就是准备开始着手开始写我们的游戏引擎了。









附上代码



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

using QXGame_Silverlight3.AStar;
using System.Xml.Linq;

namespace BattleTest
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            
            //加载背景图片测试
            DrawBackImage();

            //寻路测试
            FindMoveZone(4, 5, 3);

            //地图单元格
            DrawMapBack();
            
            //静态图片测试
            DrawElementPic("/pic/MM.png",4, 5);
            DrawElementPic("/pic/rolebig1.png",3, 2);
            DrawElementPic("/pic/2.png", 7, 7); 

            //动画测试
            DrawAnimation(2, 2);

            //寻路
            FindPath(3, 3, 1, 8);

            //动态加载控件
            LoadUserControl();

            //加载XML数据
            LoadXMLData();
        }

        //加载图片
        public static BitmapSource GetImage(string address)
        {
            return new BitmapImage(new Uri(string.Format(@"{0}", address), UriKind.Relative));
        }

        //绘制地图单元格
        public void DrawMapBack()
        {
            for (int i = 0; i < MAP_SIZE_X; ++i)
                for (int j = 0; j < MAP_SIZE_Y; ++j)
                {
                    DrawMapBlock(i,j);
                }
        }

        //加载背景图片
        private void DrawBackImage()
        {
            Brush brush_instance = new ImageBrush { ImageSource = GetImage("/pic/battle_back.jpg") };
            Carrier.Background = brush_instance;
        }

        //搜索角色移动范围
        bool[,] m_MoveZoneResult;
        static int[] dx = new int[4] { 0,1,0,-1 };
        static int[] dy = new int[4] { 1,0,-1,0 }; 
        private void FindMoveZone(int x, int y, int move_ability)
        {
            m_MoveZoneResult = new bool[MAP_SIZE_X, MAP_SIZE_Y];
            MoveZoneSearch(x, y, move_ability);
        }
        private void MoveZoneSearch(int x, int y, int v)
	    {
		    int tmpx,tmpy;
            m_MoveZoneResult[x, y] = true;
		    if( v == 0) return;
		    for( int i=0;i<4;i++ )
		    {
			    tmpx = x + dx[i];
			    tmpy = y + dy[i];
			    if( Visitable( tmpx ,tmpy ) )
                    MoveZoneSearch(tmpx, tmpy, v - 1);
		    }
	    }
        private bool Visitable(int x,int y) { return true; }

        //绘制地图单元格
        public void DrawMapBlock(int x, int y)
        {
            Rectangle rect = new Rectangle();
            if (m_MoveZoneResult[x, y])
                rect.Fill = new SolidColorBrush(Colors.Green);
            else
                rect.Fill = new SolidColorBrush(Colors.Yellow);
            rect.Opacity = 0.3;//透明度
            //rect.Stroke = new SolidColorBrush(Colors.Black);
            rect.Width = block_size;
            rect.Height = block_size;
            rect.RadiusX = block_radius;
            rect.RadiusY = block_radius;
            Carrier.Children.Add(rect);
            Canvas.SetLeft(rect, Transfer_X(x));
            Canvas.SetTop(rect, Transfer_Y(y));
        }

        //绘制元素(方块)
        public void DrawElement(int x, int y)
        {
            Rectangle rect = new Rectangle();
            rect.Fill = new SolidColorBrush(Colors.Red);

            rect.Width = block_size;
            rect.Height = element_height;

            rect.RadiusX = block_radius;
            rect.RadiusY = block_radius;
            Carrier.Children.Add(rect);
            Canvas.SetLeft(rect, Transfer_X(x));
            Canvas.SetTop(rect, Transfer_Y_Element(y));
        }

        //绘制图片元素
        public void DrawElementPic(string image,int x, int y)
        {
            Image SpiritInstance = new Image() { Source = GetImage(image) };
            SpiritInstance.Width = block_size;
            SpiritInstance.Height = element_height;
            Carrier.Children.Add(SpiritInstance);
            Canvas.SetLeft(SpiritInstance, Transfer_X(x));
            Canvas.SetTop(SpiritInstance, Transfer_Y_Element(y));
        }

        //坐标系转换
        public int Transfer_X(int x)
        {
            return (block_size + block_blank) * x;
        }

        public int Transfer_Y(int y)
        {
            return y_offset + (block_size + block_blank) * y;
        }

        //人物元素纵坐标转换
        public int Transfer_Y_Element(int y)
        {
            return y_offset + (block_size + block_blank) * y - (element_height - block_size);
        }

        //动画
        int count = 0;
        Image Animation;
        public void DrawAnimation(int x, int y)
        { 
            Animation = new Image();
            Animation.Width = 150;
            Animation.Height = 150;
            Carrier.Children.Add(Animation);
            DispatcherTimer dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = TimeSpan.FromMilliseconds(150);
            dispatcherTimer.Start();
        }

        private void dispatcherTimer_Tick(object sender, EventArgs e) {
            Animation.Source = GetImage("/magic/0-" + count + ".png");
            count++;
            if (count > 9) count = 0;
        }

        private IPathFinder PathFinder = null;
        private byte[,] Matrix = new byte[16, 16];//只能是2的次方……QX ENGINE的问题估计是。。
        //寻路
        public void FindPath(int start_x, int start_y, int end_x, int end_y)
        {
            Point Start = new Point(start_x, start_y);
            Point End = new Point(end_x, end_y);

            for (int i = 0; i < 16; i++)
                for (int j = 0; j < 16; j++)
                    Matrix[i,j] = 1;//假设没有障碍物

            //使用QXEngine提供的A*算法,此处可以斜方向寻路,到时候需要改……
            PathFinder = new PathFinderFast(Matrix)
            {
                HeavyDiagonals = false,
                HeuristicEstimate = 2,
                SearchLimit = 2000
            };
            List<PathFinderNode> path = PathFinder.FindPath(Start, End);

            if (path == null)
                MessageBox.Show("没有路径");
            else
            {
                for (int i = 0; i < path.Count; i++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Fill = new SolidColorBrush(Colors.Red);
                    rect.Width = block_size;
                    rect.Height = block_size;
                    rect.Opacity = 0.3;//透明度
                    Carrier.Children.Add(rect);
                    Canvas.SetLeft(rect, Transfer_X(path[i].X));
                    Canvas.SetTop(rect, Transfer_Y(path[i].Y));
                }
            }
        }

        //加载用户控件
        public void LoadUserControl()
        {
            SilverlightControl1 test = new SilverlightControl1();
            Carrier.Children.Add(test);
            test.Opacity = 0.5;
            Canvas.SetLeft(test, 400);
            Canvas.SetTop(test, 200);
        }

        //加载XML数据
        public void LoadXMLData()
        {
            XElement mapdata = GetTreeNode(XElement.Load("XMLFile1.xml"), "Map", "Name", "大地图");
            string value = mapdata.Attribute("Value").Value;
            MessageBox.Show(value);
        }

        public static XElement GetTreeNode(XElement XML, string newroot, string attribute, string value)
        {
            return XML.DescendantsAndSelf(newroot).Single(X => X.Attribute(attribute).Value == value);
        }

        //常数
        private static int element_height = 80;
        private static int block_radius = 5;
        private static int block_size = 50;
        private static int y_offset = 30;
        private static int block_blank = 2;
        private static int MAP_SIZE_X = 10;
        private static int MAP_SIZE_Y = 10;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: