博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 Button 类在 XNA 中创建图形按钮(九)
阅读量:6830 次
发布时间:2019-06-26

本文共 7834 字,大约阅读时间需要 26 分钟。

平方已经开发了一些 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
sequences = new List
( ); 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
Pressing;internal event EventHandler
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
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
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
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。

本期视频

项目地址
更多内容
平方开发的游戏
QQ 群 213685539

欢迎访问我在其他位置发布的同一文章:

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

你可能感兴趣的文章
AngularJS - Apply方法监听model变化
查看>>
linux_密钥
查看>>
silverlight 添加配置项
查看>>
oracle数据库迁移相关
查看>>
Linux之 VIM 编辑器
查看>>
实用网址集合
查看>>
【转】移动web资源整理
查看>>
【Linux】CentOS7下安装JDK详细过程
查看>>
python基础之socket编程3:粘包
查看>>
(转)Hibernate 的应用(Hibernate 的结构)?
查看>>
Ubuntu terminator 多窗口终端的快捷键
查看>>
Add Binary leetcode
查看>>
关于pycharm中缩进、粘贴复制等文本编辑功能部分失效的解决办法
查看>>
[20190524]浅谈模糊查询.txt
查看>>
Swift 构造与析构
查看>>
Java基础学习总结--Java对象的序列化和反序列化
查看>>
关于application/x-www-form-urlencoded等字符编码的解释说明
查看>>
svn项目冲突时显示无法加载项目的解决方法
查看>>
node论坛练手
查看>>
将object强制转换成int效率测试
查看>>