天天看點

上接遊戲人生Silverlight(6) - 貪吃蛇[Silverlight 3.0(c#)]

/// <summary> 

                /// 生成豆 

                /// </summary> 

                void UpdateBean() 

                { 

                        if (_needBeansCount > 0 && (DateTime.Now - _prevAddBeanDateTime).TotalSeconds > 3) 

                        { 

                                List<CellPoint> emptyCells = GetEmptyCells(); 

                                if (emptyCells.Count == 0) 

                                { 

                                        GameOver(this, EventArgs.Empty); 

                                        return; 

                                } 

                                CellPoint point = emptyCells[_random.Next(0, emptyCells.Count)]; 

                                Bean bean = new Bean(); 

                                bean.SetValue(Canvas.LeftProperty, point.X * App.CellSize); 

                                bean.SetValue(Canvas.TopProperty, point.Y * App.CellSize); 

                                _beans.Add(bean, point); 

                                canvasBean.Children.Add(bean); 

                                bean.ani.Completed += delegate 

                                        ripple.ShowRipple(new Point(point.X * App.CellSize + App.CellSize / 2, point.Y * App.CellSize + App.CellSize / 2)); 

                                        player.PlayDrop(); 

                                }; 

                                _needBeansCount--; 

                                _prevAddBeanDateTime = DateTime.Now; 

                        } 

                } 

                private DateTime _prevDateTime = DateTime.Now; 

                private double _leftoverLength = 0d; 

                void CompositionTarget_Rendering(object sender, EventArgs e) 

                        double length = (DateTime.Now - _prevDateTime).TotalSeconds + _leftoverLength; 

                        while (length > _dt) 

                                Update(); 

                                length -= _dt; 

                        _leftoverLength = length; 

                        _prevDateTime = DateTime.Now; 

                /// <summary> 

                /// 即時計算 

                private void Update() 

                        if (!_enabled) 

                                return; 

                        double offset = Math.Round(_speed * _dt, _decimals); 

                        // 蛇頭所處位置進入了網格點區域内 

                        if (Math.Abs(Math.Round((double)_bodies.First().Key.GetValue(Canvas.TopProperty) % App.CellSize, _decimals)) < offset && Math.Abs(Math.Round((double)_bodies.First().Key.GetValue(Canvas.LeftProperty) % App.CellSize, _decimals)) < offset) 

                                UpdateDirection(); 

                                CorrectPosition(); 

                                UpdateBodyCell(); 

                                CheckEat(); 

                                CheckSkin(); 

                                CheckCollision(); 

                                UpdateBean(); 

                                if (_needRaiseAteEvent) 

                                        Ate(this.Ate, EventArgs.Empty); 

                                        _needRaiseAteEvent = false; 

                        UpdatePosition(); 

                /// 蛻皮 

                private void CheckSkin() 

                        if (_bodies.Count >= _ateCapacity + _selfLength) 

                                AddSkin(_ateCapacity); 

                /// 碰撞檢測 

                private void CheckCollision() 

                        if (_skins.Any(p => p.Value == _bodies.First().Value) || _bodies.Where(p => p.Key.BodyType == BodyType.Tail).Any(p => p.Value == _bodies.First().Value)) 

                                _enabled = false; 

                                player.PlayOver(); 

                                GameOver(this, EventArgs.Empty); 

                /// 吃豆 

                private void CheckEat() 

                        // 是否有被吃的豆 

                        var bean = _beans.FirstOrDefault(p => p.Value == _bodies.First().Value).Key; 

                        if (bean != null) 

                                _beans.Remove(bean); 

                                canvasBean.Children.Remove(bean); 

                                player.PlayEat(); 

                                AddTail(); 

                                AddBean(); 

                                _needRaiseAteEvent = true; 

                /// 更新蛇的每一段的運動方向 

                private void UpdateDirection() 

                        for (int i = _bodies.Count - 1; i > -1; i--) 

                                if (i == 0) 

                                        _bodies.ElementAt(i).Key.MoveDirection = _moveDirection; 

                                else 

                                        _bodies.ElementAt(i).Key.MoveDirection = _bodies.ElementAt(i - 1).Key.MoveDirection; 

                /// 更新蛇的每一段的位置 

                private void UpdatePosition() 

                        foreach (var body in _bodies.Keys) 

                                if (body.MoveDirection == Direction.Up) 

                                        body.SetValue(Canvas.TopProperty, Math.Round((double)body.GetValue(Canvas.TopProperty) - offset, _decimals)); 

                                else if (body.MoveDirection == Direction.Down) 

                                        body.SetValue(Canvas.TopProperty, Math.Round((double)body.GetValue(Canvas.TopProperty) + offset, _decimals)); 

                                else if (body.MoveDirection == Direction.Left) 

                                        body.SetValue(Canvas.LeftProperty, Math.Round((double)body.GetValue(Canvas.LeftProperty) - offset, _decimals)); 

                                else if (body.MoveDirection == Direction.Right) 

                                        body.SetValue(Canvas.LeftProperty, Math.Round((double)body.GetValue(Canvas.LeftProperty) + offset, _decimals)); 

                /// 蛻指定數量的皮 

                private void AddSkin(int count) 

                        player.PlaySkin(); 

                        while (count > 0) 

                                KeyValuePair<Body, CellPoint> body = _bodies.ElementAt(_bodies.Count - 1); 

                                CellPoint skinPoint = body.Value; 

                                Skin skin = new Skin(); 

                                skin.SetValue(Canvas.LeftProperty, skinPoint.X * App.CellSize); 

                                skin.SetValue(Canvas.TopProperty, skinPoint.Y * App.CellSize); 

                                _skins.Add(skin, skinPoint); 

                                canvasSkin.Children.Add(skin); 

                                _emptyCells.Remove(skinPoint); 

                                canvasSnake.Children.Remove(body.Key); 

                                _bodies.Remove(body.Key); 

                                count--; 

輔助方法#region 輔助方法 

                /// 修正指定的位置資訊為整數 

                private int CorrectPosition(double position) 

                        double result; 

                        double temp = Math.Round(position % App.CellSize, _decimals); 

                        if (Math.Abs(temp) < offset) 

                                result = Math.Round(position - temp); 

                        else 

                                result = Math.Round(position - temp) + Math.Sign(temp) * App.CellSize; 

                        return (int)result; 

                /// 修正蛇的每一段的位置為整數 

                private void CorrectPosition() 

                        foreach (Body body in _bodies.Keys) 

                                double x = CorrectPosition((double)body.GetValue(Canvas.LeftProperty)); 

                                double y = CorrectPosition((double)body.GetValue(Canvas.TopProperty)); 

                                if (x == App.Width) 

                                        x = 0d; 

                                else if (x == -App.CellSize) 

                                        x = App.Width - App.CellSize; 

                                else if (y == App.Height) 

                                        y = 0d; 

                                else if (y == -App.CellSize) 

                                        y = App.Height - App.CellSize; 

                                body.SetValue(Canvas.LeftProperty, x); 

                                body.SetValue(Canvas.TopProperty, y); 

                /// 更新蛇的每一段的網格位置資訊 

                private void UpdateBodyCell() 

                        for (int i = 0; i < _bodies.Count; i++) 

                                UpdateBodyCell(_bodies.ElementAt(i).Key); 

                /// 更新指定的 Body 的網格位置資訊 

                private void UpdateBodyCell(Body body) 

                        CellPoint point = new CellPoint((int)((double)body.GetValue(Canvas.LeftProperty) / App.CellSize), (int)((double)body.GetValue(Canvas.TopProperty) / App.CellSize)); 

                        if (body.MoveDirection == Direction.Up) 

                                point.Y--; 

                        else if (body.MoveDirection == Direction.Down) 

                                point.Y++; 

                        else if (body.MoveDirection == Direction.Left) 

                                point.X--; 

                        else if (body.MoveDirection == Direction.Right) 

                                point.X++; 

                        point = CorrectCellPoint(point); 

                        _bodies[body] = point; 

                /// 修正網格位置 

                private CellPoint CorrectCellPoint(CellPoint point) 

                        if (point.X > _columns - 1) 

                                point.X = _columns - point.X; 

                        else if (point.X < 0) 

                                point.X = point.X + _columns; 

                        if (point.Y > _rows - 1) 

                                point.Y = _rows - point.Y; 

                        else if (point.Y < 0) 

                                point.Y = point.Y + _rows; 

                        return point; 

                /// 擷取空網格集合 

                private List<CellPoint> GetEmptyCells() 

                        List<CellPoint> emptyCells = new List<CellPoint>(); 

                        List<CellPoint> aroundHeadCells = new List<CellPoint>(); 

                        CellPoint headPoint = _bodies.First().Value; 

                        for (int i = -5; i < 5; i++) 

                                for (int j = -5; j < 5; j++) 

                                        CellPoint point = new CellPoint(headPoint.X + i, headPoint.Y + j); 

                                        point = CorrectCellPoint(point); 

                                        aroundHeadCells.Add(point); 

                        // skin 的占位情況因為确定了就不變了,是以在 AddSkin() 處計算 

                        // 為了以下 LINQ 的可用,需要重寫 CellPoint 的 public override bool Equals(object obj) 

                        emptyCells = _emptyCells.Where(p => !_bodies.Select(x => x.Value).Contains(p)).ToList(); 

                        emptyCells = emptyCells.Where(p => !_beans.Select(x => x.Value).Contains(p)).ToList(); 

                        emptyCells = emptyCells.Where(p => !aroundHeadCells.Contains(p)).ToList(); 

                        return emptyCells; 

                #endregion 

屬性#region 屬性 

                public Direction MoveDirection 

                        set 

                                Body head = _bodies.First().Key; 

                                if (head.MoveDirection == Direction.Up && value == Direction.Down) 

                                if (head.MoveDirection == Direction.Down && value == Direction.Up) 

                                if (head.MoveDirection == Direction.Left && value == Direction.Right) 

                                if (head.MoveDirection == Direction.Right && value == Direction.Left) 

                                _moveDirection = value; 

                public bool Enabled 

                        get { return _enabled; } 

                        set { _enabled = value; } 

                public double Speed 

                        get { return _speed; } 

                        set { _speed = value; } 

                public int AteCapacity 

                        get { return _ateCapacity; } 

                        set { _ateCapacity = value; } 

事件 GameOver 和 Ate#region 事件 GameOver 和 Ate 

                public event EventHandler GameOver; 

                public event EventHandler Ate; 

        } 

}

OK

<a href="http://down.51cto.com/data/101271" target="_blank">[源碼下載下傳]</a>

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/345619,如需轉載請自行聯系原作者

繼續閱讀