zoukankan      html  css  js  c++  java
  • XNA游戏:Bizzy Bees蜜蜂警官游戏

    先来看一下游戏的界面

    done

    游戏的思路差不多像俄罗斯方块一样,上面的花一直往下掉,然后你就需要选中一只蜜蜂来吃上面的花,当蜜蜂的颜色和花的颜色一样或者花是彩色的花的时候,花就会被蜜蜂给吃掉,这时候这只蜜蜂也会被随机生成一只新的蜜蜂。当吃掉一朵彩色的花的时候,会增加一分,当花落到了底下的时候游戏结束。

    看一下下面的代码:

    花的对象

    Flower.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DemoGame
    {
        class Flower
        {
            public int Color;//颜色
            public float X;//X轴坐标
            public float Y;//Y轴坐标
    
            public Flower(int color, float x, float y)
            {
                this.Color = color;
                this.X = x;
                this.Y = y;
            }
        }
    }

    花的列容器

    Column.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    
    namespace DemoGame
    {
        class Column
        {
            const int columnTop = 150;//列头高度,当花移动出这个高度后将开始新增新花
            const int numberOfFlowerColors = 6;//花颜色的数量
            const int rainbowFlowerColor = 6; //彩虹花的颜色
            const int flowerDeltaY = 80;
            const int flowerWidth = 72;//花的宽度
            const int flowerHeight = 72;//花的高度
            const int columnBottom = 620;//列的高度 用来判断花是否移动到底了
    
            private List<Flower> flowers = null;//花的集合
            private SpriteBatch spriteBatch;//绘制花
            private float x;//花的X轴,X轴的坐标是固定的
            private Random r;
            private Texture2D flowerMap;//花的纹理
    
            public float Velocity = 0.4f;//速度
            /// <summary>
            /// 判断是否有花移动到底
            /// </summary>
            public bool ReachedBottom
            {
                get
                {
                    if (flowers.Count != 0 && flowers[0].Y >= columnBottom)
                        return true;
                    else
                        return false;
                }
            }
            /// <summary>
            /// 初始化一列
            /// </summary>
            /// <param name="content">当前的ContentManager</param>
            /// <param name="spriteBatch">当前的SpriteBatch</param>
            /// <param name="x"></param>
            /// <param name="seed"></param>
            public Column(ContentManager content, SpriteBatch spriteBatch, float x, int seed)
            {
                this.spriteBatch = spriteBatch;
                this.x = x;
                this.flowers = new List<Flower>();
                this.r = new Random(seed);
                this.flowerMap = content.Load<Texture2D>("flowermap");
    
                //初始化 添加3朵花
                AddRandomFlower(x, columnTop + 2 * flowerDeltaY);
                AddRandomFlower(x, columnTop + flowerDeltaY);
                AddRandomFlower(x, columnTop);
            }
            /// <summary>
            /// 随机添加一朵花
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            private void AddRandomFlower(float x, int y)
            {
                int color = r.Next(numberOfFlowerColors+1);
                flowers.Add(new Flower(color, x, y));
            }
            /// <summary>
            /// 在spriteBatch中绘制花精灵
            /// </summary>
            public void Draw()
            {
                foreach (Flower flower in flowers)
                {
                    spriteBatch.Draw(flowerMap, new Vector2(flower.X, flower.Y), new Rectangle(flower.Color * flowerWidth, 0, flowerWidth, flowerHeight), Color.White);
                }
            }
            /// <summary>
            /// 更新列
            /// </summary>
            public void Update()
            {
                foreach (Flower f in flowers)
                {
                    f.Y += Velocity;//增加Y轴的偏移量,表示正在向下移动
                }
                //如果最上面的花已经全部离开顶部,则需要随机生成新的花从上面下来
                if (flowers.Count == 0 || flowers[flowers.Count - 1].Y > columnTop)
                    AddRandomFlower(x, columnTop - flowerDeltaY);
            }
            /// <summary>
            /// 获取最底下的一朵花
            /// </summary>
            /// <returns></returns>
            public Flower GetBottomFlower()
            {
                if (flowers.Count > 0)
                    return flowers[0];
                else
                    return null;
            }
            /// <summary>
            /// 移走最底下的一朵花
            /// </summary>
            internal void RemoveBottomFlower()
            {
                if (flowers.Count > 0)
                    flowers.RemoveAt(0);
            }
        }
    }

    蜜蜂对象
    Bee.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DemoGame
    {
        class Bee
        {
            public int Color;//蜜蜂颜色
            public bool IsSelected = false;//是否选中
    
            public Bee(int color)
            {
                this.Color = color;
            }
        }
    }

    蜜蜂容器
    BeePicker.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework;
    
    namespace DemoGame
    {
        class BeePicker
        {
            const int beeDeltaX = 96;
            const int beeStartX = 5;
            const int beeStartY = 700;
            const int numberOfBeeColors = 5;//蜜蜂颜色的数量
    
            private List<Bee> bees = null;//蜜蜂集合
            private SpriteBatch spriteBatch;
            private Texture2D beeMap;
            private Random r;
    
            public BeePicker(ContentManager content, SpriteBatch spriteBatch, int seed)
            {
                beeMap = content.Load<Texture2D>("beemap");
                this.spriteBatch = spriteBatch;
                bees = new List<Bee>();
                r = new Random(seed);
    
                for (int i = 0; i < 5; i++)
                {
                    AddRandomBee();
                }
    
            }
            /// <summary>
            /// 添加一只蜜蜂
            /// </summary>
            private void AddRandomBee()
            {
                bees.Add(new Bee(r.Next(numberOfBeeColors + 1)));
            }
            /// <summary>
            /// 绘制蜜蜂
            /// </summary>
            public void Draw()
            {
                for (int i = 0; i < 5; i++)
                {
                    if(bees[i].IsSelected)                    
                        spriteBatch.Draw(beeMap, new Vector2(beeStartX + i * beeDeltaX, beeStartY), new Rectangle(bees[i].Color * 91, 0, 91, 91), Color.DimGray);
                    else
                        spriteBatch.Draw(beeMap, new Vector2(beeStartX + i * beeDeltaX, beeStartY), new Rectangle(bees[i].Color * 91, 0, 91, 91), Color.White);
                }
            }
            /// <summary>
            /// 选中一只蜜蜂
            /// </summary>
            /// <param name="x"></param>
            public void MarkSelectedBee(float x)
            {
                GetSelectedBee(x).IsSelected = true;
            }
            /// <summary>
            /// 获取选中的蜜蜂
            /// </summary>
            /// <param name="x"></param>
            /// <returns></returns>
            public Bee GetSelectedBee(float x)
            {
                int index = (int)(x / beeDeltaX);
                return bees[index];
            }
            /// <summary>
            /// 移除和替换蜜蜂
            /// </summary>
            /// <param name="selectedBee"></param>
            /// <param name="availableFlowers"></param>
            public void RemoveAndReplaceBee(Bee selectedBee, List<int> availableFlowers)
            {
                int beeIndex = bees.IndexOf(selectedBee);
    
                //check if we already have a bee that matches the available flowers 
                //remember to skip over the selectedBee since it will be removed in a moment
                bool match = false;
                int rainbowColor = 6;
    
                //if there is a rainbow flower it will always match
                if (availableFlowers.Contains(rainbowColor))
                    match = true;
                else
                {
                    for (int i = 0; i < bees.Count; i++)
                    {
                        if(i != beeIndex && availableFlowers.Contains(bees[i].Color)){
                            match = true;
                            break;
                        }
                    }
                }
    
                int color;
                if(match){
                    //we already have a match, just add a random colored bee
                    color = r.Next(numberOfBeeColors + 1 );
                }
                else{
                    //we have no match so we must pick a color from the available colors
                    color = availableFlowers[r.Next(availableFlowers.Count)];
                }
    
                //set the selected bee to the new color to "create" a new bee
                bees[beeIndex].Color = color;
            }
    
            internal void DeselectAll()
            {
                foreach (Bee bee in bees)
                    bee.IsSelected = false;
            }
        }
    }

    游戏主程序
    Game1.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Media;
    
    namespace DemoGame
    {
        /// <summary>
        /// This is the main type for your game
        /// </summary>
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
    
            //纹理
            Texture2D backgroundTexture;
            Texture2D foregroundTexture;
            Texture2D hudTexture;
            Texture2D flowerMapTexture;
            //分数
            int score = 0;
            //字体
            SpriteFont largeFont;
            SpriteFont mediumFont;
            SpriteFont smallFont;
    
            List<Column> columns;//列集合
            bool gameOver = false;//标记游戏是否结束
            BeePicker beePicker = null;//蜜蜂处理类
            Bee selectedBee = null;//蜜蜂
    
            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                //设置游戏图像的宽和高
                graphics.PreferredBackBufferHeight = 800;
                graphics.PreferredBackBufferWidth = 480;
    
                Content.RootDirectory = "Content";
    
                // Frame rate is 30 fps by default for Windows Phone.
                TargetElapsedTime = TimeSpan.FromTicks(333333);
    
                // Extend battery life under lock.
                InactiveSleepTime = TimeSpan.FromSeconds(1);
            }
            /// <summary>
            /// 初始化
            /// </summary>
            protected override void Initialize()
            {
                // TODO: Add your initialization logic here
                //添加触摸事件
                TouchPanel.EnabledGestures = GestureType.Tap;
    
                base.Initialize();
            }
            /// <summary>
            /// 加载资源
            /// </summary>
            protected override void LoadContent()
            {
                //创建一个新的SpriteBatch用来绘制纹理
                spriteBatch = new SpriteBatch(GraphicsDevice);
                //加载纹理
                backgroundTexture = Content.Load<Texture2D>("GameScreenBackground");
                foregroundTexture = Content.Load<Texture2D>("GameScreenForeground");
                hudTexture = Content.Load<Texture2D>("HUDBackground");
                flowerMapTexture = Content.Load<Texture2D>("flowermap");
                //加载字体资源
                largeFont = Content.Load<SpriteFont>("LargeMenuFont");
                mediumFont = Content.Load<SpriteFont>("MediumMenuFont");
                smallFont = Content.Load<SpriteFont>("SmallMenuFont");
                //初始化列
                InitializeColumns();
                beePicker = new BeePicker(Content, spriteBatch, System.DateTime.Now.Millisecond);
            }
            /// <summary>
            /// 初始化列
            /// </summary>
            private void InitializeColumns()
            {
                columns = new List<Column>();
    
                int seed = System.DateTime.Now.Millisecond;
                //初始化6列
                for (int i = 0; i < 5; i++)
                {
                    columns.Add(new Column(Content, spriteBatch, i * 92 + 22, seed + i));
                }
            }
            /// <summary>
            /// UnloadContent will be called once per game and is the place to unload
            /// all content.
            /// </summary>
            protected override void UnloadContent()
            {
                // TODO: Unload any non ContentManager content here
            }
    
            /// <summary>
            /// Allows the game to run logic such as updating the world,
            /// checking for collisions, gathering input, and playing audio.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            protected override void Update(GameTime gameTime)
            {
                // 退出游戏
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
    
                // 添加更新的逻辑
                if (!gameOver)
                {
                    //处理用户的操作
                    while (TouchPanel.IsGestureAvailable)//是否触摸到屏幕
                    {
                        GestureSample gesture = TouchPanel.ReadGesture();//获取手势
                        if (gesture.GestureType == GestureType.Tap)//点击操作
                        {
                            HandleInput(gesture.Position);//传入点击的位置,处理点击操作
                        }
                    }
                    //更新花的状态,即不停地往下移动
                    foreach (Column c in columns)
                    {
                        c.Update();
                        if (c.ReachedBottom)//花到达底部,游戏结束
                        {
                            gameOver = true;
                            break;
                        }
                    }
                }
    
                base.Update(gameTime);
            }
            /// <summary>
            /// 点击输入操作处理
            /// </summary>
            /// <param name="position"></param>
            private void HandleInput(Vector2 position)
            {
                if (position.X > 0 && position.X < 480 && position.Y > 700 && position.Y < 800)//点种了蜜蜂的位置
                    HandleBeeSelection(position.X);
                else if (selectedBee != null)//选中了蜜蜂
                    HandleFlowerSelection(position.X, position.Y);
            }
            /// <summary>
            /// 处理选中花的操作
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            private void HandleFlowerSelection(float x, float y)
            {
                //判断是否点中了列的位置
                if (x > 10 && x < 470 && y > 100 && y < 700)
                {
                    int rainbowColor = 6;
                    int selectedColumnIndex = (int)((x - 10) / 92);
                    //获取点中的列
                    Column selectedColumn = columns[selectedColumnIndex];
                    //获取点中的列底部的花
                    Flower selectedFlower = selectedColumn.GetBottomFlower();
    
                    //判断是否点中了底部的花,并且花的颜色和蜜蜂的颜色要相等,或者花是彩色的花
                    if(selectedFlower != null && (selectedFlower.Color == selectedBee.Color || selectedFlower.Color == rainbowColor))
                    {
                        //移除花
                        selectedColumn.RemoveBottomFlower();
                        //替换另外一只蜜蜂,并且要保证至少要有一只蜜蜂可以和最底层的花可以匹配得上
                        List<int> availableFlowers = GetAvailableFlowers();
                        beePicker.RemoveAndReplaceBee(selectedBee, availableFlowers);
    
                        //取消对蜜蜂的选中状态
                        beePicker.DeselectAll();
                        selectedBee = null;//设置选中的蜜蜂为null
    
                        //如果蜜蜂吃掉的是彩色的花则增加一分
                        if (selectedFlower.Color == rainbowColor)
                        {
                            score++;
                            //如果分数达到10, 20, 30... 则不断地增加花下落的Y轴偏移量速度
                            if ((score % 10) == 0)
                            {
                                foreach (Column c in columns)
                                    c.Velocity += 0.1f;
                            }
                        }
                    }
                }
            }
            /// <summary>
            /// 获取最底下花的颜色,用来作为随机生成蜜蜂的一个条件
            /// </summary>
            /// <returns></returns>
            private List<int> GetAvailableFlowers()
            {
                List<int> flowerColors = new List<int>();
                foreach (Column c in columns)
                {
                    Flower f = c.GetBottomFlower();
                    if (f != null)
                        flowerColors.Add(f.Color);
                }
                return flowerColors;
            }
            /// <summary>
            /// 处理选中蜜蜂操作
            /// </summary>
            /// <param name="x"></param>
            private void HandleBeeSelection(float x)
            {
                //first de-select any previously selected bee
                if (selectedBee != null)
                {
                    selectedBee.IsSelected = false;
                    selectedBee = null;
                }
                //Mark and select the new bee
                beePicker.MarkSelectedBee(x);
                selectedBee = beePicker.GetSelectedBee(x);
            }
    
            /// <summary>
            /// This is called when the game should draw itself.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                spriteBatch.Begin();
                //画游戏背景
                spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
                //判断游戏是否结束
                if (!gameOver)
                {
                    //绘制花精灵
                    foreach (Column c in columns)
                        c.Draw();
                    //绘制蜜蜂精灵
                    beePicker.Draw();
                }
                else
                {
                    spriteBatch.DrawString(largeFont, "GAME OVER", new Vector2(150, 400), Color.Red);
                }
    
                spriteBatch.Draw(foregroundTexture, Vector2.Zero, Color.White);
                DrawHUD();
                spriteBatch.End();
    
                base.Draw(gameTime);
            }
            /// <summary>
            /// 初始化屏幕
            /// </summary>
            private void DrawHUD()
            {
                spriteBatch.Draw(hudTexture, new Vector2(7, 7), Color.White);
                //Print out game score and level
                spriteBatch.DrawString(mediumFont, "Marathon", new Vector2(40, 10), Color.Blue);
                spriteBatch.DrawString(largeFont, score.ToString(), new Vector2(127, 45), Color.Yellow);
                //TODO: Draw a flower on the HUD
                spriteBatch.Draw(flowerMapTexture, new Vector2(40, 45), new Rectangle(6*72, 0, 72, 72), Color.White, 0, Vector2.Zero, 0.5f, SpriteEffects.None, 0f);
                //Print out instructions
                spriteBatch.DrawString(smallFont, "Match flowers and bees", new Vector2(210, 10), Color.Yellow);
                spriteBatch.DrawString(smallFont, "Rainbow flowers match", new Vector2(206, 30), Color.Yellow);
                spriteBatch.DrawString(smallFont, "with all bees", new Vector2(260, 50), Color.Yellow);
                //Print out goal message
                spriteBatch.DrawString(largeFont, "Collect Rainbow Flowers", new Vector2(50, 115), Color.Blue);
            }
        }
    }

    游戏的项目结构

    参考文章:

    http://blogs.msdn.com/b/tess/archive/2012/03/02/xna-for-windows-phone-walkthrough-creating-the-bizzy-bees-game.aspx

  • 相关阅读:
    delphi try except语句 和 try finally语句用法以及区别
    正向代理与反向代理(转)
    kbmMW功能
    problem 202,263、232、21、231
    leetcode day8
    leetcode day7
    VS2013 opencv2.4.8
    web 前端routine
    leetcode day6
    leetcode day5
  • 原文地址:https://www.cnblogs.com/linzheng/p/2441521.html
Copyright © 2011-2022 走看看