平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛。在这里分享一下经验,仅为了和各位朋友交流经验。平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXNA 吧,最后请高手绕道而行吧,以免浪费时间。(为了突出重点和减少篇幅,有些示例代码可能不够严谨。)

按钮

在游戏当中,我们可能需要创建一些图形按钮,平方创建了 Button 类来完成这个任务。

首先,我们需要在按钮中定义了一个 Movie,使用这个 Movie 来控制图形,他可以播放按钮各种状态时的动画。

protected readonly Movie backgroundMovie;protected string upMovieSequenceName = "up";
protected string downMovieSequenceName = "down";
protected string disableMovieSequenceName = "disable";internal Button ( string name, string resourceName, string command, Vector2 location, int width, int height, bool isSole, Point upFrameIndex, Point downFrameIndex, Point disableFrameIndex, params MovieSequence[] movieSequences ): base ( name, resourceName )
{// ...
List<MovieSequence> sequences = new List<MovieSequence> ( );sequences.Add ( new MovieSequence ( this.upMovieSequenceName, upFrameIndex ) );sequences.Add ( new MovieSequence ( this.downMovieSequenceName, downFrameIndex ) );sequences.Add ( new MovieSequence ( this.disableMovieSequenceName, disableFrameIndex ) );if ( null != movieSequences && movieSequences.Length != 0 )sequences.AddRange ( movieSequences );this.backgroundMovie = new Movie ( "background", resourceName, location, width, height, 0, 1f, this.upMovieSequenceName,sequences.ToArray ( ));// ...
}internal override void Init ( Scene scene )
{base.Init ( scene );this.backgroundMovie.Init ( scene );
}internal override void InitResource ( ResourceManager resourceManager )
{base.InitResource ( resourceManager );this.backgroundMovie.InitResource ( resourceManager );
}public override void Dispose ( )
{this.backgroundMovie.Dispose ( );base.Dispose ( );
}

在构造函数中,参数 resourceName 表示按钮图形的资源名称,字段 backgroundMovie 是控制按钮背景的电影,默认电影序列的名称为 up,down,disable,分别对应了按钮松开,按钮按下,按钮不可用。

你可以指定不同电影序列对应的帧,也可以使用默认的值。默认情况下,up 右边的是 down,down 右边是 disable,就像下面的图形:

由于 backgroundMovie 是被 Button 创建的,所以 backgroundMovie 需要被 Button 管理。在方法 Init,InitResource 中,我们会初始化 backgroundMovie,在方法 Dispose 中,我们销毁了 backgroundMovie。

internal event EventHandler<ButtonEventArgs> Pressing;
internal event EventHandler<ButtonEventArgs> Pressed;internal static void Press ( Button button )
{button.IsPressing = true;button.press ( );if ( null != button.Pressing )button.Pressing ( button, new ButtonEventArgs ( button.command ) );}internal static void Unpress ( Button button )
{if ( !button.IsPressing )return;button.IsPressing = false;button.unpress ( );if ( null != button.Pressed )button.Pressed ( button, new ButtonEventArgs ( button.command ) );}internal static bool PressTest ( Button button, IList<Motion> motions )
{if ( !button.isEnabled || !button.isVisible )return false;foreach ( Motion motion in motions )if ( motion.Type == MotionType.Down || motion.Type == MotionType.Press ){Point location = new Point ( ( int ) motion.Position.X, ( int ) motion.Position.Y );if ( button.bound.Contains ( location ) ){Press ( button );return true;}}Unpress ( button );return false;
}

方法 Press 将使按钮进入按下状态,并触发 Pressing 事件。方法 Unpress 将使按钮离开按下状态,并触发 Pressed 事件。你并不需要直接调用上面的两个方法,而只需要调用 PressTest,这个方法将检测某一个按钮的按下状态。

internal event EventHandler<ButtonEventArgs> Selected;internal static void Select ( Button button )
{if ( !button.isEnabled )return;button.select ( );if ( null != button.Selected )button.Selected ( button, new ButtonEventArgs ( button.command ) );}internal static bool ClickTest ( Button button, IList<Motion> motions )
{if ( !button.isEnabled || !button.isVisible )return false;foreach ( Motion motion in motions )if ( motion.Type == MotionType.Up ){Point location = new Point ( ( int ) motion.Position.X, ( int ) motion.Position.Y );if ( button.bound.Contains ( location ) ){Select ( button );return true;}}return false;
}

方法 Select 和 Press 方法类似,并可以通过方法 ClickTest 来测试用户是否选择了按钮。

protected virtual void select ( )
{ this.scene.AudioManager.PlaySound ( "click.s" ); }protected virtual void press ( )
{if ( this.backgroundMovie.CurrentSequenceName != this.downMovieSequenceName )Movie.Play ( this.backgroundMovie, this.downMovieSequenceName );}protected virtual void unpress ( )
{if ( this.backgroundMovie.CurrentSequenceName != this.upMovieSequenceName )Movie.Play ( this.backgroundMovie, this.upMovieSequenceName );}internal virtual void Draw ( SpriteBatch batch )
{if ( !this.isVisible )return;Movie.Draw ( this.backgroundMovie, null, batch );
}

Button 的 select 方法中将播放资源名称为 click.s 的声音,press 和 unpress 方法中将播放相关的动画。派生类可以修改这些方法来执行自己的操作。在 Draw 方法中,我们将绘制按钮。

protected string command;internal bool IsPressing = false;private bool isEnabled = true;
internal virtual bool IsEnabled
{get { return this.isEnabled; }set{Movie.Play ( this.backgroundMovie, value ? this.upMovieSequenceName : this.disableMovieSequenceName );this.isEnabled = value;}
}protected Vector2 location;
public virtual Vector2 Location
{get { return this.location; }set {this.location = value;this.backgroundMovie.Location = value;this.bound = new Rectangle (( int ) ( value.X ),( int ) ( value.Y ),this.Width,this.Height);}
}internal override bool IsVisible
{set{base.IsVisible = value;this.backgroundMovie.IsVisible = value;}
}

字段 command 表示按钮的命令,字段 IsPressing 表示的按钮是否被按下,属性 IsEnabled 表示按钮是否可用,属性 Location 表示按钮的位置,属性 IsVisible 表示按钮是否可见。

一个例子

internal sealed class SceneT10: Scene
{private readonly Button buttonPlay;internal SceneT10 ( ): base ( Vector2.Zero, GestureType.None,new Resource[] {new Resource ( "play.image", ResourceType.Image, @"image\button1" ),new Resource ( "click.s", ResourceType.Sound, @"sound\click" ),},new Making[] {new Button ( "b.play", "play.image", "PLAY", new Vector2 ( 100, 100 ), 100, 50, new Point ( 1, 1 ) )}){this.buttonPlay = this.makings[ "b.play" ] as Button;//this.buttonPlay.IsEnabled = false;this.buttonPlay.Pressing += this.buttonPlayPressing;this.buttonPlay.Pressed += this.buttonPlayPressed;}protected override void inputing ( Controller controller ){base.inputing ( controller );Button.PressTest ( this.buttonPlay, controller.Motions );}protected override void drawing ( GameTime time, SpriteBatch batch ){base.drawing ( time, batch );this.buttonPlay.Draw ( batch );}private void buttonPlayPressing ( object sender, ButtonEventArgs e ){ Debug.WriteLine ( "play button pressing" ); }private void buttonPlayPressed ( object sender, ButtonEventArgs e ){ Debug.WriteLine ( "play button pressed" ); }public override void Dispose ( ){this.buttonPlay.Pressing -= this.buttonPlayPressing;this.buttonPlay.Pressed -= this.buttonPlayPressed;base.Dispose ( );}}

在场景 SceneT10 中,我们载入按钮所需要的资源,包括:图像,声音。并定义一个按钮。

在场景 SceneT10 的 inputing 方法中,我们使用 Button 的 PressTest 方法测试用户是否按下了按钮。

在构造函数中,我们会 Button 设置了事件 Pressing 和 Pressed,在 buttonPlayPressing 和 buttonPlayPressed 方法中,我们打印了一些文字。

protected override void OnNavigatedTo ( NavigationEventArgs e )
{// ...this.appendScene ( new mygame.test.SceneT10 ( ), null, false );// ...
}

最后,我们在 World 的 OnNavigatedTo 方法中,使用 appendScene 方法添加了场景 SceneT10。

本期视频 http://v.youku.com/v_show/id_XNTc0MDY3ODQw.html
项目地址 http://wp-xna.googlecode.com/

更多内容 WPXNA
平方开发的游戏 http://zoyobar.lofter.com/
QQ 群 213685539

欢迎访问我在其他位置发布的同一文章:http://www.wpgame.info/post/decc4_6eacd9

转载于:https://www.cnblogs.com/zoyobar/p/wpxna9.html

使用 Button 类在 XNA 中创建图形按钮(九)相关推荐

  1. 使用 CommandScene 类在 XNA 中创建命令场景(十二)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  2. 编写Java程序,使用ThreadLocal类,项目中创建账户类 Account,类中包括账户名称name、 ThreadLocal 类的引用变量amount,表示存款

    查看本章节 查看作业目录 需求说明: 某用户共有两张银行卡,账户名称相同,但卡号和余额不同.模拟用户使用这两张银行卡进行消费的过程,并打印出消费明细 实现思路: 项目中创建账户类 Account,类中 ...

  3. 声明银行账户类 java_编写Java程序,使用ThreadLocal类,项目中创建账户类 Account,类中包括账户名称name、 ThreadLocal 类的引用变量amount,表示存款...

    查看本章节 查看作业目录 需求说明: 某用户共有两张银行卡,账户名称相同,但卡号和余额不同.模拟用户使用这两张银行卡进行消费的过程,并打印出消费明细 实现思路: 项目中创建账户类 Account,类中 ...

  4. java实现按钮名字自定义_在Java中创建自定义按钮

    当我第一次学习Java时,我们必须使Yahtzee,我认为创建自定义的Swing组件和容器,而不是只是绘制一切在一个JPanel是很酷.扩展Swing组件的好处当然是能够添加对键盘快捷方式和其他辅助功 ...

  5. 使用 Item,ItemManager 在 XNA 中创建物品和道具(十六)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  6. 使用 Label 类在 XNA 中显示文本,WPXNA(七)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  7. VBA在EXCEL中创建图形线条

    EXCEL使用了多少行: ActiveSheet.UsedRange.Rows.Count(再也不用循环到头啦) 创建线条并命名:ActiveSheet.Shapes.AddLine(x1,y1,x2 ...

  8. unity编辑器扩展_01(在工具栏中创建一个按钮)

    代码: [MenuItem("Tools/Test",false,1)]     static void Test()     {         Debug.Log(" ...

  9. C#中创建圆形/按钮(使用重绘)

    创建圆形按钮挺简单的. public class EllipseButton : Button { protected override void OnPaint(PaintEventArgs pev ...

最新文章

  1. golang 系统调用 syscall 简介
  2. python如何调用图片-用python简单处理图片(4):图像中的像素访问
  3. ZOJ 1970 All in All
  4. 从web移动端布局到react native布局
  5. SecureCRT中的实用配置
  6. 最完美的xslt数值函数与字符串函数
  7. 华为机试HJ52:计算字符串的距离(动态规划)
  8. java下载m3u8视频,解密并合并ts(一)
  9. 吴怀宇 第三版 自动控制原理课后习题答案 武汉科技大学814
  10. 编程珠玑第一章-位图压缩存储
  11. 如何高效率学习PMP?
  12. 最实用windows 下python+numpy安装(转载)
  13. 人事管理系统:若依框架集成activiti工作流自动审批
  14. 商标注册后的注意事项
  15. draw.io怎么安装在linux,Draw.io安装
  16. 魔百和CM201-1-YS易视腾代工-免拆机-线刷固件包
  17. CHM 已取消到该网页的导航
  18. carte集群的搭建笔记
  19. 今日头条还可以引流么?今日头条引流效果怎么样?
  20. 类似Confluence的软件有哪些

热门文章

  1. 开发购物车应用程序(1)
  2. zookeeper+kafka集群部署+storm集群
  3. 使用WINS服务器实现跨网段名称注册解析和释放
  4. Visual studio 2010出现“error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”解决方式...
  5. NDK 高级编程(笔记)
  6. WebSocket API简介
  7. 浅谈C中的指针和数组(一)
  8. 转贴:cg(c for graphic)编程语言
  9. iOS 发大招 otherButtonTitles:(nullable NSString *)otherButtonTitles, ... 写法 编写通用类的时候关于可变参数的处理...
  10. 黑白青春-纪念那年我的秋天