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


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

    CommandScene

    CommandScene 类继承自 Scene 类,在这个场景中,我们将控制按钮并检测按钮的点击情况,而且可以将这些情况传递给外界。

    internal event EventHandler<SceneEventArgs> Executing;
    
    private readonly Shape backgroundShape;
    
    protected readonly List<Button> buttons = new List<Button> ( );
    private readonly List<Anime> animes = new List<Anime> ( );

    事件 Executing 将通知外界哪些按钮被点击了,字段 buttons 表示被 CommandScene 控制的所有按钮。

    字段 backgroundShape 表示场景的背景图片,字段 animes 表示场景中的动画。

    场景 CommandScene 将包含一些资源,包括:字体,背景图片,按钮点击的声音。

    internal CommandScene ( Vector2 location, GestureType gestureType, string backgroundResourcePath, IList<Resource> resources, IList<Making> makings, bool isBroken )
        : base ( location, gestureType,
        ResourceManager.Combine ( new Resource[] {
            new Resource ( "peg", ResourceType.Font, @"fontpeg" ),
            new Resource ( "background", ResourceType.Image, string.Format ( @"image{0}", backgroundResourcePath ) ),
            new Resource ( "click.s", ResourceType.Sound, @"soundclick" ),
        }, resources ),
        combine ( new Making[] {
            new Shape ( "background.s", "background" )
        }, makings ),
        isBroken
        )
    {
        this.backgroundShape = this.makings["background.s"] as Shape;
    
        foreach ( Making making in this.makings.Values )
            if ( making is Button )
            {
                Button button = making as Button;
                button.Selected += this.buttonSelected;
                this.buttons.Add ( button );
            }
            else if ( making is Anime )
                this.animes.Add ( making as Anime );
    
    }
    
    public override void Dispose ( )
    {
    
        foreach ( Button button in this.buttons )
            button.Selected -= this.buttonSelected;
    
        this.buttons.Clear ( );
        this.animes.Clear ( );
    
        base.Dispose ( );
    }

    在构造函数中,我们从元件中获取所有的 Button 对象,并设置他们的 Selected 事件。而在 Dispose 方法中,我们做了相反的操作。

    private void buttonSelected ( object sender, ButtonEventArgs e )
    { this.Execute ( e.Command ); }
    
    internal void Execute ( string command )
    {
    
        if ( null != this.Executing )
            this.Executing ( this, new SceneEventArgs ( command ) );
    
    }

    每一个按钮的 Selected 事件都将执行 buttonSelected 方法,在该方法中,我们将调用 Execute 方法。

    在方法 Execute 中,我们将触发 CommandScene 的 Executing 事件,参数 command 和按钮的 command 字段相同,这样外界就可以知道是哪个按钮被点击了。如果按钮的 IsSole 字段为 true,则只有一个按钮的点击是有效的。

    protected override void inputing ( Controller controller )
    {
    
        foreach ( Button button in this.buttons )
            Button.PressTest ( button, controller.Motions );
    
        foreach ( Button button in this.buttons )
            if ( Button.ClickTest ( button, controller.Motions ) && button.IsSole )
                break;
    
    }

    在 inputing 方法中,我们同时调用了 Button 的 PressTest 和 ClickTest 方法,这样可以检测按钮的按下和点击情况。但 PressTest 是给以后的场景使用的,这里我们用的是 ClickTest,他将检测按钮的点击情况并触发 Button 的 Selected。

    protected override void drawing ( GameTime time, SpriteBatch batch )
    {
        Shape.Draw ( this.backgroundShape, time, batch );
    
        foreach ( Anime anime in this.animes )
            Anime.Draw ( anime, time, batch );
    
        foreach ( Button button in this.buttons )
            button.Draw ( batch );
    
    }
    
    protected override void updating ( GameTime time )
    {
    
        foreach ( Anime anime in this.animes )
            anime.Update ( time );
    
    }

    在 drawing 方法中,我们将绘制按钮和动画以及场景的背景图片。在 updating 方法中,我们将更新场景中的小动画,比如:一只小鸟。

    示例

    SceneT13 是一个简单的场景,我们将包含两个按钮。

    internal sealed class SceneT13
        : CommandScene
    {
    
        internal SceneT13 ( )
            : base ( Vector2.Zero, GestureType.None, "background1",
            new Resource[] {
                new Resource ( "play.image", ResourceType.Image, @"imageutton1" ),
                new Resource ( "stop.image", ResourceType.Image, @"imageutton2" ),
            },
            new Making[] {
                new Button ( "b.play", "play.image", "PLAY", new Vector2 ( 100, 100 ), 100, 50, new Point ( 1, 1 ) ),
                new Button ( "s.play", "stop.image", "STOP", new Vector2 ( 100, 300 ), 100, 50, new Point ( 1, 1 ) )
            }
            )
        { }
    
    }

    在方法 OnNavigatedTo 中,我们将通过 appendScene 方法添加场景 SceneT13。

    protected override void OnNavigatedTo ( NavigationEventArgs e )
    {
        // ...
    
        this.appendScene ( new Scene[] { new mygame.test.SceneT13 ( ) } );
    
        base.OnNavigatedTo ( e );
    }

    我们稍微的修改了 appendScene 和 RemoveScene 方法,让他们调用了 sceneAppending 和 sceneRemoving。这样,我们可以通过修改 sceneAppending 和 sceneRemoving 来完成一些工作。

    private void appendScene ( Scene scene, Type afterSceneType, bool isInitialized )
    {
    
        if ( null == scene )
            return;
    
        this.sceneAppending ( scene );
    
        // ...
    }
    
    internal void RemoveScene ( Scene scene )
    {
    
        if ( null == scene || !this.scenes.Contains ( scene ) )
            return;
    
        this.sceneRemoving ( scene );
        
        // ...
    }

    在 sceneAppending 方法中,我们设置了场景 SceneT13 的 Executing 事件。在 sceneRemoving 方法中,我们注销了 Executing 事件。

    private void sceneAppending ( Scene scene )
    {
    
        if ( scene is mygame.test.SceneT13 )
            ( scene as mygame.test.SceneT13 ).Executing += this.sceneT13Executing;
    
    }
    
    private void sceneRemoving ( Scene scene )
    {
    
        if ( scene is mygame.test.SceneT13 )
            ( scene as mygame.test.SceneT13 ).Executing -= this.sceneT13Executing;
    
    }

    在方法 sceneT13Executing 中,我们打印了参数 e 的 Command 字段,他表示被点击按钮的 command。

    private void sceneT13Executing ( object sender, SceneEventArgs e )
    {
        Debug.WriteLine ( "SceneT13: " + e.Command );
    }

    本期视频 http://v.youku.com/v_show/id_XNTc4NDAwMDEy.html

    项目地址 http://wp-xna.googlecode.com/
    更多内容 WPXNA

    平方开发的游戏 http://zoyobar.lofter.com/

    QQ 群 213685539

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

  • 相关阅读:
    vue系列【element ui table中render函数加if的使用】
    vue系列【watch的使用方法及immdiate、deep解决组件传值中数据改变视图不更新等常见问题】
    vue系列【element ui 处理图片流及实现多张图片轮播】
    webpack系列【webpack的基本使用及配置项】
    vue系列【element ui 行内三元表达式的使用及实现行内switch按钮加文字】
    vue系列【vue路由$route.go(1)返回使用KeepAlive保持原页面数据不更新】
    vue系列【post 和 get 请求书写及使用】
    vue系列【vue+element 三元表达式多条件实现功能】
    vue系列【sessionStorage的setItem和getItem使用】
    vue系列【vue swiper插件实现图片轮播效果】
  • 原文地址:https://www.cnblogs.com/zoyobar/p/wpxna12.html
Copyright © 2020-2023  润新知