zoukankan      html  css  js  c++  java
  • 使用 Item,ItemManager 在 XNA 中创建物品和道具(十六)

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

    物品

    玩家可以在游戏中获得各种物品,这样我们创建了一个新的类,用来表示物品。Item 类继承自 Spirit 类,他的很多内容和 Bullet 是类似的。

    internal abstract class Item
        : Spirit
    {
    
        private readonly bool isAutoPick;
    
        protected Item ( IPlayScene scene, int type, Vector2 location, string movieName, float speed, int angle, HitArea hitArea, int width, int height, double destroySecond, bool isAreaLimited, bool isAreaEntered, double areaSecond, bool isAutoPick )
            : base ( scene, type, location, movieName,
            null,
            speed, angle, hitArea, width, height, destroySecond,
            false,
            isAreaLimited, isAreaEntered, areaSecond )
        {
            this.isAutoPick = isAutoPick;
    
            this.isMoving = true;
        }
    
        protected override void move ( )
        {
            this.Location.X += this.xSpeed;
            this.Location.Y += this.ySpeed;
        }
    
        protected override Vector2 getMovieLocation ( )
        { return this.Location - this.halfSize; }
    
        protected override void updateSpeed ( )
        {
            this.xSpeed = Calculator.Cos ( this.angle ) * this.speed;
            this.ySpeed = Calculator.Sin ( this.angle ) * this.speed;
    
            base.updateSpeed ( );
        }
    
    }

    字段 isAutoPick 用来表示物品是否可以被自动拾取,不过目前并没有实现这个效果。方法 updateSpeed 用来根据字段 speed 来计算出 xSpeed 和 ySpeed。

    至于其他的成员,大家可以参照 Bullet 类的解释。

    物品管理器

    ItemManager 类派生自类 SpiritManager<T>,默认的绘制顺序是 -1000。

    事件 Picked 用来通知外界,物品已经被拾起,这时外界可以完成各种工作,比如:让玩家的生命值增加。

    至于其他的成员,大家可以参照 BulletManager 类的解释。

    internal class ItemManager
        : SpiritManager<Item>
    {
        internal event EventHandler<HitAreaEventArgs> HitTesting;
        internal event EventHandler<SpiritEventArgs> Picked;
    
        internal ItemManager ( )
            : this ( -1000 )
        { }
        internal ItemManager ( int defaultOrder )
            : base ( defaultOrder )
        { }
    
        internal override void Update ( GameTime time )
        {
    
            if ( null == this.HitTesting )
                return;
    
            foreach ( Item item in this.Spirits.ToArray ( ) )
                if ( null != item.HitArea )
                {
                    HitAreaEventArgs hitAreaArg = new HitAreaEventArgs ( item.Type, item.HitArea );
                    this.HitTesting ( item, hitAreaArg );
    
                    if ( hitAreaArg.IsHit )
                    {
    
                        if ( null != this.Picked )
                            this.Picked ( item, new SpiritEventArgs ( item ) );
    
                        item.Destroy ( );
                    }
    
                }
    
        }
    
    }

    示例

    场景 SceneT17 是 SceneT16 的扩展,在 SceneT16 中,我们让子弹击中了小鸟,而在 SceneT17 中,我们还会创建物品,这些物品可以增加小鸟的生命值。

    首先,我们修改了 Bird 类的 life 字段,将他给为可以被外界访问的。

    internal class Bird
        : Spirit, IAssailable
    {
        internal int Life = 10;
        
        // ...
    }

    然后,我们定义了 MyItem 类,他就是新的物品,可以增加小鸟的生命值。

    internal class MyItem
        : Item
    {
    
        internal MyItem ( IPlayScene scene, Vector2 location, int angle )
            : base ( scene, 1, location, "myitem", 5, angle,
            new SingleRectangleHitArea ( new Rectangle ( -15, -15, 30, 30 ) ),
            30, 30,
            0,
            true,
            true,
            0,
            true
            )
        { }
    
    }

    我们创建了新的 ItemManager,并设置了他的 HitTesting 和 Picked 事件。

    在 itemHitTesting 方法中,我们将测试物品是否和小鸟发生了碰撞。在 itemPicked 方法中,我们为小鸟增加了生命值。

    internal sealed class SceneT17
        : CommandScene, IPlayScene
    {
        // ...
        
        private ItemManager itemManager;
        
        internal SceneT17 ( )
            : base ( Vector2.Zero, GestureType.None, "background1",
            new Resource[] {
                new Resource ( "bird2.image", ResourceType.Image, @"imageird2" ),
                new Resource ( "bullet.image", ResourceType.Image, @"imageullet" ),
                new Resource ( "item.image", ResourceType.Image, @"imageitem" ),
                new Resource ( "go.image", ResourceType.Image, @"imageutton1" ),
            },
            new Making[] {
                new Movie ( "bird", "bird2.image", 80, 80, 5, "live",
                    new MovieSequence ( "live", true, new Point ( 1, 1 ), new Point ( 2, 1 ) )
                    ),
                new Movie ( "mybutton", "bullet.image", 10, 10, 0, "b",
                    new MovieSequence ( "b", new Point ( 1, 1 ) )
                    ),
                new Movie ( "myitem", "item.image", 30, 30, 0, "i",
                    new MovieSequence ( "i", new Point ( 1, 1 ) )
                    ),
                new Button ( "b.go", "go.image", "GO", new Vector2 ( 10, 690 ), 100, 50, new Point ( 1, 1 ) ),
            }
            )
        {
            // ...
            
            this.itemManager = new ItemManager ( );
            this.itemManager.Scene = this;
            this.itemManager.HitTesting += this.itemHitTesting;
            this.itemManager.Picked += this.itemPicked;
            
            // ...
        }
    
        private void itemHitTesting ( object sender, HitAreaEventArgs e )
        {
    
            if ( !this.bird.IsDied && e.HitArea.HitTest ( this.bird.HitArea ) )
                e.IsHit = true;
    
        }
    
        private void itemPicked ( object sender, SpiritEventArgs e )
        {
            this.bird.Life++;
            Debug.WriteLine ( "item picked, life={0}", this.bird.Life );
        }
        
        // ...
    }

    最后,在点击按钮时,我们创建了物品。

    private void goButtonSelected ( object sender, ButtonEventArgs e )
    {
        this.bulletManager.Append ( new MyBullet ( this, new Vector2 ( 10, 10 ), 45 ) );
        this.itemManager.Append ( new MyItem ( this, new Vector2 ( 420, 30 ), 135 ) );
    }

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

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

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

    QQ 群 213685539

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



  • 相关阅读:
    海量数据拆分到nosql系统的一种方案
    软件架构师应该知道的97件事
    【转载】实现软件架构质量属性的战术
    让技术人员看得懂的流程
    【转载】一步步构建大型网站架构
    [转载]从100PV到1亿级PV网站架构演变
    添加和删除hadoop集群中的节点
    windows下JDK环境配置
    如何部署hadoop集群
    android9.0适配HTTPS:not permitted by network security policy'
  • 原文地址:https://www.cnblogs.com/zoyobar/p/wpxna16.html
Copyright © 2011-2022 走看看