中国风连连看游戏的设计与实现
2018-10-31商利华
商利华
(无锡城市职业技术学院, 江苏 无锡 214153)
引言
连连看是一款深受大众喜爱的集休闲、趣味、益智精华于一体的经典游戏。目前,各平台上均推出了许多连连看游戏,但游戏的质量参差不齐,游戏模式单一,而且不具有自己的特色。本文使用C#语言和GDI+技术开发一款有亮点、有挑战、有文化、更有美感的连连看游戏。设计中,将中国传统文化的元素融入这款游戏,不仅有精美的画面、别致的特效、而且还有着浓浓的中国传统文化气息蕴蓄其中…。希望玩家在乐享游戏的同时,还能广泛涉猎和感受中华五千年的传统文化的精髓,为弘扬中国传统文化发挥积极有益的推动作用。本文将对此展开如下研究论述。
1 设计思路
中国风连连看游戏规则可描述为:选择一对内容相同的图案进行连线,但此连线不能穿跨其它图案;且连线的转折点不能多于2个,如符合规定则消除此对图案。规则简单、容易上手。这个程序的界面使用了开场的LOGO动画,主程序窗口配置了一个主面板,其中设有2个子面板,左边一层子面板是游戏窗口,符合玩家开启游戏的日常习惯,包含连连看游戏的图片元素,用户进入游戏可找到32对图片;右边一层用来实现游戏控制,有开始、刷新、选择难度、显示分数、进度条等功能选项。为了更突出连连看游戏的休闲、趣味、益智特色,本游戏使用了美观的界面设计和可爱的卡通图片元素,同时加入各种特效效果,如卷首的LOGO动画、主菜单按钮漂浮浮动效果、场景切换效果、卷轴展开效果和方块消除效果等,部分效果呈现则如图1所示。
2 游戏实现
2.1 公共类设计
本游戏主要研发了6大公共类,分别是:全局帮助、特效效果、保存数据的模型、游戏状态、自定义控件和控制类。这里,针对每一类的功能设计可做阐释解析如下。
(1)全局帮助。共有3个类。总地来说,LLK_Global类是常量和常用方法。ImageProcess类是图片旋转/翻转方法。IniOperation类是读写ini文件的ini操作类。
图1 中图风连连看游戏效果界面
(2)特效效果。重点设计了方块清除特效、场景切换动画和游戏开场卷轴动画的类。
(3)模型。用于存放连连看方块地图、游戏关卡记录和配置类。
(4)游戏状态类。该类中有基类LLK_GameStatus,每个状态都继承LLK_GameStatus类。在各自状态类中管理本状态上的控件和界面。
(5)自定义控件。这是自定义控件的一类。LLK_KongJian是所有自定义控件的基类,定义了所有控件共有的属性和方法。LLK_Window继承Form类,搭建了整个游戏的框架,是游戏的窗口类。
(6)控制类。是计时类、方块控制类和背景音乐播放类的集成。其中,计时类可用于游戏时间计时和连击时间计时,主要通过线程设计来实现。方块控制类可用于游戏方块的消除判定、道具使用后的操作(如提示、消一对和重新排列)。背景音乐播放类则用于控制游戏背景音乐的播放。
2.2 特效类设计
本款游戏的主题特色就是将中国传统文化的元素融入连连看游戏,为了达到这一设计主旨,研究中特别设计了3个特效类。为此,本文将专门给出研究分述可见如下。
2.2.1GuoChangDongHua类
GuoChangDongHua类实现的是状态场景切换时的从左到右变黑的效果。是向整个窗口填充矩形,颜色从左到右透明度越来越低,而且有一张不规则边缘图片画在黑边上,以获得良好的美工效果。该类的设计效果如图2所示。 参考代码可详见如下。
图2 GuoChangDongHua类的设计效果界面
classGuoChangDongHua
{// 延迟时间
private const intSLEEPTIME= 16;
// 动画显示总时间
private const intALLTIME= 800;
// 线程
privateThreadthreadChange;
// 游戏窗口
privateLLK_WindowparantWindow;
// 是否改变游戏状态
private boolisChangeGameStatus=false;
// 当前动画百分比
private floatp= 0;
//边缘图片private Image imageShuTiao;
privateSemaphoresemImg= newSemaphore(1, 1);privateinttoStatus;
public boolIsChangeGameStatus
{get { returnthis.isChangeGameStatus; }}
publicGuoChangDongHua(LLK_WindowparantWindow, inttoStatus)
{this.parantWindow=parantWindow;
this.toStatus=toStatus;
threadChange=new Thread(run);
threadChange.Start();} // 线程执行的方法
public voidrun()
{Randomr=newRandom();// 载入图片
imageShuTiao=Image.FromFile(LLK_Global.PATH_RESOURCE_IMAGES + "shutiao.png");
// 总共需要的循环次
intcount=ALLTIME/SLEEPTIME;
for (inti= 0;i {p=(float)i/(count-20); // 计算出当前动画百分比 parantWindow.Invalidate();// 窗口重绘 Thread.Sleep(SLEEPTIME); // 延时} isChangeGameStatus=true; // 更改状态标志 parantWindow.GameStatus=this.toStatus; // 改为游戏状态} public voidshow(Graphicsg) // 显示 {intalpha=100+(int)(155 *p); // 计算透明度 if (alpha>255) {alpha=255; } else if(alpha<0) {alpha=0; } Brushb=newSolidBrush(Color.FromArgb(alpha, 0, 0, 0)); // 画笔 g.FillRectangle(b,newRectangleF(0, 0,LLK_Global.WINDOW_WIDTH*p,LLK_Global.WINDOW_HEIGHT)); // 填充半透明 b.Dispose();// 画边缘图片 semImg.WaitOne(); if (imageShuTiao!=null) {g.DrawImage(imageShuTiao,newPoint((int) (LLK_Global.WINDOW_WIDTH*p)-4, 0)); } semImg.Release();} public voidDispose() {threadChange.Abort(); semImg.WaitOne(); imageShuTiao.Dispose(); imageShuTiao=null; semImg.Release();}} 2.2.2ClearEffect类 ClearEffect类是连连看方块消除特效类,可实现2个方块之间路径动画以及墨汁爆开特效。该类中有一个List类型变量,存储正处于特效生成中的路径,此后若还有请求特效的新路径需要加入,就一并添加到该List类型变量中。此外,该类中还有一个线程,且自游戏启动时就开始运行,经过一定时间就绘制一次特效,由此即可实现路径动画。而当路径中所有点都绘制完毕后将继以描画墨汁爆开图片,再将该路径从List变量中移除。ClearEffect类的设计效果如图3所示。效果预览代码可详见如下。 图3 ClearEffect类的设计效果界面 public voidthreadDo()// 特效线程 { inti; while (true) {sem.WaitOne(); boolishave= false; // 遍历所有特效点 for(i=this.effectPointDataList.Count- 1;i>= 0;i--) {// 判断当前点是否是最后一个 if (this.effectPointDataList[i].Index>=this.effectPointDataList[i].PList.Count- 1) {// 判断是否还有剩余显示时间 if (this.effectPointDataList[i].Sleep<= 0) {this.effectPointDataList[i].Index= -1; gs.removeKongjian("gameBlock" +this.effectPointDataList[i].PList[0].X+ "," +this.effectPointDataList[i].PList[0].Y,false); gs.removeKongjian("gameBlock" +this.effectPointDataList[i].PList[this.effectPointDataList[i].PList.Count- 1].X+ "," +this.effectPointDataList[i].PList[this.effectPointDataList[i].PList.Count- 1].Y, false); ishave= true; }} else if (this.effectPointDataList[i].Index>= 0) {this.effectPointDataList[i].Index++; // 索引加1 ishave= true; } else if (this.effectPointDataList[i].Sleep<= -20 *LLK_Global.EFFECT_POINT_SLEEP) {this.effectPointDataList.RemoveAt(i); // 将该组特效点移除 ishave= true; continue; } this.effectPointDataList[i].Sleep-=LLK_Global.EFFECT_POINT_SLEEP; }// 减去时间 sem.Release();// 游戏窗口重绘 if (ishave) {isRefresh= true;window.Invalidate();} Thread.Sleep(LLK_Global.EFFECT_POINT_SLEEP); }}// 延时 2.2.3ReelEffect类 ReelEffect类是开始游戏前卷轴展开动画类。先给卷轴展开限定一个时间,然后在线程中每经过一定时间就根据当前时间和总时间比例绘制卷轴部分宽度。ReelEffect类的设计效果如图4所示。效果预览代码可详见如下。 private voidreelEffect()// 卷轴特效线程 {this.isEffect= true;p= 0; intt=Environment.TickCount; window.Invalidate();sem.WaitOne(); while (p<=100) {p= (Environment.TickCount-t) / 10*0.5; sem.Release();window.Invalidate(); 图4 ReelEffect类的设计效果界面 isRefresh= true; Thread.Sleep(10); sem.WaitOne();} sem.Release(); ((LLK_Gaming)gameStatus).init(); this.isEffect= false; } public voidshow(Graphicsg) {semImg.WaitOne(); if (cache!= null) {if (this.isEffect&&isRefresh) {isRefresh= false; Graphicsg1 =Graphics.FromImage(cache); g1.Clear(Color.Transparent); intx1,y= 0,x2 = 0,width= 0; sem.WaitOne(); x1 = (int)(left* (100 -p) / 100) + 4; if (imgReel!= null) {x2 = (int)(left+imgReel.Width+left*p/ 100) - 4; y= (int)((LLK_Global.WINDOW_HEIGHT-imgReel.Height) / 2); width=x2 - (x1 +imgReel.Width) + 8; } sem.Release(); if (imgReelPaper!=null) {g1.DrawImage(imgReelPaper,newRectangle(x1 +imgReel.Width- 4,y+ 40,x2 - (x1 +imgReel.Width) + 8,imgReelPaper.Height)); } if (imgReelBg!= null) {g1.DrawImage(imgReelBg,x1 +imgReel.Width- 4,y+ 80, newRectangleF((imgReelBg.Width-width) / 2, 0,width,imgReelBg.Height),GraphicsUnit.Pixel); } if (imgReel!= null) {g1.DrawImage(imgReel,x1,y); g1.DrawImage(imgReel,x2,y); } g1.Dispose();} g.DrawImageUnscaled(cache, 0, 0); } semImg.Release();} 主菜单界面,可以选择开始游戏、游戏设置、游戏帮助和退出游戏。对此设计,可具体阐释如下。 首先是在Graphics上描绘一张背景图片。然后创建主菜单按钮LLK_MainMenuButton类继承图片按钮LLK_ImageButton类,来完成主菜单按钮设计。在LLK_MainMenuButton被创建时就启动一个线程。该线程用于实现鼠标移入和移出按钮时的下拉/上拉效果和通常状态时的自由浮动效果的数据变动。 如下拉/上拉时有一个高度变量,根据当前鼠标是否在按钮范围内进行加长和缩短,来设计实现上拉/下拉动画效果设计。在自由浮动时,随机选取按钮邻近一定范围内的坐标点,计算出按照像素移动的路径。记下路径点,每次绘制时绘制下一个坐标点,以此来获得流畅的自由浮动效果。 本文开发的中国风特色连连看游戏除实现基本功能外,还设置了诸多特效效果,如开首的LOGO动画、主菜单按钮漂浮浮动效果、场景切换效果、卷轴展开效果和方块消除效果等,除增加画面感和趣味性以外,还涉及到了图形界面的显示与更新、数据的收集与更新等,对开发类似的GDI+游戏有很好的借鉴作用。2.3 主菜单设计
3 结束语