分享我的XNA版超级玛丽(1)

  在前文(圆我一个游戏梦,XNA版超级玛丽)中提到本人最近因学习WP开发时,因需要学习XNA,遂产生了尝试开发一个小时候玩过无数遍的游戏"超级玛丽"的想法.

  这两天终于完成了游戏的雏形.从本文开始,我将一步步分享开发的历程.由于我没有系统的学习过游戏开发,所以文章中提到的内容也许并不是游戏开发正规的做法,但如果您从未接触过游戏开发,并对此感兴趣,我想我的文章还是能给你带来帮助的.


准备工作

  在开始之前,你需要一些必备的开发工具:VS和XNA.以下是本文对应的开发环境

  • VS2010
  • Microsoft XNA Game Studio 4.0

  VS相信大家都有,至于版本,以下是各个VS对应的XNA版本,如果你不是用的VS2010,那么你可以下载对应的XNA版本.

  •   XNA Game Studio 2.0(VS2005)
  •   XNA Game Studio 3.0(VS2008)
  •   XNA Game Studio 3.1(VS2008)
  •   XNA Game Studio 4.0(VS2010)

  下载连接就不贴了,谷哥一下就出来了,我是安装WP7.1时顺带给我装上的.


Hello Mario

  准备工作完成,可以正式开始我们的玛丽开发历程了.

  打开VS,新建一个项目,选择C#-XNA Game Studio 中的Windows Game(4.0)模板,项目名称为SuperMario,如下图,点确定

这时VS会为我们生成一个名为SuperMario的解决方案,解决方案下面有两个项目,一个是名为SuperMario的主项目,另一个是名为SuperMarioContent的资源项目.SuperMarioContent项目是专门用来存放一些游戏资源的,比如图片,声音,地图什么的.解决方案如下图

打开Game1.cs,这是我们的主游戏文件,类似于新建一个Winform项目时默认创建的Form1.cs,同样,它的加载由Program.cs完成.

我们看到,它有5个重写的方法,前面三个我们看名字也能猜到大概它们的功能.后面两个才是我们关注的重点.这里我简单介绍下,我想大家肯定知道,电影是怎么形成的:一张张静止的图片不断的切换造成视觉上动画.那么游戏其实是一样的,区别就在电影是已经拍好的图片一张张切换,而游戏则是根据玩家的控制,画出相应的静止图片,然后不停的切换,形成动画,也就是说游戏比电影多了一个画的步骤,所以玩游戏比看电影对电脑的配置要求高,因为做的事多了.Game1.cs中的Draw方法就是负责画画的.而Update则是根据玩家的输入和时间的流动更新游戏中的元素.当游戏运行时,Update和Draw方法会不停的轮流运行,即时你没有为游戏添加任何功能.比如你现在按F5运行时,你看到的是一张静止的蓝色背景窗口,但实际上Update和Draw方法会每秒执行60次.

  接下来让我们的玛丽出现在游戏画面中.在SuperMarioContent项目中添加一个文件夹,名称为Image,在该文件夹种"添加现有项",添加这张图片,这是mario的素材图片(有点小,大家凑和着用吧.实在找不到更好的了).在Game1.cs中输入如下代码

复制代码
 1         Texture2D _marioText;
 2         protected override void LoadContent()
 3         {
 4             spriteBatch = new SpriteBatch(GraphicsDevice);
 5 
 6             _marioText = this.Content.Load<Texture2D>(@"Image/mario");
 7         }
 8          protected override void Draw(GameTime gameTime)
 9         {
10             GraphicsDevice.Clear(Color.CornflowerBlue);
11             spriteBatch.Begin();
12             spriteBatch.Draw(_marioText, new Vector2(100, 100), new Rectangle(0, 0, 16, 16), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
13             spriteBatch.End();
14             base.Draw(gameTime);
15         }
复制代码

我们在LoadContent中载入了一张图片,然后在Draw方法中,绘制它,绘制的位置是坐标(x:100,y:100),XNA中默认的坐标原点是左上角.绘制时,并有没有绘制整个图片,而是一个小块,这个小块在图片中的位置是(x:0,y:0)长宽为16.按F5运行.Mario已经出现在游戏的画面中了...


跑吧 Mario

一动不动的Mario怎么去救公主呢,我们先来解决Mario跑步的问题.既然Mario能移动,说明他的位置是会变的,为它的位置申明一个变量,然后在Update方法中更新他的位置.代码现在如下

复制代码
        Texture2D _marioText;
        Vector2 _marioPosition = new Vector2(100, 100);
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            _marioPosition.X++;

            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.Draw(_marioText, _marioPosition, new Rectangle(0, 0, 16, 16), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            spriteBatch.End();
            base.Draw(gameTime);
        }
复制代码

按F5运行,怎么样,我们的Mario已经会"移动"了吧?不过现在的移动有点像鬼一样在飘,而且是自动的,不受我们的控制.我们先给他加上控制,一般游戏都是用"A" "D" 键来移动的,一个左移,一个右移.修改Update函数

复制代码
 1         protected override void Update(GameTime gameTime)
 2         {
 3             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
 4                 this.Exit();
 5             KeyboardState keyState = Keyboard.GetState();
 6             if (keyState.IsKeyDown(Keys.A))
 7             {
 8                 _marioPosition.X--;
 9             }
10             if (keyState.IsKeyDown(Keys.D))
11             {
12                 _marioPosition.X++;
13             }
14 
15             base.Update(gameTime);
16         }
复制代码

代码很好理解,我就不解释了....现在按F5运行,Mario已经成为我们能控制的游戏角色了.但Mario还是像鬼一样在飘,是时候让它的脚动起来了。刚才提到过,所谓的动画,就是不断地切换静态的图片,为了让我们的Mario动起来,我们让Mairo在移动的时候不停的切换mario.png图片中的第二个和第三个小玛丽图片。这里我们给图片的所有小图片的位置编号,从0开始,那么跑步应该用1号和2号图片。先看代码

复制代码
        int _frmStartIndex=0;
        int _frmEndIndex = 0;
        int _frmIndex = 0;//当前画的图块的索引
        int _frmChangeTime = 100;//多少毫秒换一次图片
        int _frmCurrentTime = 0;//距离上次换图片过了多少毫秒
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.A))
            {
                _marioPosition.X--;
                _frmStartIndex = 1;
                _frmEndIndex = 2;
            }
            if (keyState.IsKeyDown(Keys.D))
            {
                _marioPosition.X++;
                _frmStartIndex = 1;
                _frmEndIndex = 2;
            }
            if (keyState.GetPressedKeys().Count() == 0)
            {
                _frmStartIndex = 0;
                _frmEndIndex = 0;
            }

            _frmCurrentTime += gameTime.ElapsedGameTime.Milliseconds;
            if (_frmCurrentTime > _frmChangeTime)
            {
                _frmCurrentTime = 0;
                _frmIndex++;
                if (_frmIndex > _frmEndIndex)
                    _frmIndex = _frmStartIndex;
            }

            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.Draw(_marioText, _marioPosition, new Rectangle(_frmIndex * 16, 0, 16, 16), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
            spriteBatch.End();
            base.Draw(gameTime);
        }
复制代码

请注意Draw函数的第二个参数有一些小的更改,在Update函数中,我们通过判断按键情况选择画图时应该选择的图片块的区域,Mario不动时图片块的索引范围是0-0,移动时是1-2,并且定义了一个切换图片的间隔时间变量_frmChangeTime,在Update函数中不停的累积,当超过100毫秒时,换下一张图片。如果没有这个间隔时间变量,那么每次Update执行都会换图片,那我们的Mario跑起来会疯了一样手舞足蹈。按F5运行,Mario移动时会动了吧,我想一定有人会说“为什么只有手会动,脚不动”,这纯粹是因为我找不到玛丽移动时应该用哪些图,不用怀疑现在的代码,如果你能找到正确的图片,就能让Mario正确的手脚并用跑起来。

  处理加速  

  如果你玩过Mario这个游戏,你一定知道,Mario移动时是有个加速的过程的,而不是一按下跑步键就按固定的速度移动。其实这很容易解决,学过中学物理的我们都知道,加速移动嘛,不就是给个加速度然后运动的时候不停的增加速度。这里我们只要在游戏中通过物理知识模拟真实的运动情况就行了。看代码

复制代码
float _runAcceleration=0.01F;//跑步加速度
        float _runResistance = 0.005F;//...
        int MAXspeedR = 3;//右移最大速度
        int MAXspeedL = -3;//左移最大速度
        float _speed = 0;//当前速度
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            KeyboardState keyState = Keyboard.GetState();
            int frmTime=gameTime.ElapsedGameTime.Milliseconds;
            if (keyState.IsKeyDown(Keys.A))
            {
                _speed = _speed < MAXspeedL ? MAXspeedL : _speed - _runAcceleration * frmTime;
            }
            if (keyState.IsKeyDown(Keys.D))
            {
                _speed = _speed > MAXspeedR ? MAXspeedR : _speed + _runAcceleration * frmTime;
            }
            if (keyState.GetPressedKeys().Count() == 0)
            {
                if (_speed > 0)
                {
                    _speed -= _runResistance * frmTime;
                    if (_speed < 0)
                        _speed = 0;
                }
                if (_speed < 0)
                {
                    _speed += _runResistance * frmTime;
                    if (_speed >0)
                        _speed = 0;
                }
            }

            if (_speed == 0)
            {
                _frmStartIndex = 0;
                _frmEndIndex = 0;
            }
            else
            {
                _frmStartIndex = 1;
                _frmEndIndex = 2;
            }

            this._marioPosition.X += _speed;

            _frmCurrentTime += frmTime;
            if (_frmCurrentTime > _frmChangeTime)
            {
                _frmCurrentTime = 0;
                _frmIndex++;
                if (_frmIndex > _frmEndIndex)
                    _frmIndex = _frmStartIndex;
            }

            base.Update(gameTime);
        }

Update函数现在可以分为2部分,第一部分根据用户的键盘输入处理Mario速度,用时间乘以加速度得到速度,当用户不再按任何键时,处理减速。第二部分为根据Mario的速度来处理图片索引范围,现在当Mario的速度不为0时,显示跑步图片。这里this._marioPosition.X += _speed;何解呢?因为我们算出的速度是这一帧内的速度,可以理解为单位速度,距离等于速度乘以时间,时间为1,相当于距离等于速度。最后我们按F5运行,怎么样,此时的Mario已经有点感觉了吧。
  目前Mario不管左移还是右移,身体都是朝右边的,往左移动时应该面朝左,这个不难处理,图片已经有了,有兴趣的可以自己试试。


结束

第一篇就先介绍到这里,我们的超级玛丽还远远没有完成,剩下的以后慢慢来。希望对大家有帮助。

下雪天的写个伯克不容易,给个好评阿,亲.....

源码:http://files.cnblogs.com/xxfss2/SuperMario1.rar

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包含制作的说明档(readme.doc)以及一定会的执行档 一、 超级玛丽制作揭秘1工程开始 2 二、 超级玛丽制作揭秘2图片基类MYBITMAP 4 三、 超级玛丽制作揭秘3游戏背景 类MYBKSKY 7 四、 超级玛丽制作揭秘4图片显示 类MYANIOBJ 9 五、 超级玛丽制作揭秘5魔法攻击 类MYANIMAGIC 13 六、 超级玛丽制作揭秘6时钟控制 类MYCLOCK 14 七、 超级玛丽制作揭秘7字体管理 类MYFONT 19 八、 超级玛丽制作揭秘8跟踪打印 类FILEREPORT 22 九、 超级玛丽制作揭秘9精灵结构struct ROLE 24 十、 超级玛丽制作揭秘10子弹的显示和帧的刷新 26 十一、 超级玛丽制作揭秘11子弹运和打怪 27 十二、 超级玛丽制作揭秘12旋风攻击,小怪运,火圈 29 十三、 超级玛丽制作揭秘13小怪和火圈,模板 34 十四、 超级玛丽制作揭秘14爆炸效果,金币 37 十五、 超级玛丽制作揭秘15金币提示,攻击提示 41 十六、 超级玛丽制作揭秘16攻击方式切换 43 十七、 超级玛丽制作揭秘17地图物品 44 十八、 超级玛丽制作揭秘18背景物品 47 十九、 超级玛丽制作揭秘19视图 48 二十、 超级玛丽制作揭秘20地图切换 50 二十一、 超级玛丽制作揭秘21游戏数据管理 53 二十二、 超级玛丽制作揭秘22玩家角色类MYROLE 58 二十三、 超级玛丽制作揭秘23玩家作控制 63 二十四、 超级玛丽制作揭秘24角色画 69 二十五、 超级玛丽制作揭秘25类GAMEMAP 全局变量 72 二十六、 超级玛丽制作揭秘26菜单控制 窗口缩放 76 二十七、 超级玛丽制作揭秘27程序框架WinProc 80 二十八、 InitInstance函数说明 85 二十九、 后记 87 以下的资源也很不错, 加减可以看一下o 使用C++制作3D画人物-100%提供源码 http://download.csdn.net/source/2255453 Linux kernel 每一行都完全注释-初学者必备 http://download.csdn.net/source/1982431 Programming Embedded Systems 2nd http://download.csdn.net/source/1982338 J2ME pdf and code 郭克华 http://download.csdn.net/source/2229809 C语言程序设计(Visual+C 6.0环境) http://download.csdn.net/source/2232878 Visual C++ 60 MFC + code 学习最强宝典 http://download.csdn.net/source/2236266 ASP.NET Web (第一次亲密接触ASP.NET) http://download.csdn.net/source/2241466 http://hqioan.download.csdn.net/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值