前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小游戏——js+h5[canvas]+cs3制作【五子棋】小游戏

小游戏——js+h5[canvas]+cs3制作【五子棋】小游戏

作者头像
xing.org1^
发布2018-05-17 16:17:59
3.6K0
发布2018-05-17 16:17:59
举报
文章被收录于专栏:前端说吧前端说吧

五子棋小游戏学习——

有一个问题是,棋盘线的颜色,在canvas中,明明设置了灰色,但在我的预览中还是黑色的,很重的颜色。

以下是复刻的源码:

代码语言:javascript
复制
  1 <!DOCTYPE html>
  2 <html>
  3 
  4     <head>
  5         <meta charset="UTF-8">
  6         <title>五子棋游戏</title>
  7         <meta name="Description" content="git上看到的一个很值得学习练习的简易h5+js制作的小游戏,很久没有摸键盘码代码了,刚好拿来练练手。" />
  8         <style type="text/css">
  9             canvas {
 10                 display: block;
 11                 margin: 50px auto;
 12                 -webkit-box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
 13                 box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
 14                 cursor: pointer;
 15             }
 16             
 17             .btn_wrap {
 18                 display: flex;
 19                 flex-direction: row;
 20                 justify-content: center;
 21             }
 22             
 23             .btn_wrap div {
 24                 margin: 0 10px;
 25             }
 26             
 27             div>span {
 28                 display: inline-block;
 29                 padding: 10px 20px;
 30                 color: #FFF;
 31                 background: #ee82ee;
 32                 -webkit-border-radius: 5px;
 33                 -moz-border-radius: 5px;
 34                 border-radius: 5px;
 35                 cursor: pointer;
 36             }
 37             
 38             div.unable span {
 39                 background: #d6d6d4;
 40                 color: #adacaa;
 41             }
 42             
 43             #result-wrap {
 44                 text-align: center;
 45             }
 46         </style>
 47     </head>
 48 
 49     <body>
 50         <h3 id="result-wrap">--五子棋游戏--</h3>
 51         <canvas id="chess" width="450px" height="450px"></canvas>
 52         <div class="btn_wrap">
 53             <div id="restart" class="restart">
 54                 <span>重新开始</span>
 55             </div>
 56             <div id="goback" class="goback unable">
 57                 <span>悔棋</span>
 58             </div>
 59             <div id="return" class="return unable">
 60                 <span>
 61                     撤销悔棋
 62                 </span>
 63             </div>
 64         </div>
 65         <a href="https://github.com/wj704/wj704.github.io/blob/master/five_game.html">原文地址</a>
 66     </body>
 67     <script type="text/javascript">
 68         var over = false;
 69         var me = true; //我
 70         var _nowi = 0,
 71             _nowj = 0;
 72         var _compi = 0,
 73             _compj = 0;
 74         var _myWin = [],
 75             _compWin = [];
 76         var backAble = false,
 77             returnAble = false;
 78         var resultTxt = document.getElementById('result-wrap');
 79 
 80         var chressBord = [];
 81         for(var i = 0; i < 15; i++) {
 82             chressBord[i] = [];
 83             for(var j = 0; j < 15; j++) {
 84                 chressBord[i][j] = 0;
 85             }
 86         }
 87 
 88         //赢法的统计数组
 89         var myWin = [];
 90         var computerWin = [];
 91 
 92         //赢法数组
 93         var wins = [];
 94         for(var i = 0; i < 15; i++) {
 95             wins[i] = [];
 96             for(var j = 0; j < 15; j++) {
 97                 wins[i][j] = [];
 98             }
 99         }
100 
101         var count = 0; //赢法总数
102         //横线赢法
103         for(var i = 0; i < 15; i++) {
104             for(var j = 0; j < 11; j++) {
105                 for(var k = 0; k < 5; k++) {
106                     wins[i][j + k][count] = true;
107                 }
108                 count++;
109             }
110         }
111 
112         //竖线赢法
113         for(var i = 0; i < 15; i++) {
114             for(var j = 0; j < 11; j++) {
115                 for(var k = 0; k < 5; k++) {
116                     wins[j + k][i][count] = true;
117                 }
118                 count++;
119             }
120         }
121 
122         //正斜线赢法
123         for(var i = 0; i < 11; i++) {
124             for(var j = 0; j < 11; j++) {
125                 for(var k = 0; k < 5; k++) {
126                     wins[i + k][j + k][count] = true;
127                 }
128                 count++;
129             }
130         }
131 
132         //反斜线赢法
133         for(var i = 0; i < 11; i++) {
134             for(var j = 14; j > 3; j--) {
135                 for(var k = 0; k < 5; k++) {
136                     wins[i + k][j - k][count] = true;
137                 }
138                 count++;
139             }
140         }
141 
142         //debugger
143         for(var i = 0; i < count; i++) {
144             myWin[i] = 0;
145             _myWin[i] = 0;
146             computerWin[i] = 0;
147             _compWin[i] = 0;
148         }
149         var chess = document.getElementById('chess');
150         var context = chess.getContext('2d')
151         context.storkeStyle = '#bfbfbf'; //边框颜色
152         var backbtn = document.getElementById('goback');
153         var returnbtn = document.getElementById('return');
154         window.onload = function() {
155             drawChessBoard();
156         }
157 
158         document.getElementById('restart').onclick = function() {
159             window.location.reload();
160         }
161         //我,下棋
162         chess.onclick = function(e) {
163             if(over) {
164                 return;
165             }
166             if(!me) {
167                 return;
168             }
169             //悔棋功能可用
170             backbtn.className = backbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
171             var x = e.offsetX;
172             var y = e.offsetY;
173             var i = Math.floor(x / 30);
174             var j = Math.floor(y / 30);
175             _nowi = i;
176             _nowj = j;
177             if(chressBord[i][j] == 0) {
178                 oneStep(i, j, me);
179                 chressBord[i][j] = 1; //我,已占位置
180                 for(var k = 0; k < count; k++) { //将可能赢的情况都加1
181                     if(wins[i][j][k]) {
182                         //debugger
183                         myWin[k]++;
184                         _compWin[k] = computerWin[k];
185                         computerWin[k] = 6; //这个位置对方不可能赢了
186                         if(myWin[k] == 5) {
187                             //window.alert('你赢了');
188                             resultTxt.innerHTML = '恭喜,你赢了!';
189                             over = true;
190                         }
191                     }
192                 }
193                 if(!over) {
194                     me = !me;
195                     computerAI();
196                 }
197             }
198         }
199 
200         //悔棋
201         backbtn.onclick = function(e) {
202             if(!backAble) {
203                 return;
204             }
205             over = false;
206             me = true;
207             //resultTxt.innerHTMl = "(⊙o⊙),悔棋中";
208             //撤销悔棋功能可用
209             returnbtn.className = returnbtn.className.replace(new RgeExp("(\\s|^)unable(\\s|$)"), " ");
210             //我,悔棋
211             chressBord[_nowi][_nowj] = 0; //我,已占位置 还原
212             minusStep(_nowi, _nowj); //销毁棋子
213             for(var k = 0; k < count; k++) { //将可能赢得情况都减1
214                 if(wins[_nowi][_nowj][k]) {
215                     myWin[k]--;
216                     computerWin[k] = _compWin[k]; //这个位置对方可能赢
217                 }
218             }
219 
220             //计算机相应的悔棋
221             chressBord[_compi][_compj] = 0; //计算机,已占位置 还原
222             minusStep(_compi, _compj); //销毁棋子
223             for(var k = 0; k < count; k++) {
224                 if(wins[_compi][_compj][k]) {
225                     computerWin[k]--;
226                     myWin[k] = _myWin[i]; //这个位置对方可能赢
227                 }
228             }
229             resultTxt.innerHTML = "--益智五子棋--";
230             returnAble = true;
231             backAble = false;
232         }
233 
234         //撤销悔棋
235         returnbtn.onclick = function(e) {
236             if(!returnAble) {
237                 return;
238             }
239             //我,撤销悔棋
240             chressBord[_nowi][_nowj] = 1; //我,已占位置
241             oneStep(_nowi, _nowj, me);
242             for(var k = 0; k < count; k++) {
243 
244                 if(wins[_nowi][_nowj][k]) {
245                     myWin[k]++;
246                     _compWin[k] = computerWin[k];
247                     computerWin[k] = 6; //这个位置对方不可能赢
248                 }
249                 if(myWin[k] == 5) {
250                     resultTxt.innerHTML = '恭喜,你赢了!';
251                     over = true;
252                 }
253             }
254 
255             //计算机撤销相应的悔棋
256             chressBord[_compi][_compj] = 2; //计算机,已占位置
257             oneStep(_compi, _compj, false);
258             for(var k = 0; k < count; k++) { //将可能赢得情况减一
259                 if(wins[_compi][_compj][k]) {
260                     computerWin[k]++;
261                     _myWin[k] = myWin[k];
262                     myWin[k] = 6; //这个位置对方不可能赢
263                 }
264                 if(computerWin[k] == 5) {
265                     resultTxt.innerHTML = "┗|`O′|┛ 嗷~~,计算机赢了,继续加油!";
266                     over = true;
267                 }
268             }
269             returnbtn.className += " " + "unable";
270             returnAble = false;
271             backAble = true;
272         }
273 
274         //计算机下棋
275         var computerAI = function() {
276             var myScore = [];
277             var computerScore = [];
278             var max = 0;
279             var u = 0,
280                 v = 0;
281             for(var i = 0; i < 15; i++) {
282                 myScore[i] = [];
283                 computerScore[i] = [];
284                 for(var j = 0; j < 15; j++) {
285                     myScore[i][j] = 0;
286                     computerScore[i][j] = 0;
287                 }
288             }
289             for(var i = 0; i < 15; i++) {
290                 for(var j = 0; j < 15; j++) {
291                     if(chressBord[i][j] == 0) {
292                         for(var k = 0; k < count; k++) {
293                             if(wins[i][j][k]) {
294 
295                                 if(myWin[k] == 1) {
296                                     myScore[i][j] += 200;
297                                 } else if(myWin[k] == 2) {
298                                     myScore[i][j] += 400;
299                                 } else if(myWin[k] == 3) {
300                                     myScore[i][j] += 2000;
301                                 } else if(myWin[k] == 4) {
302                                     myScore[i][j] += 10000;
303                                 }
304 
305                                 if(computerWin[k] == 1) {
306                                     computerScore[i][j] += 220;
307                                 } else if(computerWin[k] == 2) {
308                                     computerScore[i][j] += 420;
309                                 } else if(computerWin[k] == 3) {
310                                     computerScore[i][j] += 2100;
311                                 } else if(computerWin[k] == 4) {
312                                     computerScore[i][j] += 20000;
313                                 }
314                             }
315                         }
316                         if(myScore[i][j] > max) {
317                             max = myScore[i][j];
318                             u = i;
319                             v = j;
320                         } else if(myScore[i][j] == max) {
321                             if(computerScore[i][j] > computerScore[u][v]) {
322                                 u = i;
323                                 v = j;
324                             }
325                         }
326                         if(computerScore[i][j] > max) {
327                             max = computerScore[i][j];
328                             u = i;
329                             v = j; 
330                         } else if(computerScore[i][j] == max) {
331                             if(myScore[i][j] > myScore[u][v]) {
332                                 u = i;
333                                 v = j;
334                             }
335                         }
336 
337                     }
338                 }
339             }
340 
341             _compi = u;
342             _compj = v;
343             oneStep(u, v, false);
344             chressBord[u][v] = 2; //计算机占据位置
345             for(var k = 0; k < count; k++) {
346                 if(wins[u][v][k]) {
347                     computerWin[k]++;
348                     _myWin[k] = myWin[k];
349                     myWin[k] = 6; //这个位置对方不可能赢了;
350                     if(computerWin[k] == 5) {
351                         resultTxt.innerHTML = "┗|`O′|┛ 嗷~~,计算机赢了,继续加油!";
352                         over = true;
353                     }
354                 }
355             }
356             if(!over) {
357                 me = !me;
358             }
359             backAble = true;
360             returnAble = false;
361             var hasClass = new RegExp('unable').test("" + returnbtn.className + "");
362             if(!hasClass) {
363                 returnbtn.className += " " + "unable";
364             }
365         }
366 
367         //绘画键盘;
368         var drawChessBoard = function() {
369             for(var i = 0; i < 15; i++) {
370                 context.moveTo(15 + i * 30, 15);
371                 context.lineTo(15 + i * 30, 435);
372                 context.stroke();
373                 context.moveTo(15, 15 + i * 30);
374                 context.lineTo(435, 15 + i * 30);
375                 context.stroke();
376             }
377         }
378 
379         //画棋子
380         var oneStep = function(i, j, me) {
381             context.beginPath();
382             context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI); //画圆
383             context.closePath();
384             //渐变
385             var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);
386 
387             if(me) {
388                 gradient.addColorStop(0, '#0a0a0a');
389                 gradient.addColorStop(1, '#636766');
390             } else {
391                 gradient.addColorStop(0, '#d1d1d1');
392                 gradient.addColorStop(1, '#f9f9f9');
393             }
394             context.fillStyle = gradient;
395             context.fill();
396         }
397 
398         //销毁棋子
399         var minusStep = function(i, j) {
400             //擦除该圆
401             context.clearRect((i) * 30, (j) * 30, 30, 30);
402 
403             //重画该圆周围的格子
404             context.beginPath();
405             context.moveTo(15 + i * 30, j * 30);
406             context.lineTo(15 + i * 30, j * 30 + 30);
407             context.moveTo(i * 30, j * 30 + 15);
408             context.lineTo((i + 1) * 30, j * 30 + 15);
409             context.stroke();
410         }
411     </script>
412 
413 </html>

以下是对源码的分析与学习笔记:

五子棋小游戏代码详解:

结构上:

一个h3用来放标题,给了个id同时为了后期就可以更改提示信息放进去。

放一块画布

放三个按钮,分别是重来,悔棋,放弃悔棋。

样式中:

一:box-shadow

Box-shadow值得注意:一个box同时用了两个box-shadow;如下:

box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;

做一个案例彻底分析下:

box-shadow: -2px -2px 2px #f00, 5px 5px 5px #164A84;

为了看着明白,特地弄了对比明显的颜色。

色值说明:#f00【红色】, #164A84【蓝色】

X,y值得说明:-2px -2px, 5px 5px;【这么写,阴影是在是坐上和右下】

角度和x,y取值的关系表:

x,y的取值

阴影所在的角度

有阴影的两条边是

总结:

+x,+y

右下角

右边和下边

从左上角开始想象:

+x,-y

右上角

右边和上边

X负责左右,正右负左;

-x,+y

左下角

左边和下边

Y负责上下,正下负上;

-x,-y

左上角

左边和上边

二、display:flex;

Flex浏览器支持情况很差,仅火狐和谷歌通用。Ie10还不支持,手机上的浏览器全军覆没。

兼容写法:

display:-webkit-flex;

display: -moz-flex;

一个flexbox布局是有一个伸缩容器(flex containers)和这个容器里的伸缩内容(flex items)组成。

伸缩容器(flex containers)是一个HTML标签元素,并且“display”属性显式的设置了“flex”属性值。在伸缩容器中的所有子元素都会自动变成伸缩项目(flex items)。

三、Flex-direction:row(默认值);

四、Justify-content: center;

注:

本代码纯属学习与练习之用

源代码及博文见掘金地址:https://juejin.im/post/594669d461ff4b006cf132ff

git地址:https://github.com/wj704/wj704.github.io/blob/master/five_game.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档