标题:2d 引擎实现Sprite (大学时候的作品回复)
取消只看楼主
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
结帖率:80.91%
 问题点数:0 回复次数:2 
2d 引擎实现Sprite (大学时候的作品回复)
前段时间发了一个大学时候的作品  是关于仿泡泡堂的一个例子 呵呵 应大家要求本人才疏学浅今天就献丑给各位讲解一下 不足之处还望各位谅解

重点讲解Sprite
于是在国外网上找个2D引擎 MCDX不错 C#开发 纯ddraw的封装 不过性能不怎么样但是用这个DEMO还是足够了
MCDX.rar (2.27 MB)
大家可以装下试试  上手很快 估计不到半个小时 大家都能写个2D的Demo了 呵呵
记得引用命名空间
using MCDX;
安装后添加组件

这样工具箱就有了控件 CDXControl
//CDXControl 是一个可视组件,是唯一可以添加到工具栏上的,等同于Surface的管理器,负责控制显示设备的刷新、控制属性等等方面;
搜索更多相关主题的帖子: Sprite 引擎 大学 作品 
2010-11-14 10:24
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
程序代码:
using System;
using System.Collections.Generic;
using using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MCDX;
namespace 炸弹人
{
    public partial class sprite : Form
    {
        private CDXSprite player;//CDXSprite 就是一个精灵基类,它提供了Draw的方法,可以制定绘制到某个Surface,当然这样做很灵活,其实也可以再增加一个精灵管理类,统一管理绘制、移动、碰撞检测、消亡。
        private CDXTile playerTile;//CDXTile 负责管理Tile,比如连续的图块,它用于切割和制定存储方式(系统内存、显存)
        private CDXTimer timer;//CDXTimer 高分辨率计时器(我一直这样称呼的),很精确,比不负责任的Time消息好多了
        private CDXInput input;//CDXInput 收集键盘和鼠标的消息

        private CDXControl cdxControl1;//CDXControl 是一个可视组件,是唯一可以添加到工具栏上的,等同于Surface的管理器,负责控制显示设备的刷新、控制属性等等方面;


        System.Random random = new System.Random();
        CDXGui gui;
        /*This is the master control used for controlling the entire Gui.
            This should be the first CDXGui control created and all controls should be added to it.
            A CDXInput object should be passes to it's Update method to allow it to handle any input.*/
        //这是一个主控制用于控制图形用户接口 你创造的所有控制都必须添加到它这里
        CDXTile bugs;
        CDXTile house;
        CDXTile house1;
        CDXTile Owl;
        CDXTile tree;

        Rectangle guiRect = new Rectangle(0, 0, 120, 599);
        Rectangle spriteRect = new Rectangle(121, 0, 524, 431);
        CDXSpriteCollection bugCollection = new CDXSpriteCollection();


        CDXSpriteCollection bugCollection1 = new CDXSpriteCollection();//用于从存储的精灵中动态的进行收集
        private IContainer components = null;

        public sprite()
        {
            InitializeComponent();
        }


        private void sprite_Load(object sender, EventArgs e)
        {

        }

        private void cdxControl1_InitializeObjects(object sender, EventArgs e)
        {
            input = new CDXInput(cdxControl1.Screen, this, true, true, false);
            //cdxControl1.Screen 建立一个输入设备
            //控制被建立的设备
            //是否允许键盘控制 True to obtain keyboard access, otherwise false.
            //是否允许鼠标控制 True to obtain mouse access, otherwise false.
            //是否允许游戏手柄控制 True to obtain joystick access, otherwise false.
            playerTile = new CDXTile(cdxControl1.Screen, "player2.bmp", 48, 57, 16, MemTypes.SystemOnly);//16个图像帧
            /*This class name is somewhat deceptive given that a CDXTile object
           holds the bitmap information for all the tiles of a given map or sprite,
          rather than just one tile. CDXTile is derived from CDXSurface.
          IMPORTANT NOTES: The bitmap file containing the tiles should
          have an empty tile at the start, this is because CDX treats
          the first tile to be transparent. Tiles should be stored from
          left to right down the bitmap and should fit exactly into the
          width of the bitmap, have a look at the tiles from one of the
          examples if this is unclear. Remember to set the color key for
          the surface if you intend to draw the tiles transparently.*/
            //CDXScreen是一个很重要的对象每一个程序用到CDX时必须包含这一项它的名字也暗示了在控制视频演示时所含有的所有必须功能
            //
            //
            //“切割”数量
            //具体指定表面的内存格式
            playerTile.ColorKey = Color.FromArgb(255, 0, 255);////透明色=紫色
            //获取或设置颜色的键值  "瓦片"的背景色
            player = new CDXSprite(playerTile, -1);


            player.Animation = new CDXAnimation();
            //增加每个方向的动画关键帧
            int[] animUp = new int[6] { 8, 9, 10, 11, 10, 9 };
            int[] animDown = new int[6] { 0, 1, 2, 3, 2, 1 };
            int[] animLeft = new int[6] { 4, 5, 6, 7, 6, 5 };
            int[] animRight = new int[6] { 12, 13, 14, 15, 14, 13 };
            //添加到管理器
            player.Animation.AddAnimation(10, 0, true, animUp);//The animation frame rate. The length between frames
            player.Animation.AddAnimation(10, 0, false, animDown);
            player.Animation.AddAnimation(15, 0, true, animLeft);
            player.Animation.AddAnimation(15, 0, false, animRight);


            player.TileNumber = -1;
            player.PosX = 100;
            player.PosY = 100;


            timer = new CDXTimer();
            timer.DesiredFps = 200;//Gets or sets the desired FPS that the timer is operating at. 

            /*小怪物*/
            bugs = new CDXTile(cdxControl1.Screen, "bugs.bmp", 40, 36, 10, MemTypes.SystemOnly);
            bugs.ColorKey = Color.FromArgb(87, 87, 87);
            timer = new CDXTimer(20);
            gui = new CDXGui(cdxControl1.Screen);
            /*房子*/

            house = new CDXTile(cdxControl1.Screen, "build01_04.bmp", 160, 45, 0, MemTypes.SystemOnly);
            house.ColorKey = Color.FromArgb(255, 0, 255);
            house1 = new CDXTile(cdxControl1.Screen, "build01_04.bmp", 160, 45, 0, MemTypes.SystemOnly);
            house1.ColorKey = Color.FromArgb(255, 0, 255);
            /*玩家2*/

            Owl = new CDXTile(cdxControl1.Screen, "Owl.bmp", 40, 40, 8, MemTypes.SystemOnly);
            Owl.ColorKey = Color.FromArgb(255, 0, 255);
            /**/
            tree = new CDXTile(cdxControl1.Screen, "build06.bmp", 64, 56, 0, MemTypes.SystemOnly);
            tree.ColorKey = Color.FromArgb(87, 87, 87);
        }

        private void cdxControl1_DrawFrame(object sender, EventArgs e)
        {
            gui.Draw(cdxControl1.BackSurface, 0, 0);//代表着映射到图象表面的图解数据
            //  surface
            //x
            //X offset to begin drawing.
            //y
            //Y offset to begin drawing.

            cdxControl1.Screen.BackSurface.ColorFill(Color.Olive);

            player.Draw(cdxControl1.Screen.BackSurface, BltTypes.Trans);
            //surface
            //Destination surface.
            //bltType
            //One of the BltTypes to draw with.

            for (int i = 0; i < bugCollection.Count; i++)
                bugCollection[i].Draw(cdxControl1.BackSurface, spriteRect.Left, spriteRect.Top, BltTypes.Trans);
            for (int i = 0; i < bugCollection1.Count; i++)
                bugCollection1[i].Draw(cdxControl1.BackSurface, spriteRect.Left, spriteRect.Top, BltTypes.Trans);

            gui.Draw(cdxControl1.BackSurface, 0, 0);//代表着映射到图象表面的图解数据
        }

        private void cdxControl1_MoveFrame(object sender, EventArgs e)
        {
            //结合键盘控制来完成这个sprite程序
            if (timer.NextFrame())
            {
                input.Update();
                bool canDrawNextFrame = true;
                MoveSprites();
                if (input.KeyState(MCDX.Keys.UpArrow) == KeyStates.Press || input.KeyState(MCDX.Keys.UpArrow) == KeyStates.Repeat)
                {
                    player.TileNumber = -1;
                    player.PosY = player.PosY - 2;
                }
                else if (input.KeyState(MCDX.Keys.DownArrow) == KeyStates.Press || input.KeyState(MCDX.Keys.DownArrow) == KeyStates.Repeat)
                {

                    player.TileNumber = -2;
                    player.PosY += 2;
                }
                else if (input.KeyState(MCDX.Keys.LeftArrow) == KeyStates.Press || input.KeyState(MCDX.Keys.LeftArrow) == KeyStates.Repeat)
                {

                    player.TileNumber = -3;
                    player.PosX = player.PosX - 2;
                }
                else if (input.KeyState(MCDX.Keys.RightArrow) == KeyStates.Press || input.KeyState(MCDX.Keys.RightArrow) == KeyStates.Repeat)
                {

                    player.TileNumber = -4;
                    player.PosX += 2;
                }
                else
                {
                    player.Animation.SetNextFrame(0);
                    canDrawNextFrame = false;

                }
                //canDrawNextFrame是为了避免没有按键得情况下它还自动播放动画,不控制是不对的。
                if (canDrawNextFrame && player.Animation != null)
                {
                    player.NextFrame();
                    player.Animation.NextFrame();
                }

                if (player.PosX < 0)
                {
                    player.PosX = 0;
                }

                if (player.PosY < 0)
                {
                    player.PosY = 0;
                }

                if (player.PosX > cdxControl1.Screen.Width - playerTile.BlockWidth)
                {
                    player.PosX = cdxControl1.Screen.Width - playerTile.BlockWidth;
                }

                if (player.PosY > cdxControl1.Screen.Height - playerTile.BlockHeight)
                {
                    player.PosY = cdxControl1.Screen.Height - playerTile.BlockHeight;
                }

            }

        }
        private void AddSprite()
        {
            CDXSprite sprite;
            int[] anim;

            sprite = new CDXSprite(bugs, 0);//声明一个含有切割的一个精灵实例 这个精灵切割的数量
            sprite.PosX = 100;
            sprite.PosY = 100;
            sprite.VelX = 1;//速度
            sprite.VelY = 1;
            {  

                anim = new int[4] { 1, 2, 3, 2 };
                sprite.Animation = new CDXAnimation();
                sprite.Animation.AddAnimation(random.Next(5, 10), 0, false, anim);
                sprite.TileNumber = -1;//当前精灵所含有“Till”的数量
            }
            bugCollection.Add(sprite);




            CDXSprite sprite1;
            sprite1 = new CDXSprite(house, 0);//声明一个含有切割的一个精灵实例 这个精灵切割的数量
            sprite1.PosX = 70;
            sprite1.PosY = 0;
            {
                sprite1.Animation = new CDXAnimation();

                sprite1.TileNumber = -1;//当前精灵所含有“Till”的数量

            }
            bugCollection1.Add(sprite1);



            CDXSprite sprite2;
            sprite2 = new CDXSprite(house1, 0);//声明一个含有切割的一个精灵实例 这个精灵切割的数量
            sprite2.PosX = 170;
            sprite2.PosY = 380;
            {

                sprite2.Animation = new CDXAnimation();
                sprite2.TileNumber = -1;//当前精灵所含有“Till”的数量

            }
            bugCollection1.Add(sprite2);



            CDXSprite sprite3;
            sprite3 = new CDXSprite(Owl, 0);//声明一个含有切割的一个精灵实例 这个精灵切割的数量
            sprite3.PosX = 400;
            sprite3.PosY = 100;
            sprite3.VelX = random.Next(1, 2);//速度
            sprite3.VelY = random.Next(1, 2);
            { 

                anim = new int[8] { 0, 1, 2, 3, 4, 5, 6, 7 };
                sprite3.Animation = new CDXAnimation();
                sprite3.Animation.AddAnimation(random.Next(10, 20), 0, false, anim);
                sprite3.TileNumber = -1;//当前精灵所含有“Till”的数量
            }
            bugCollection.Add(sprite3);

            CDXSprite sprite4;
            sprite4 = new CDXSprite(tree, 0);//声明一个含有切割的一个精灵实例 这个精灵切割的数量
            sprite4.PosX = 400;
            sprite4.PosY = 300;

            sprite4.Animation = new CDXAnimation();
            sprite4.TileNumber = -1;//当前精灵所含有“Till”的数量

            bugCollection.Add(sprite4);




        }

        private void cdxControl1_Load(object sender, EventArgs e)
        {
            AddSprite();
        }

        private void MoveSprites()
        {
            foreach (CDXSprite sprite in bugCollection)
            {
                if (sprite.Animation != null)
                    sprite.Animation.NextFrame();//移动到动画区的下一祯

                sprite.NextFrame();


                if (sprite.PosX < 0)
                {
                    sprite.PosX = 0;
                    sprite.VelX *= -1;
                }

                if (sprite.PosY < 0)
                {
                    sprite.PosY = 0;
                    sprite.VelY *= -1;
                }

                if (sprite.PosX > spriteRect.Width - bugs.BlockWidth)
                {
                    sprite.PosX = spriteRect.Width - bugs.BlockWidth;
                    sprite.VelX *= -1;
                }

                if (sprite.PosY > spriteRect.Height - bugs.BlockHeight)
                {
                    sprite.PosY = spriteRect.Height - bugs.BlockHeight;
                    sprite.VelY *= -1;
                }

            }

        }

    }
}

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2010-11-14 10:25
wangnannan
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:87
帖 子:2545
专家分:9359
注 册:2007-11-3
得分:0 
主要代码就是上面那些 关键位置 洒家已经加上了注释 代码格式混乱 是上学时候写的 大家如有疑问 还可以参照英文的帮助文档 记得当时代码只做到这里就不做了主要是能力已经不行了  呵呵  这里附上游戏图片
游戏图片.rar (40.8 KB)
希望对大家有帮助

[ 本帖最后由 wangnannan 于 2010-11-14 10:34 编辑 ]

出来混,谁不都要拼命的嘛。 。拼不赢?那就看谁倒霉了。 。有机会也要看谁下手快,快的就能赢,慢。 。狗屎你都抢不到。 。还说什么拼命?
2010-11-14 10:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-325711-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.086460 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved