基于C# WPF框架的贪吃蛇
游戏开始界面
游戏开始
共有两条蛇,吃到红色食物加1分,吃到绿色毒食物减1分,知道0不减;
碰到墙壁游戏结束,碰到对方游戏结束,碰到自己游戏结束
此游戏通过canvas画布布局,通过c#代码实现
游戏主界面大小为1200*1000
<window x:class="贪吃蛇__.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:贪吃蛇__" mc:ignorable="d" title="贪吃蛇" loaded="window_loaded" height="700" width="900"> <canvas name="bg" width = "1200" height = "1000"></canvas> </window>
全局声明:
random ran = new random();// 随机对象 int size = 20; // 边框距离bg距离,格子数 canvas gamearea = new canvas(); // 游戏区对象 border food = new border(); //食物对象 border dufood = new border(); // 毒食物对象 list<border> snakelist1 = new list<border>(); // 存储蛇1的泛型 list<border> snakelist2 = new list<border>(); // 存储蛇2的泛型 dispatchertimer movetimer1 = new dispatchertimer(); // 蛇1移动定时器 dispatchertimer movetimer2 = new dispatchertimer(); // 蛇2移动定时器 soundplayer eatfm = new soundplayer(@"../../music/eatfood.wav"); // 吃食物音乐 soundplayer eatdufm = new soundplayer(@"../../music/eatdufood.wav");// 吃毒食物音乐 soundplayer overm = new soundplayer(@"../../music/over.wav"); // 游戏结束音乐 soundplayer bgm = new soundplayer(@"../../music/bgmusic.wav"); // 背景音乐 int score = 0; //记录分数 label feng = new label(); // 分数对象 bool pand = true; // 游戏开始和暂停判断
加载事件:
private void window_loaded(object sender, routedeventargs e) { this.background = brushes.cyan; this.windowstate = windowstate.maximized; // 屏幕最大化 bg.background = new lineargradientbrush(colors.yellow, colors.pink, 10); // 边框 border biankuang = new border(); biankuang.width = 1040; biankuang.height = 840; canvas.setleft(biankuang, size); canvas.settop(biankuang, size); biankuang.borderthickness = new thickness(20); // 边框厚度 biankuang.cornerradius = new cornerradius(10); // 画圆 biankuang.borderbrush = brushes.green; bg.children.add(biankuang); image map = new image(); map.source = new bitmapimage(new uri("../../img/bgimg.png",urikind.relative)); imagebrush mp = new imagebrush(); mp.imagesource = map.source; // 显示图片 // 游戏区 gamearea.width = 1000; gamearea.height = 800; gamearea.background = mp; mp.stretch = stretch.fill; canvas.setleft(gamearea, 2 * size); canvas.settop(gamearea, 2 * size); bg.children.add(gamearea); // 得分对象 feng.width = 120; feng.height = 50; canvas.setleft(feng, 1060); canvas.settop(feng, 100); feng.background = brushes.coral; feng.foreground = brushes.deepskyblue; feng.fontfamily = new fontfamily("楷体"); feng.content = " 得分:" + score + "分"; feng.fontsize = 20; bg.children.add(feng); // 蛇1移动定时器 movetimer1.tick += movetimer1_tick; ; movetimer1.interval = timespan.frommilliseconds(100); // 蛇2移动定时器 movetimer2.tick += movetimer2_tick; movetimer2.interval = timespan.frommilliseconds(100); // 开始按钮 button kaise = new button(); kaise.cursor = cursors.hand; // 鼠标移动到按钮处变成手型 kaise.width = 120; kaise.height = 50; canvas.setleft(kaise, 1060); canvas.settop(kaise, 160); kaise.content = "开始游戏"; kaise.fontfamily = new fontfamily("楷体"); kaise.borderbrush = brushes.cyan; // 边框颜色 kaise.foreground = brushes.darkred; // 字体颜色 kaise.fontsize = 20; kaise.background = brushes.darkkhaki; kaise.click += kaise_click; bg.children.add(kaise); // 暂停按钮 button zanting = new button(); zanting.cursor = cursors.hand; // 鼠标移动到按钮处变为手型 zanting.width = 120; zanting.height = 50; canvas.setleft(zanting, 1060); canvas.settop(zanting, 220); zanting.content = "暂停游戏"; zanting.fontfamily = new fontfamily("楷体"); zanting.borderbrush = brushes.cyan; zanting.foreground = brushes.darkred; zanting.fontsize = 20; zanting.background = brushes.burlywood; zanting.click += zanting_click; bg.children.add(zanting); // 背景音乐播放 bgm.play(); }
开启游戏按钮
// 开启游戏 private void kaise_click(object sender, routedeventargs e) { bgm.stop(); // 背景音乐停止 this.keydown += mainwindow_keydown; if (pand == true) { createsnake1(); // 生成蛇1方法 createsnake2(); // 生成蛇2方法 createfood(); // 生成食物 createdufood();// 生成毒食物 } movetimer1.start(); // 蛇1移动 movetimer2.start();// 蛇2移动 pand = false; }
暂停按钮
// 暂停游戏 private void zanting_click(object sender, routedeventargs e) { this.keydown -= mainwindow_keydown; movetimer1.stop(); // 蛇1移动 movetimer2.stop();// 蛇2移动 pand = false; }
创建食物方法:
// 创建食物 private void createfood() { food.width = food.height = size; food.background = brushes.red; food.cornerradius = new cornerradius(20); canvas.setleft(food, ran.next(1, 50) * size); canvas.settop(food, ran.next(1, 40) * size); // 判断食物在蛇位置上 for (int i = 0; i < snakelist1.count; i++) { for (int j = 0; j < snakelist2.count; j++) { if (canvas.getleft(food)==canvas.getleft(snakelist1[i])&&canvas.gettop(food)==canvas.gettop(snakelist1[i])||canvas.getleft(food)==canvas.getleft(snakelist2[j])&&canvas.gettop(food)==canvas.gettop(snakelist2[j])) { canvas.setleft(food, ran.next(1, 50) * size); canvas.settop(food, ran.next(1, 40) * size); } } } gamearea.children.add(food); }
创建毒食物方法:
// 创建毒食物 private void createdufood() { dufood.width = dufood.height = size; dufood.background = brushes.greenyellow; dufood.cornerradius = new cornerradius(20); canvas.setleft(dufood, ran.next(1, 50) * size); canvas.settop(dufood, ran.next(1, 40) * size); // 毒食物与食物位置重合 if (canvas.getleft(dufood)==canvas.getleft(food)&&canvas.gettop(dufood)==canvas.gettop(food)) { canvas.setleft(dufood, ran.next(1, 50) * size); canvas.settop(dufood, ran.next(1, 40) * size); } // 毒食物在蛇身上 for (int i = 0; i < snakelist1.count; i++) { for (int j = 0; j < snakelist2.count; j++) { if (canvas.getleft(dufood) == canvas.getleft(snakelist1[i]) && canvas.gettop(dufood) == canvas.gettop(snakelist1[i]) || canvas.getleft(dufood) == canvas.getleft(snakelist2[j]) && canvas.gettop(dufood) == canvas.gettop(snakelist2[j])) { canvas.setleft(dufood, ran.next(1, 50) * size); canvas.settop(dufood, ran.next(1, 40) * size); } } } gamearea.children.add(dufood); }
蛇1创建方法:
// 创建蛇1方法 private void createsnake1() { int lenght = 4; // 默认蛇长度 for (int i = 0; i < lenght; i++) { border sna1 = new border(); // 蛇对象 sna1.width = sna1.height = size; // 蛇宽度,高度 sna1.tag = "right";// 默认方法存储到tag中 if (i == 0) { sna1.background = brushes.thistle; } else { sna1.background = brushes.purple; } canvas.setleft(sna1, gamearea.width / 2 - (size * i)); canvas.settop(sna1, gamearea.height / 2); sna1.cornerradius = new cornerradius(20); gamearea.children.add(sna1); snakelist1.add(sna1); } }
蛇2创建方法:
// 创建蛇2方法 private void createsnake2() { int length = 4; for (int i = 0; i < length; i++) { border sna2 = new border(); sna2.width = sna2.height = size; sna2.tag = "left"; if (i == 0) { sna2.background = brushes.thistle; } else { sna2.background = brushes.orange; } sna2.cornerradius = new cornerradius(20); canvas.setleft(sna2, gamearea.width / 2 + (i * size)); canvas.settop(sna2, gamearea.width / 2); gamearea.children.add(sna2); snakelist2.add(sna2); } }
蛇1移动
// 蛇1移动定时器 private void movetimer1_tick(object sender, eventargs e) { for (int i = 0; i < snakelist1.count; i++) { if (snakelist1[i].tag.tostring() == "right") // 向右移动 { canvas.setleft(snakelist1[i], canvas.getleft(snakelist1[i]) + size); } else if (snakelist1[i].tag.tostring() == "left") // 向左移动 { canvas.setleft(snakelist1[i], canvas.getleft(snakelist1[i]) - size); } else if (snakelist1[i].tag.tostring() == "up") // 向上移动 { canvas.settop(snakelist1[i], canvas.gettop(snakelist1[i]) - size); } else if (snakelist1[i].tag.tostring() == "down") // 向下移动 { canvas.settop(snakelist1[i], canvas.gettop(snakelist1[i]) + size); } } for (int i = snakelist1.count - 1; i > 0; i--) { // 蛇身跟随蛇头,占蛇头位置 snakelist1[i].tag = snakelist1[i - 1].tag; } // 蛇碰到墙 if (canvas.gettop(snakelist1[0]) <= -1 || canvas.gettop(snakelist1[0]) == gamearea.height || canvas.getleft(snakelist1[0]) <= -1 || canvas.getleft(snakelist1[0]) == gamearea.width) { gameover(); } // 蛇1碰到蛇2 for (int x = 0; x < snakelist2.count; x++) { if (canvas.getleft(snakelist1[0]) == canvas.getleft(snakelist2[x]) && canvas.gettop(snakelist1[0]) == canvas.gettop(snakelist2[x])) { gameover(); } } // 吃到食物 if ( snakelist1.count>0&&canvas.gettop(snakelist1[0]) == canvas.gettop(food) && canvas.getleft(snakelist1[0]) == canvas.getleft(food)) { gamearea.children.remove(food); //删除吃的食物 createfood(); // 重新创建食物 eatfm.play(); // 吃食物的音乐 //新创建的蛇身 border slimuse = new border();//增添蛇身 slimuse.width = slimuse.height = size; slimuse.tag = " "; slimuse.background = brushes.purple; slimuse.cornerradius = new cornerradius(20); // 变圆 canvas.setleft(slimuse, canvas.getleft(snakelist1[snakelist1.count - 1])); // 获取到蛇尾的left位置 canvas.settop(slimuse, canvas.gettop(snakelist1[snakelist1.count - 1])); // 获取到蛇尾的top位置 gamearea.children.add(slimuse); snakelist1.add(slimuse); score++; feng.content = " 得分:" + score + "分"; } //吃到毒食物 if (snakelist1.count > 0 && canvas.gettop(snakelist1[0]) == canvas.gettop(dufood) && canvas.getleft(snakelist1[0]) == canvas.getleft(dufood)) { eatdufm.play(); // 吃毒食物音乐 gamearea.children.remove(dufood);// 删掉吃的毒食物 createdufood(); // 重新创建毒食物 if (score > 0) { score--; feng.content = " 得分:" + score + "分"; } gamearea.children.remove(snakelist1[snakelist1.count - 1]); // 清除蛇身最后一节 snakelist1.remove(snakelist1[snakelist1.count - 1]); // 清除集合最后一节 } // 蛇头碰到蛇身体 for (int i = 1; i < snakelist1.count; i++) { // 蛇头碰到蛇身 if (canvas.gettop(snakelist1[0]) == canvas.gettop(snakelist1[i]) && canvas.getleft(snakelist1[0]) == canvas.getleft(snakelist1[i])) { gameover(); } } }
蛇2移动
// 蛇2移动定时器 private void movetimer2_tick(object sender, eventargs e) { for (int i = 0; i < snakelist2.count; i++) { if (snakelist2[i].tag.tostring() == "left") // 向左移动 { canvas.setleft(snakelist2[i], canvas.getleft(snakelist2[i]) - size); } else if (snakelist2[i].tag.tostring() == "right") // 向右移动 { canvas.setleft(snakelist2[i], canvas.getleft(snakelist2[i]) + size); } else if (snakelist2[i].tag.tostring() == "up") // 向上 { canvas.settop(snakelist2[i], canvas.gettop(snakelist2[i]) - size); } else if (snakelist2[i].tag.tostring() == "down") // 向下 { canvas.settop(snakelist2[i], canvas.gettop(snakelist2[i]) + size); } } for (int i = snakelist2.count - 1; i > 0; i--) { // 蛇身跟随蛇头移动 snakelist2[i].tag = snakelist2[i - 1].tag; } // 蛇2碰到墙 if (canvas.getleft(snakelist2[0]) <= -1 || canvas.getleft(snakelist2[0]) >= gamearea.width || canvas.gettop(snakelist2[0]) <= -1 || canvas.gettop(snakelist2[0]) >= gamearea.height) { gameover();// 调用游戏结束方法 } // 蛇2碰到蛇1 for (int x = 0; x < snakelist1.count; x++) { if (canvas.getleft(snakelist2[0]) == canvas.getleft(snakelist1[x]) && canvas.gettop(snakelist2[0]) == canvas.gettop(snakelist1[x])) { gameover();// 调用游戏结束方法 } } // 吃到食物 if (snakelist2.count>0&& canvas.getleft(snakelist2[0]) == canvas.getleft(food) && canvas.gettop(snakelist2[0]) == canvas.gettop(food)) { gamearea.children.remove(food); // 删除食物 createfood(); // 创建新食物 eatfm.play();// 吃食物音乐 border slom = new border();// 添加的蛇身 创建新蛇身 slom.tag = " "; slom.width = slom.height = size; slom.background = brushes.orange; slom.cornerradius = new cornerradius(20); canvas.setleft(slom, canvas.getleft(snakelist2[snakelist2.count - 1])); canvas.settop(slom, canvas.gettop(snakelist2[snakelist2.count - 1])); snakelist2.add(slom); gamearea.children.add(slom); score++; feng.content = " 得分:" + score + "分"; } // 吃到毒食物 if (snakelist2.count > 0&&canvas.getleft(snakelist2[0])==canvas.getleft(dufood)&&canvas.gettop(snakelist2[0])==canvas.gettop(dufood)) { eatdufm.play(); // 吃毒食物音乐 gamearea.children.remove(dufood); // 消除毒食物 createdufood(); // 创建新毒食物 if (score>0) { score--; feng.content = " 得分:" + score + "分"; } gamearea.children.remove(snakelist2[snakelist2.count - 1]); snakelist2.remove(snakelist2[snakelist2.count - 1]); } // 蛇头碰到蛇身 for (int i = 1; i < snakelist2.count; i++) { if (canvas.getleft(snakelist2[0]) == canvas.getleft(snakelist2[i]) && canvas.gettop(snakelist2[0]) == canvas.gettop(snakelist2[i])) { gameover();// 调用游戏结束方法 } } }
游戏结束方法:
// 游戏结束方法 private void gameover() { this.keydown -= mainwindow_keydown; movetimer1.stop(); movetimer2.stop(); gamearea.children.clear(); // 清除游戏区子级 // overm.play(); // 游戏结束音乐 messageboxresult out = messagebox.show("游戏结束,得分为:" + score + ",是否重新开始游戏", "游戏结束", messageboxbutton.yesno, messageboximage.asterisk); if (out == messageboxresult.yes) { snakelist1.clear(); // 清除存储蛇1的泛型 snakelist2.clear(); // 清除存储蛇2的泛型 pand = true; score = 0; feng.content = " 得分:" + score + "分"; } else { this.close(); } }
##### 键盘事件csharp // 键盘事件 private void mainwindow_keydown(object sender, keyeventargs e) { switch (e.key) { case key.left: snakelist1[0].tag = "left"; break; case key.right: snakelist1[0].tag = "right"; break; case key.up: snakelist1[0].tag = "up"; break; case key.down: snakelist1[0].tag = "down"; break; case key.a: snakelist2[0].tag = "left"; break; case key.d: snakelist2[0].tag = "right"; break; case key.w: snakelist2[0].tag = "up"; break; case key.s: snakelist2[0].tag = "down"; break; default: break; } }