WPF游戏-菜鸟版俄罗斯方块.docx
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WPF 游戏 菜鸟 俄罗斯方块
- 资源描述:
-
WPF游戏 菜鸟版俄罗斯方块 时间:2010-09-20 05:42来源:博客园 作者:lipan 点击: 822次 在以前的MFC、winform中实现一个游戏程序是一件相当困难的事情,自从WPF诞生后,富客户端设计工作变得相对简单。本人刚学WPF不久,写写劣质代码望大侠莫见笑。自于这个游戏本身的实现方式我并未去研究,这里只是根据自己的理解来做。 代码下载: 主要思想: 一、提供一个容器 在以前的MFC、winform中实现一个游戏程序是一件相当困难的事情,自从WPF诞生后,富客户端设计工作变得相对简单。本人刚学WPF不久,写写劣质代码望大侠莫见笑。自于这个游戏本身的实现方式我并未去研究,这里只是根据自己的理解来做。 代码下载: 主要思想: 一、提供一个容器类(Container),用来作为方块活动的网格状区域。由于WPF自带Grid控件支持网格,因此就直接利用了。 1.Container类需要关联到Grid,活动区域;和waitingGrid等候区域(下一个出现的方块) 2.在Container类中实现消层的逻辑 二、提供一个方块基类(Box),7中方块全部从其派生。 1.每个方块包含4个Rectangle(小方格) 2.通过一个工厂类随机产生某个方块的实例 3.基类实现方块移动、变形、等逻辑、子类定义方块颜色、初始化方式,确定每个方格相对坐标。 4.在方块下降到底部触发OnBottom事件,Container接受此事件触发消行逻辑。Container类中OnGameover事件被界面层接受处理。 运行效果: 代码部分: Box方块基类 abstract class Box { public Box() { for (int i = 0; i < 4; i++) { rectangles.Add(new Rectangle()); rectangles[i].Width = 24.0; rectangles[i].Height = 24.0; } dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal); dispatcherTimer.Tick += new EventHandler(Timer_Tick); dispatcherTimer.Interval = TimeSpan.FromMilliseconds(450 - Result.GetInstance().Level * 50); } protected Grid grid; /// <summary> /// 定义由四个方格组成的方块 /// </summary> protected IList<Rectangle> rectangles = new List<Rectangle>(4); DispatcherTimer dispatcherTimer; /// <summary> /// 当方块到达底部时触发的事件句柄 /// </summary> public event EventHandler OnBottom; /// <summary> /// 判断x行y列是否包含方格 /// </summary> protected bool Existence(int x, int y) { foreach (var r in grid.Children) { if (r is Rectangle) { if (this.rectangles.Contains(r as Rectangle)) return false; if (Convert.ToInt32((r as Rectangle).GetValue(Grid.ColumnProperty)) == x && Convert.ToInt32((r as Rectangle).GetValue(Grid.RowProperty)) == y) { return true; } } } return false; } /// <summary> /// 当前方块是否与其他方块重叠 /// </summary> public bool ISOverlapping() { foreach (var r in rectangles) { int x = Convert.ToInt32((r as Rectangle).GetValue(Grid.ColumnProperty)); int y = Convert.ToInt32((r as Rectangle).GetValue(Grid.RowProperty)); if (Existence(x, y)) return true; } return false; } /// <summary> /// 判断由数值 x,y标示的行列值是否在Grid范围内 /// </summary> protected bool InGrid(int x, int y) { if (x >= 12 || y >= 24 || x < 0 || y < 0) return false; return true; } /// <summary> /// 定义活动方块自动下降 /// </summary> public void AtuoDown() { dispatcherTimer.Start(); } private void Timer_Tick(object sender, EventArgs e) { if (!MoveDown()) { dispatcherTimer.Stop(); OnBottom(this, null); } } public abstract void Ready(); public abstract void ShowWating(ref Grid WaingGrid); protected bool Move(int _x, int _y) { if (IsPause) return false; for (int i = 0; i < 4; i++) { int x = Convert.ToInt32(rectangles[i].GetValue(Grid.ColumnProperty)) + _x; int y = Convert.ToInt32(rectangles[i].GetValue(Grid.RowProperty)) + _y; if (Existence(x, y)) return false; if (!InGrid(x, y)) return false; } for (int i = 0; i < 4; i++) { rectangles[i].SetValue(Grid.ColumnProperty, Convert.ToInt32(rectangles[i].GetValue(Grid.ColumnProperty)) + _x); rectangles[i].SetValue(Grid.RowProperty, Convert.ToInt32(rectangles[i].GetValue(Grid.RowProperty)) + _y); } return true; } public bool MoveUp() { return Move(0, -1); } public bool MoveDown() { return Move(0, 1); } public bool MoveLeft() { return Move(-1, 0); } public bool MoveRight() { return Move(1, 0); } /// <summary> /// 快速下降 /// </summary> public bool FastDown() { if (IsPause) return false; bool mark = false; int j = 0; while (!mark) { j++; for (int i = 0; i < 4; i++) { int x = Convert.ToInt32(rectangles[i].GetValue(Grid.ColumnProperty)); int y = Convert.ToInt32(rectangles[i].GetValue(Grid.RowProperty)) + j; if (Existence(x, y) || !InGrid(x, y)) { j--; mark = true; } } } for (int i = 0; i < 4; i++) { rectangles[i].SetValue(Grid.RowProperty, Convert.ToInt32(rectangles[i].GetValue(Grid.RowProperty)) + j); } //OnBottom(this, null); return mark; } /// <summary> /// 当前方块是否处于暂停状态 /// </summary> private bool IsPause = false; public void Pause() { dispatcherTimer.IsEnabled = false; IsPause = true; } public void UnPause() { dispatcherTimer.IsEnabled = true; IsPause = false; } public void StopAction() { dispatcherTimer.Stop(); } /// <summary> /// 当前变形状态 /// </summary> protected Status ActivityStatus; /// <summary> /// 变形 /// </summary> public bool ChangeShape() { if (IsPause) return false; IList<Position> P = new List<Position>(4); for (int i = 0; i < 4; i++) P.Add(new Position()); P[0].x = Convert.ToInt32(rectangles[0].GetValue(Grid.ColumnProperty)) + ActivityStatus.NextRelativeposition[0].x; P[0].y = Convert.ToInt32(rectangles[0].GetValue(Grid.RowProperty)) + ActivityStatus.NextRelativeposition[0].y; if (ActivityStatus.NeedCheck[0]) if (Existence(P[0].x, P[0].y) || !InGrid(P[0].x, P[0].y)) return false; P[1].x = Convert.ToInt32(rectangles[1].GetValue(Grid.ColumnProperty)) + ActivityStatus.NextRelativeposition[1].x; P[1].y = Convert.ToInt32(rectangles[1].GetValue(Grid.RowProperty)) + ActivityStatus.NextRelativeposition[1].y; if (ActivityStatus.NeedCheck[1]) if (Existence(P[1].x, P[1].y) || !InGrid(P[1].x, P[1].y)) return false; P[2].x = Convert.ToInt32(rectangles[2].GetValue(Grid.ColumnProperty)) + ActivityStatus.NextRelativeposition[2].x; P[2].y = Convert.ToInt32(rectangles[2].GetValue(Grid.RowProperty)) + ActivityStatus.NextRelativeposition[2].y; if (ActivityStatus.NeedCheck[2]) if (Existence(P[2].x, P[2].y) || !InGrid(P[2].x, P[2].y)) return false; P[3].x = Convert.ToInt32(rectangles[3].GetValue(Grid.ColumnProperty)) + ActivityStatus.NextRelativeposition[3].x; P[3].y = Convert.ToInt32(rectangles[3].GetValue(Grid.RowProperty)) + ActivityStatus.NextRelativeposition[3].y; if (ActivityStatus.NeedCheck[3]) if (Existence(P[3].x, P[3].y) || !InGrid(P[3].x, P[3].y)) return false; for (int i = 0; i < 4; i++) { rectangles[i].SetValue(Grid.ColumnProperty, P[i].x); rectangles[i].SetValue(Grid.RowProperty, P[i].y); } ActivityStatus = ActivityStatus.Next; return true; } } “Z”形方块子类 class Box_Z : Box { public Box_Z(ref Grid grid) { this.grid = grid; for (int i = 0; i < 4; i++) rectangles[i].Fill = new SolidColorBrush(Colors.DarkOrange); } private void ShowAt(Position P, ref Grid grid) { rectangles[0].SetValue(Grid.ColumnProperty, P.x + 0); rectangles[0].SetValue(Grid.RowProperty, P.y + 0); rectangles[1].SetValue(Grid.ColumnProperty, P.x + 1); rectangles[1].SetValue(Grid.RowProperty, P.y + 0); rectangles[2].SetValue(Grid.ColumnProperty, P.x + 1); rectangles[2].SetValue(Grid.RowProperty, P.y + 1); rectangles[3].SetValue(Grid.ColumnProperty, P.x + 2); rectangles[3].SetValue(Grid.RowProperty, P.y + 1); for (int i = 0; i < 4; i++) grid.Children.Add(rectangles[i]); } public override void ShowWating(ref Grid WaingGrid) { ShowAt(new Position(1, 1), ref WaingGrid); } public override void Ready() { ShowAt(new Position(4, 0), ref grid); ActivityStatus = new Status(); ActivityStatus.NextRelativeposition.Add(new Position(1, 2)); ActivityStatus.NextRelativeposition.Add(new Position(0, 1)); ActivityStatus.NextRelativeposition.Add(new Position(1, 0)); ActivityStatus.NextRelativeposition.Add(new Position(0, -1)); ActivityStatus.NeedCheck.Add(true); ActivityStatus.NeedCheck.Add(false); ActivityStatus.NeedCheck.Add(false); ActivityStatus.NeedCheck.Add(true); ActivityStatus.Next = new Status(); ActivityStatus.Next.NextRelativeposition.Add(new Position(-1, -2)); ActivityStatus.Next.NextRelativeposition.Add(new Position(0, -1)); ActivityStatus.Next.NextRelativeposition.Add(new Position(-1, 0)); ActivityStatus.Next.NextRelativeposition.Add(new Position(0, 1)); ActivityStatus.Next.NeedCheck.Add(true); ActivityStatus.Next.NeedCheck.Add(true); ActivityStatus.Next.NeedCheck.Add(false); ActivityStatus.Next.NeedCheck.Add(false); ActivityStatus.Next.Next = ActivityStatus; } } 由于每种方块的变形方式都不一样,Z型有4种状态,I型有2中状态,而O型只有一种状态,现在需要描述方块形状状态,需要定义循环链表数据类型。 定义一个坐标点,描述位置和相对位置 /// <summary> /// 定义一个方格坐标点 /// </summary> class Position { public Position(int x, int y) { this.x = x; this.y = y; } public Position() { } public int x { get; set; } public int y { get; set; } } /// <summary> /// 定义方块形状状态循环链表,标记变形状态 /// </summary> class Status { /// <summary> /// 方格[四个方块]下一次变形将要去的相对位置 /// </summary> public List<Position> NextRelativeposition = new List<Position>(4); /// <summary> /// 是否需要检查方块[每个方格]到这个位置的可行性 /// </summary> public List<bool> NeedCheck = new List<bool>(4); /// <summary> /// 指向下一状态 /// </summary> public Status Next; } 在方块子类中Ready方法即为每种方块设置状态链表。 由于方块的生成为随机方式,定义简单工厂模式生成方块如下: 代码 class BoxFactory { /// <summary> /// 随机方块工厂 /// </summary> static public Box GetRandomBox(ref Grid grid) { //return new Box_Z(ref grid); Random ran = new Random(); int index = ran.Next(7); switch (index) { case 0: return new Box_S(ref grid); case 1: return new Box_Z(ref grid); case 2: return new Box_J(ref grid); case 3: return new Box_L(ref grid); case 4: return new Box_I(ref grid); case 5: return new Box_O(ref grid); case 6: return new Box_T(ref grid); default: return null; } } } 到此为止,方块定义好了,也可以随机产生了,怎么让展示在Grid中? 1.方块子类ShowAt函数标示展示到指定Grid; 2.ShowWating表示展示在等候区域。 当方块展示到容器Grid中时,怎么自动下降呢?这里用到DispatcherTimer。 dispatcherTimer = new DispatcherTimer(DispatcherPriority.Normal); dispatcherTimer.Tick += new EventHandler(Timer_Tick); dispatcherTimer.Interval = TimeSpan.FromMilliseconds(450 - Result.GetInstance().Level * 50); /// <summary> /// 定义活动方块自动下降 /// </summary> public void AtuoDown() { dispatcherTimer.Start(); } private void Timer_Tick(object sender, EventArgs e) { if (!MoveDown()) { dispatcherTimer.Stop(); OnBottom(this, null); } } 当方块到达底部时,事件通知容器类执行消层函数: 在Box中: /// <summary> /// 当方块到达底部时触发的事件句柄 /// </summary> public event EventHandler OnBottom; private void Timer_Tick(object sender, EventArgs e) { if (!MoveDown()) { dispatcherTimer.Stop(); OnBottom(this, null); } } 在Container中: ActivityBox.OnBottom += ActivityBox_OnBottom; /// <summary> /// 活动方块到达底部时触发 /// </summary> static public void ActivityBox_OnBottom(object sender, EventArgs e) { Result.GetInstance().CalculateScore(RemoveLine()); NewBoxReadyToDown(); } RemoveLine消层函数 /// <summary> /// 消层,并返回消除的层数 /// </summary> static int RemoveLine() { if (grid == null) new Exception("缺少活动区域,必须为容器指定grid值。"); int[] lineCount = new int[24]; for (int i = 0; i < 24; i++) lineCount[i] = 0; int RemoveLineCount = 0; //计算每一行方块总数 foreach (var r in grid.Children) { if (r is Rectangle) { int x = Convert.ToInt32((r as Rectangle).GetValue(Grid.RowProperty)); lineCount[x]++; } } for (int i = 23; i >= 0; i--) { if (lineCount[i] >= 12) { //移除一行小方格 for (int j = 0; j < grid.Children.Count; j++)// (var r in mygrid.Children) { if (grid.Children[j] is Recta展开阅读全文
咨信网温馨提示:1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。




WPF游戏-菜鸟版俄罗斯方块.docx



实名认证













自信AI助手
















微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/11739625.html