Head First C# (蜂巢模拟系统)

这个系统模拟一个蜂巢,蜜蜂进行采集花粉并酿蜜,该模拟系统运用到的技术有 LINQ、 GDI、 序列化、打印 和 委托等C#常用技术,利用GDI绘图简单实现了动画效果如下图所示:

打印预览效果如下图所示,本链接提供了本系统的源代码,还有之前Head First3个游戏的源代码,下面贴一些核心代码,如果比较熟悉该部分内容则可略过

namespace 蜂巢模拟系统
{
    public partial class Form1 : Form
    {
        World world;//花园
        private Random random = new Random();
        private DateTime start = DateTime.Now;
        private DateTime end;
        private int framesRun = 0;//游戏已经运行的时间
        private HiveForm hiveForm;//蜂窝窗体
        private FieldForm fieldForm;//花园窗体
        Renderer renderer;//图像绘制类

        public Form1()
        {
            //初始化并显示窗体
            InitializeComponent();
            world = new World(new Bee.BeeMessage(SendMessage));

            timer1.Interval = 50;
            timer1.Tick+=new EventHandler(RunFrame);
            timer1.Enabled = false;
            UpdateStats(new TimeSpan());

            hiveForm = new HiveForm();
            fieldForm = new FieldForm();
            CreateRender();

            MoveChildForms();
            hiveForm.Show(this);
            fieldForm.Show(this);
        }

        private void MoveChildForms()
        {
            hiveForm.Location = new Point(Location.X+Width+10,Location.Y);
            fieldForm.Location = new Point(Location.X, Location.Y + Math.Max(Height, hiveForm.Height) + 10);
        }

        /// <summary>
        /// 更新窗体数据
        /// </summary>
        private void UpdateStats(TimeSpan frameDuration)
        {
            Bees.Text = world.Bees.Count.ToString();
            Flowers.Text = world.Flowers.Count.ToString();
            HoneyInHive.Text = string.Format("{0:f3}",world.Hive.Honey);
            double nectar = 0;
            foreach (Flower flower in world.Flowers)
                nectar += flower.Nectar;
            NectarInFlowers.Text = string.Format("{0:f3}",nectar);
            FrameRun.Text = framesRun.ToString();
            double milliSeconds = frameDuration.TotalMilliseconds;
            if (milliSeconds != 0.0)
                FrameRate.Text = string.Format("{0:f0}({1:f1}ms)", 1000 / milliSeconds, milliSeconds);
            else
                FrameRate.Text = "N/A";
        }

        /// <summary>
        /// 运行
        /// </summary>
        public void RunFrame(object sender, EventArgs e)
        {
            framesRun++;
            world.Go(random);
            end = DateTime.Now;
            TimeSpan frameDuration = end - start;
            start = end;
            UpdateStats(frameDuration);
            hiveForm.Invalidate();
            fieldForm.Invalidate();
        }

        /// <summary>
        /// 系统运行按钮触发
        /// </summary>
        private void startSimulation_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled)
            {
                toolStrip1.Items[0].Text = "Resume simulation";
                timer1.Stop();
            }
            else
            {
                toolStrip1.Items[0].Text = "Pause simulation";
                timer1.Start();
            }
        }

        /// <summary>
        /// 系统重置按钮触发
        /// </summary>
        private void reset_Click(object sender, EventArgs e)
        {
            world = new World(new Bee.BeeMessage(SendMessage));
            CreateRender();
            framesRun = 0;            
            if (!timer1.Enabled)
                toolStrip1.Items[0].Text = "Start simulation";
        }

        private void CreateRender()
        {
            renderer = new Renderer(world,hiveForm,fieldForm);
            hiveForm.renderer = renderer;
            fieldForm.renderer = renderer;
        }

        /// <summary>
        /// 显示蜜蜂信息
        /// </summary>
        private void SendMessage(int ID, string Message)
        {
            statusStrip1.Items[0].Text = "Bee #" + ID + ":" + Message;

            //LINQ
            var beeGroups = from bee in world.Bees
                            group bee by bee.CurrentState into beeGroup
                            orderby beeGroup.Key
                            select beeGroup;
            listBox1.Items.Clear();
            foreach (var group in beeGroups)
            {
                string s;
                if (group.Count() == 1)
                    s = "";
                else
                    s = "s";
                listBox1.Items.Add(group.Key.ToString() + ": "
                    + group.Count() + " bee" + s);
                if (group.Key == BeeState.Idle
                    && group.Count() == world.Bees.Count()
                    && framesRun > 0)
                {
                    listBox1.Items.Add("Simulation ended:all bees are idle");
                    toolStrip1.Items[0].Text = "Simulation ended";
                    timer1.Enabled = false;
                }
            }
        }

        private void Form1_Move(object sender, EventArgs e)
        {
            MoveChildForms();
        }

        /// <summary>
        /// 打开已保存的数据(反序列化)
        /// </summary>
        private void 打开OToolStripButton_Click(object sender, EventArgs e)
        {
            World currentWord = world;
            int currentFramesRun = framesRun;

            bool enabled = timer1.Enabled;
            if (enabled)
                timer1.Stop();

            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "Simulator File(*.bees)|*.bees";
            open.CheckFileExists = true;
            open.CheckPathExists = true;
            open.Title = "Choose a file with a simulation to load";
            if (open.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    using (Stream input = File.OpenRead(open.FileName))
                    {
                        world = (World)bf.Deserialize(input);
                        framesRun = (int)bf.Deserialize(input);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to read the simulator file\r\n"+ex.Message,
                        "Bee Simulator Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    world = currentWord;
                    framesRun = currentFramesRun;
                }
            }
            world.Hive.MessageSender = new Bee.BeeMessage(SendMessage);
            foreach (Bee bee in world.Bees)
                bee.MessageSender = new Bee.BeeMessage(SendMessage);
            if (enabled)
                timer1.Start();

            CreateRender();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            renderer.AnimateBees();
        }

        /// <summary>
        /// 打印按钮触发
        /// </summary>
        private void 打印PToolStripButton_Click(object sender, EventArgs e)
        {
            bool stoppedTimer = false;
            if (timer1.Enabled)
            {
                timer1.Stop();
                stoppedTimer = true;
            }
            PrintPreviewDialog preview = new PrintPreviewDialog();
            PrintDocument document = new PrintDocument();
            preview.Document = document;
            document.PrintPage += new PrintPageEventHandler(document_PrintPage);
            preview.ShowDialog(this);          
            if (stoppedTimer)
                timer1.Start();
        }

        /// <summary>
        /// 打印表格
        /// </summary>
        private int PrintTableRow(Graphics printGraphics, int tableX, int tableWidth, int firstColumnX, int secondColumnX,
            int tableY, string firstColumn, string secondColumn)
        {
            Font arial12 = new Font("Arial",12);
            Size stringSize = Size.Ceiling(printGraphics.MeasureString(firstColumn, arial12));
            tableY += 2;
            printGraphics.DrawString(firstColumn, arial12, Brushes.Black, firstColumnX, tableY);
            printGraphics.DrawString(secondColumn, arial12, Brushes.Black, secondColumnX, tableY);
            tableY += (int)stringSize.Height + 2;
            printGraphics.DrawLine(Pens.Black, tableX, tableY, tableX + tableWidth, tableY);
            arial12.Dispose();
            return tableY;
        }

        /// <summary>
        /// 打印页面绘制 GDI
        /// </summary>
        private void document_PrintPage(object sender, PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;

            Size stringSize;
            using (Font arial24bold = new Font("Arial", 24, FontStyle.Bold))
            {
                stringSize = Size.Ceiling(g.MeasureString("Bee Simulator", arial24bold));
                g.FillEllipse(Brushes.Gray, new Rectangle(e.MarginBounds.X + 2, e.MarginBounds.Y + 2,
                    stringSize.Width + 30, stringSize.Height + 30));
                g.FillEllipse(Brushes.Black,new Rectangle (e.MarginBounds.X,e.MarginBounds.Y,
                    stringSize.Width + 30, stringSize.Height + 30) );
                g.DrawString("Bee Simulator", arial24bold, Brushes.Gray,
                    e.MarginBounds.X + 17, e.MarginBounds.Y + 17);
                g.DrawString("Bee Simulator", arial24bold, Brushes.White,
                   e.MarginBounds.X + 15, e.MarginBounds.Y + 15);
            }

            int tableX = e.MarginBounds.X + (int)stringSize.Width + 50;
            int tableWidth = e.MarginBounds.X + e.MarginBounds.Width - tableX - 20;
            int firstColumnX = tableX + 2;
            int secondColumnX = tableX + (tableWidth / 2) + 5;
            int tableY = e.MarginBounds.Y;

            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
                "Bees", Bees.Text);
            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
               "Flowers", Flowers.Text);
            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
               "Honey in Hive", HoneyInHive.Text);
            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
               "Nectar in Flowers", NectarInFlowers.Text);
            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
               "Frames Run",FrameRun.Text);
            tableY = PrintTableRow(g, tableX, tableWidth, firstColumnX, secondColumnX, tableY,
               "Frame Rate", FrameRate.Text);

            g.DrawRectangle(Pens.Black,tableX,e.MarginBounds.Y,tableWidth,tableY-e.MarginBounds.Y);
            g.DrawLine(Pens.Black, secondColumnX, e.MarginBounds.Y, secondColumnX, tableY);
            
            using(Pen blackPen=new Pen (Brushes.Black))
            using(Bitmap hiveBitmap=new Bitmap (hiveForm.ClientSize.Width,hiveForm.ClientSize.Height))
            using (Bitmap fieldBitmap = new Bitmap(fieldForm.ClientSize.Width, fieldForm.ClientSize.Height))
            {
                using (Graphics hiveGraphics = Graphics.FromImage(hiveBitmap))
                {
                    renderer.PaintHive(hiveGraphics);
                }
                int hiveWidth = hiveForm.ClientSize.Width+50;
                float ratio = (float)hiveBitmap.Height / (float)hiveBitmap.Width;
                int hiveHeight = (int)(hiveWidth * ratio);
                int hiveX = e.MarginBounds.X + (e.MarginBounds.Width - hiveWidth) / 2;
                int hiveY = tableY + 40;
                g.DrawImage(hiveBitmap, hiveX, hiveY, hiveWidth, hiveHeight);
                g.DrawRectangle(blackPen,hiveX,hiveY,hiveWidth,hiveHeight);

                using (Graphics fieldGraphics = Graphics.FromImage(fieldBitmap))
                {
                    renderer.PaintField(fieldGraphics);
                }
                int fieldWidth = e.MarginBounds.Width;
                ratio = (float)fieldBitmap.Height / (float)fieldBitmap.Width;
                int fieldHeight = (int)(fieldWidth * ratio);
                int fieldX = e.MarginBounds.X;
                int fieldY = hiveY +hiveHeight+ 50;
                g.DrawImage(fieldBitmap, fieldX, fieldY, fieldWidth, fieldHeight);
                g.DrawRectangle(blackPen, fieldX, fieldY, fieldWidth, fieldHeight);

            }
        }

        /// <summary>
        /// 保存按钮触发(序列化)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 保存SToolStripButton_Click(object sender, EventArgs e)
        {
            bool enabled = timer1.Enabled;
            if (enabled)
                timer1.Stop();
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.Filter = "Simulator File(*.bees)|*.bees";
            saveDialog.CheckFileExists = true;
            saveDialog.Title = "Choose a file to save the current simulation";
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    using (Stream output = File.OpenWrite(saveDialog.FileName))
                    {
                        bf.Serialize(output, world);
                        bf.Serialize(output, framesRun);
                    }
                }
                catch (Exception ex)
                { MessageBox.Show("Unable to save the simulator file\r\n"+ex.Message,
                    "Bee Simulator Error",MessageBoxButtons.OK,MessageBoxIcon.Error); }
            }          
            if (enabled)
                timer1.Start();
        }
    }

    [Serializable]
    public class Flower
    {
        private const int LifeSpanMin = 1500;//花的最短寿命
        private const int LifeSpanMax = 3000;//花的最长寿命
        private const double InitialNectar = 1.5;//最初花粉
        private const double MaxNectar = 5.0;//一朵花能装多少花粉
        private const double NectarAddedPerTurn = 0.01;//花逐渐变老时每次增加多少花粉
        private const double NectarGatheredPerTurn = 0.03;//一个周期内收集多少花粉

        public Point Location { get; private set; }//花的位置
        public int Age { get; private set; }//年龄
        public bool Alive { get; private set; }//是否存活
        public double Nectar { get; private set; }//花粉
        public double NectarHarvested { get; set; }//已被采集的花粉
        private int lifeSpan;//生命

        public Flower(Point location, Random random)
        {
            Location = location;
            Age = 0;
            Alive = true;
            Nectar = InitialNectar;
            NectarHarvested = 0;
            lifeSpan = random.Next(LifeSpanMin,LifeSpanMax+1);
        }

        public double HarvestNectar()
        {
            //采集花粉,蜜蜂采集花粉减少花粉存量增加花粉已采量
            if (NectarGatheredPerTurn > Nectar)
                return 0;
            else
            {
                Nectar -= NectarGatheredPerTurn;
                NectarHarvested += NectarGatheredPerTurn;
                return NectarGatheredPerTurn;
            }
        }

        public void Go()
        {
            //运行一帧,花增大年龄并且增加自身花粉存量
            Age++;
            if (Age > lifeSpan)
                Alive = false;
            else
            {
                Nectar += NectarAddedPerTurn;
                if (Nectar > MaxNectar)
                    Nectar = MaxNectar;
            }            
        }
    }

    public enum BeeState
    { 
        Idle,//什么也没做
        FlyingToFlower,//正飞向花
        GatheringNectar,//收集花粉
        ReturningToHive,//飞回蜂巢
        MakingHoney,//酿蜜
        Retired//退休
    }

    [Serializable]
    public class Bee
    {
        private const double HoneyConsumed = 0.05;//每次消耗的蜂蜜
        private const int MoveRate = 3;//移动速率
        private const double MinimunFlowerNectar = 1.5;//采蜜花粉最低存量
        private const int CareerSpan = 1000;//生命

        public int Age { get; private set; }//年龄
        public bool InsideHive { get; private set; }//是否在蜂巢
        public double NectarCollected { get; private set; }//采集的花粉
        public BeeState CurrentState { get; private set; }

        private Point location;
        public Point Location { get { return location; } }

        private int ID;
        private Flower destinationFlower;

        private World world;
        private Hive hive;

        public delegate void BeeMessage(int ID, string Message);

        [NonSerialized]
        public BeeMessage MessageSender;

        private bool MoveTowardsLocation(Point destination)
        {
            if (destination != null)
            {
                if (Math.Abs(destination.X - location.X) <= MoveRate
                    && Math.Abs(destination.Y - location.Y) <= MoveRate)
                    return true;
                if (destination.X > location.X)
                        location.X += MoveRate;
                else 
                    if(destination.X<location.X)
                        location.X -= MoveRate;
                if (destination.Y > location.Y)
                        location.Y += MoveRate;
                else
                    if(destination.Y < location.Y)
                        location.Y -= MoveRate;
             }       
            return false;
        }

        public Bee(int ID, Point InitialLocation,World world,Hive hive)
        {
            this.ID = ID;
            Age = 0;
            location = InitialLocation;
            InsideHive = true;
            CurrentState = BeeState.Idle;
            destinationFlower = null;
            NectarCollected = 0;
            this.world = world;
            this.hive = hive;
        }

        public void Go(Random random)
        {
            Age++;
            BeeState oldState = CurrentState;
            #region BeeAction                    
            switch (CurrentState)
            {
                case BeeState.Idle:
                    if (Age > CareerSpan)
                    {
                        CurrentState = BeeState.Retired;
                    }
                    else if (world.Flowers.Count > 0
                        && hive.ConsumeHoney(HoneyConsumed))
                    {
                        Flower flower = world.Flowers[random.Next(world.Flowers.Count)];
                        if (flower.Nectar >= MinimunFlowerNectar && flower.Alive)
                        {
                            destinationFlower = flower;
                            CurrentState = BeeState.FlyingToFlower;
                        }
                    }
                    break;
                case BeeState.FlyingToFlower:
                    if (!world.Flowers.Contains(destinationFlower))
                        CurrentState = BeeState.ReturningToHive;
                    else
                        if (InsideHive)
                        {
                            if (MoveTowardsLocation(hive.GetLocation("Exit")))
                            {
                                InsideHive = false;
                                location = hive.GetLocation("Entrance");
                            }
                        }
                        else
                            if (MoveTowardsLocation(destinationFlower.Location))
                                CurrentState = BeeState.GatheringNectar;
                    break;
                case BeeState.GatheringNectar:
                    double nectar = destinationFlower.HarvestNectar();
                    if (nectar > 0)
                        NectarCollected += nectar;
                    else
                        CurrentState = BeeState.ReturningToHive;
                    break;
                case BeeState.ReturningToHive:
                    if (!InsideHive)
                    {
                        if (MoveTowardsLocation(hive.GetLocation("Entrance")))
                        {
                            InsideHive = true;
                            location = hive.GetLocation("Exit");
                        }
                    }
                    else
                        if (MoveTowardsLocation(hive.GetLocation("HoneyFactory")))
                            CurrentState = BeeState.MakingHoney;
                    break;
                case BeeState.MakingHoney:
                    if (NectarCollected < 0.5)
                    {
                        NectarCollected = 0;
                        CurrentState = BeeState.Idle;
                    }
                    else
                        if (hive.AddHoney(0.5))
                            NectarCollected -= 0.5;
                        else
                            NectarCollected = 0;
                    break;
                case BeeState.Retired:
                    break;
            }
            #endregion

            if (oldState != CurrentState && MessageSender != null)
                MessageSender(ID,CurrentState.ToString());
        }
    }

    [Serializable]
    public class Hive
    {
        private const int InitialBees = 10;//初始蜜蜂数量
        private const double InitialHoney = 3.2;//初始蜂蜜值
        private const double MaximumHoney = 15;//最大蜂蜜值
        private const double NectarHoneyRatio = 0.25;//花粉转换成蜂蜜的比率
        private const double MinimumHoneyForCreatingBees = 4.0;//新增蜜蜂最少需要的蜂蜜存量
        private const int MaximumBees = 12;//最大蜜蜂数量

        [NonSerialized]
        public Bee.BeeMessage MessageSender;

        private Dictionary<string, Point> locations;
        private int beeCount = 0;

        private World world;

        public double Honey { get; private set; }

        private void InitializeLocation()
        {
            locations = new Dictionary<string, Point>();
            locations.Add("Entrance",new Point (600,100));
            locations.Add("Nursery", new Point(95, 174));
            locations.Add("HoneyFactory", new Point(157, 68));
            locations.Add("Exit", new Point(194, 213));
        }

        public Point GetLocation(string location)
        {
            if (locations.Keys.Contains(location))
                return locations[location];
            else
                throw new ArgumentException("Unknown location:" + location);
        }

        public Hive(World world,Bee.BeeMessage MessageSender)
        {
            this.MessageSender = MessageSender;
            Honey = InitialHoney;
            InitializeLocation();
            this.world = world;
            Random random = new Random();
            for (int i = 0; i < InitialBees; i++)
                AddBee(random);
        }

        public bool AddHoney(double nectar)
        {
            //增加蜂蜜
            double honeyToAdd = nectar * NectarHoneyRatio;
            if (honeyToAdd + Honey > MaximumHoney)
                return false;
            Honey += honeyToAdd;
            return true;
        }

        public bool ConsumeHoney(double amount)
        {
            //消耗蜂蜜
            if (amount > Honey)
                return false;
            else 
            {
                Honey -= amount;
                return true;
            }          
        }

        private void AddBee(Random random)
        {
            //增加蜜蜂
            beeCount++;
            int r1 = random.Next(100) - 50;
            int r2 = random.Next(100) - 50;
            Point startPoint = new Point(locations["Nursery"].X + r1, locations["Nursery"].Y + r2);
            Bee newBee = new Bee(beeCount,startPoint,world,this);
            newBee.MessageSender += this.MessageSender;
            world.Bees.Add(newBee);
        }

        public void Go(Random random)
        {
            if (world.Bees.Count<MaximumBees
                && Honey > MinimumHoneyForCreatingBees 
                && random.Next(10)==1)
                AddBee(random);
        }
    }

    [Serializable]
    public class World
    {
        private const double NectarHarvestedPerNewFlower = 30.0;//累积采集多少花粉会增加花朵
        private const int FieldMinX = 15;
        private const int FieldMinY = 177;
        private const int FieldMaxX = 690;
        private const int FieldMaxY = 290;

        public Hive Hive;
        public List<Bee> Bees;
        public List<Flower> Flowers;

        public World(Bee.BeeMessage messageSender)
        {
            Bees = new List<Bee>();
            Flowers=new List<Flower>();
            Random random=new Random ();
            Hive = new Hive(this,messageSender);
            for(int i=0;i<10;i++)
                AddFlower(random);
        }

        public void Go(Random random)
        {
            Hive.Go(random);

            for (int i = Bees.Count - 1; i >= 0; i--)
            {
                Bee bee = Bees[i];
                bee.Go(random);
                if (bee.CurrentState == BeeState.Retired)
                    Bees.Remove(bee);
            }

            double totalNectarHarvested = 0;
            for (int i = Flowers.Count - 1; i >= 0; i--)
            {
                Flower flower = Flowers[i];
                flower.Go();
                totalNectarHarvested += flower.NectarHarvested;
                if (!flower.Alive)
                    Flowers.Remove(flower);
                if (totalNectarHarvested > NectarHarvestedPerNewFlower)
                {
                    foreach (Flower flo in Flowers)
                    {
                        flo.NectarHarvested = 0;                      
                    }
                    AddFlower(random);
                }
            }
        }

        private void AddFlower(Random random)
        {
            Point location = new Point(random.Next(FieldMinX,FieldMaxX),
                random.Next(FieldMinY,FieldMaxY));
            Flower newFlower = new Flower(location,random);
            Flowers.Add(newFlower);
        }
    }

    public class Renderer
    {
        private World world;
        private HiveForm hiveForm;
        private FieldForm fieldForm;

        public Renderer(World world, HiveForm hiveForm, FieldForm fieldForm)
        {
            this.world = world;
            this.hiveForm = hiveForm;
            this.fieldForm = fieldForm;
            InitialIizeImage();
        }
    
        public static Bitmap ResizeImage(Bitmap picture, int width, int height)
        {
            Bitmap resizedPicture = new Bitmap(width, height);
            using (Graphics graphics = Graphics.FromImage(resizedPicture))
            {
                graphics.DrawImage(picture,0,0,width,height);
            }
            return resizedPicture;
        }

        Bitmap HiveInside;
        Bitmap HiveOutSide;
        Bitmap Flower;
        Bitmap[] BeeAnimationSmall;
        Bitmap[] BeeAnimationLarge;
        private int Cell = 0;
        private int Frame = 0;

        private void InitialIizeImage()
        {
            HiveOutSide = ResizeImage(Properties.Resources.Hive__outside_,85,100);
            Flower = ResizeImage(Properties.Resources.Flower,75,75);
            HiveInside = ResizeImage(Properties.Resources.Hive__inside_,hiveForm.ClientRectangle.Width,hiveForm.ClientRectangle.Height);
            BeeAnimationLarge = new Bitmap[4];
            BeeAnimationLarge[0] = ResizeImage(Properties.Resources.Bee_animation_1, 40, 40);
            BeeAnimationLarge[1] = ResizeImage(Properties.Resources.Bee_animation_2, 40, 40);
            BeeAnimationLarge[2] = ResizeImage(Properties.Resources.Bee_animation_3, 40, 40);
            BeeAnimationLarge[3] = ResizeImage(Properties.Resources.Bee_animation_4, 40, 40);
            BeeAnimationSmall = new Bitmap[4];
            BeeAnimationSmall[0] = ResizeImage(Properties.Resources.Bee_animation_1, 20, 20);
            BeeAnimationSmall[1] = ResizeImage(Properties.Resources.Bee_animation_2, 20, 20);
            BeeAnimationSmall[2] = ResizeImage(Properties.Resources.Bee_animation_3, 20, 20);
            BeeAnimationSmall[3] = ResizeImage(Properties.Resources.Bee_animation_4, 20, 20);
        }

        public void PaintHive(Graphics g)
        {
            g.FillRectangle(Brushes.SkyBlue,hiveForm.ClientRectangle);
            g.DrawImageUnscaled(HiveInside,0,0);
            foreach (Bee bee in world.Bees)
            {
                if (bee.InsideHive)
                    g.DrawImageUnscaled(BeeAnimationLarge[Cell], bee.Location.X, bee.Location.Y);
            }
        }

        public void PaintField(Graphics g)
        {
            using (Pen brownPen = new Pen(Color.Brown, 6.0F))
            {
                g.FillRectangle(Brushes.SkyBlue,0,0,fieldForm.ClientSize.Width,fieldForm.ClientSize.Height);
                g.FillEllipse(Brushes.Yellow, new RectangleF(50, 15, 70, 70));
                g.FillRectangle(Brushes.Green,0,fieldForm.ClientSize.Height/2,fieldForm.ClientSize.Width,fieldForm.ClientSize.Height/2);
                g.DrawLine(brownPen, new Point(643, 0), new Point(643, 30));
                g.DrawImageUnscaled(HiveOutSide,600,20);
                foreach (Flower flower in world.Flowers)
                {
                    g.DrawImageUnscaled(Flower,flower.Location.X,flower.Location.Y);
                }
                foreach (Bee bee in world.Bees)
                {
                    if (!bee.InsideHive)
                        g.DrawImageUnscaled(BeeAnimationSmall[Cell],bee.Location.X,bee.Location.Y);
                }
            }
        }

        public void AnimateBees()
        {
            Frame++;
            if (Frame > 6)
                Frame = 0;
            switch (Frame)
            {
                case 0: Cell = 0; break;
                case 1: Cell = 1; break;
                case 2: Cell = 2; break;
                case 3: Cell = 3; break;
                case 4: Cell = 2; break;
                case 5: Cell = 1; break;
                default: Cell = 0; break;
            }
            hiveForm.Invalidate();
            fieldForm.Invalidate();          
        }
    }
}


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值