XNA超级玛丽

准备工作  在开始之前,你需要一些必备的开发工具:VS和XNA.以下是本文对应的开发环境VS2010Microsoft 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(@"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不管左移还是右移,身体都是朝右边的,往左移动时应该面朝左,这个不难处理,图片已经有了,有兴趣的可以自己试试。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值