您的位置:首页 > 编程语言 > C#

上接游戏人生Silverlight(6) - 贪吃蛇[Silverlight 3.0(c#)]

2009-09-14 08:28 483 查看
/// <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>


/// 即时计算


/// </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();


}




/// <summary>


/// 蜕皮


/// </summary>


private void CheckSkin()


{


if (_bodies.Count >= _ateCapacity + _selfLength)


AddSkin(_ateCapacity);


}




/// <summary>


/// 碰撞检测


/// </summary>


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);


}


}




/// <summary>


/// 吃豆


/// </summary>


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;


}


}




/// <summary>


/// 更新蛇的每一段的运动方向


/// </summary>


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;


}


}




/// <summary>


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


/// </summary>


private void UpdatePosition()


{


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




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));


}


}




/// <summary>


/// 蜕指定数量的皮


/// </summary>


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 辅助方法


/// <summary>


/// 修正指定的位置信息为整数


/// </summary>


private int CorrectPosition(double position)


{


double result;


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




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;


}




/// <summary>


/// 修正蛇的每一段的位置为整数


/// </summary>


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);


}


}




/// <summary>


/// 更新蛇的每一段的网格位置信息


/// </summary>


private void UpdateBodyCell()


{


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


{


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


}


}




/// <summary>


/// 更新指定的 Body 的网格位置信息


/// </summary>


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;


}




/// <summary>


/// 修正网格位置


/// </summary>


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;


}




/// <summary>


/// 获取空网格集合


/// </summary>


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)


return;


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


return;


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


return;


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


return;




_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; }


}


#endregion




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


public event EventHandler GameOver;




public event EventHandler Ate;


#endregion


}


}

OK
[源码下载]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息