今天更新的第二篇博客,是最近没事的时候写的一个小游戏-----五子棋,用canvas和js写的一个,大家可能觉得,一个破五子棋,网上的逻辑一大堆,各种判断都有,这些我写完以后也去看了,才知道网上早就有人开发了一个比我这个方法好的逻辑,但是我的正方法我个人觉得比较喜欢,所以分享出来给大家看看。
之所以用canvas做这个游戏,考虑到现在玩游戏的时候基本都是比较新型的浏览器或者手机,一般对canvas的兼容性都比较好,第二点是因为用canvas写这个游戏比较简单。。。请轻喷。好了,不废话了,贴代码咯。
// JavaScript Document
var can,txt,mousePos,posArray,posArray_x,posArray_y,flag=false,qizi_color,success_array=[],type,GameStatus="on";
function init(){
can = document.getElementById("mycanvas");
txt=can.getContext("2d");
drawpic();
can.addEventListener("click", function(evt){
if(GameStatus=="on"){addqizi(evt);}
}, false);
};
function drawpic(){
txt.clearRect(0,0,800,800);
txt.strokeStyle="black";
txt.fillStyle="#e0e0e0";
txt.fillRect(0,0,800,800);
txt.lineWidth="1px";
for(var i=0;i<26;i++){
txt.beginPath();
txt.moveTo(30*i+25,25);
txt.lineTo(30*i+25,775);
txt.stroke();
txt.beginPath();
}
for(var j=0;j<26;j++){
txt.beginPath();
txt.moveTo(25,30*j+25);
txt.lineTo(775,30*j+25);
txt.stroke();
txt.beginPath();
}
posArray=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]
};
function addqizi(evt){
mousePos=getMousePos(can, evt);
posArray_x=parseInt((mousePos.x-25)/30);
posArray_y=parseInt((mousePos.y-25)/30);
if((mousePos.x-25)%30>15&&(mousePos.y-25)%30>15){
posArray_x+=1;
posArray_y+=1;
}else if((mousePos.x-25)%30>15&&(mousePos.y-25)%30<15){
posArray_x+=1;
}else if((mousePos.x-25)%30<15&&(mousePos.y-25)%30>15){
posArray_y+=1;
}
if(posArray[posArray_x][posArray_y]==0){
if(flag==false){
qizi_color = txt.createRadialGradient(30*posArray_x+25,30*posArray_y+25,2,30*posArray_x+25,30*posArray_y+25,12);
qizi_color.addColorStop(0,"#505050");
qizi_color.addColorStop(1,"#000000");
flag=true;
posArray[posArray_x][posArray_y]=1;
}else if(flag==true){
qizi_color = txt.createRadialGradient(30*posArray_x+25,30*posArray_y+25,3,30*posArray_x+25,30*posArray_y+25,12);
qizi_color.addColorStop(0,"#dedede");
qizi_color.addColorStop(1,"#cccccc");
flag=false;
posArray[posArray_x][posArray_y]=2;
}
txt.fillStyle=qizi_color;
txt.beginPath();
txt.arc(30*posArray_x+25,30*posArray_y+25,12,0,Math.PI*2,true);
txt.closePath();
txt.fill();
check_result(posArray_x,posArray_y);
}
}
function check_result(i,n){
type=posArray[i][n];
//当棋子在左上角的时候
//-------------------------------------------------------------------------
//---------------------------左上角-----------------------------------------
if(i<5&&n<5){
//先判断横着的是否形成了五个棋子
for(var num=0;num<=i;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//再判断竖着的是否形成了五个棋子
for(var num=0;num<=n;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜着往下进行判断
if(i>n){
for(var x=(i-n),y=0;x<=i,y<=n;x++,y++){
for(var a= x,b=y;a<x+5,b<y+5;a++,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}else if(i<=n){
for(var x=0,y=(n-i);y<=n,x<=i;x++,y++){
for(var a= x,b=y;a<x+5,b<y+5;a++,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//斜着往上进行判断
if(i+n==4){
for(i=0;i<5;i++){
if(posArray[i][4-i]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//---------------------------上边距------------------------------
else if(i>=5&&i<21&&n<5){
//横着排列
for(var num=i-4;num<=i;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//再判断竖着的是否形成了五个棋子
for(var num=0;num<=n;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜着往上
for(var x=i+n,y=0;x>=i,y<=n;x--,y++){
for(var a= x,b=y;a>x-5,b<y+5;a--,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜着往下
for(var x=i-n,y=0;x<=i,y<=n;x++,y++){
for(var a=x,b=y;a<x+5,b<y+5;a++,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//---------------------------左边距------------------------------
else if(i<5&&n>=5&&n<21){
//横着
for(var num=0;num<=i;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
break;
}
}
chenckResult();
}
//竖着
for(var num=n-4;num<=n;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
for(var x=0,y=n+i;x<=i,y>=n;x++,y--){
for(var a=x,b=y;a<x+5,b>y-5;a++,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜下
for(var x=0,y=n-i;x<=i,y<=n;x++,y++){
for(var a=x,b=y;a<x+5,b<y+5;a++,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//---------------------------左下角------------------------------
else if(i<5&&n>20){
//横着
for(var num=0;num<=i;num++) {
for (var mum = num; mum < num + 5; mum++) {
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=25;num>=n;num--) {
for (var mum = num; mum > num - 5; mum--) {
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
if(i>25-n){
for(var x=i+n-25,y=25;x<=i,y>=n;x++,y--){
for(var a=x,b=y;a<x+5,b>y-5;a++,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}else if(i<=25-n){
for(var x=0,y=n+i;x<=i,y>=n;x++,y--){
for(var a=x,b=y;a<x+5,b>y-5;a++,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//斜下
if(n-i==21){
for(var x=0;x<5;x++){
if(posArray[x][21+x]==type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//---------------------------下边距------------------------------
else if(i>=5&&i<21&&n>20){
//横着
for(var num=i-4;num<=i;num++){
for(var mum=num;mum<num+5;mum++){
if(posArray[mum][n]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=25;num>=n;num--) {
for (var mum = num; mum > num - 5; mum--) {
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
for(var x=i+n-25,y=25;x<=i,y>=n;x++,y--){
for(var a=x,b=y;a<x+5,b>y-5;a++,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜下
for(var x=i-n+25,y=25;x>=i,y>=n;x--,y--){
for(var a=x,b=y;a>x-5,b>y-5;a--,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//----------------------------------右边距---------------------------------
else if(i>20&&n>=5&&n<21){
//横着
for(var num=25;num>=i;num--){
for(var mum=num;mum>num-5;mum--){
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=n-4;num<=n;num++){
for(var mum=num;mum<num+5;mum++){
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
for(var x=25,y=n+i-25;x>=i,y<=n;x--,y++){
for(var a=x,b=y;a>x-5,b<y+5;a--,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜下
for(var x=25,y=n-i+25;x>=i,y>=n;x--,y--){
for(var a=x,b=y;a>x-5,b>y-5;a--,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//----------------------------------右上角---------------------------------
else if(i>20&&n<5){
//横着
for(var num=25;num>=i;num--){
for(var mum=num;mum>num-5;mum--){
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=0;num<=n;num++){
for(var mum=num;mum<num+5;mum++){
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
if(25-i>n){
for(var x=i+n,y=0;x>=i,y<=n;x--,y++){
for(var a=x,b=y;a>x-5,b<y+5;a--,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}else{
for(var x=25,y=n+i-25;x>=i,y<=n;x--,y++){
for(var a=x,b=y;a>x-5,b<y+5;a--,b++){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//斜下
if(i=n+21){
for(n=0;n<5;n++){
if(posArray[n+21][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
//-------------------------------------------------------------------------
//----------------------------------右下角---------------------------------
else if(i>20&&n>20){
//横着
for(var num=25;num>=i;num--){
for(var mum=num;mum>num-5;mum--){
if(posArray[mum][n] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=25;num>=n;num--){
for(var mum=num;mum>num-5;mum--){
if(posArray[i][mum] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
if(i+n==46){
for(i=21;i<=25;i++){
if(posArray[i][46-i] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
//斜下
if(i<n){
for(var x=i+25-n,y=25;x>=i,y>=n;x--,y--){
for(var a=x,b=y;a>x-5,b>y-5;a--,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}else{
for(var x=25,y=n+25-i;x>=i,y>=n;x--,y--){
for(var a=x,b=y;a>x-5,b>y-5;a--,b--){
if(posArray[a][b] == type){
success_array.push(1);
}
else{
success_array.push(0);
}
}
chenckResult();
}
}
}
//-------------------------------------------------------------------------
//---------------------------中间区域------------------------------
else if(i>=5&&i<21&&n>=5&&n<21){
//横着
for(var num=i-4;num<=i;num++){
for(var mum=num;mum<num+5;mum++){
if(posArray[mum][n]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
//竖着
for(var num=n-4;num<=n;num++){
for(var mum=num;mum<num+5;mum++){
if(posArray[i][mum]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
//斜上
for(var x=i-4,y=n+4;x<=i,y>=n;x++,y--){
for(var a=x,b=y;a<x+5,b>y-5;a++,b--){
if(posArray[a][b]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
//斜下
for(var x=i-4,y=n-4;x<=i,y<=n;x++,y++){
for(var a=x,b=y;a<x+5,b<y+5;a++,b++){
if(posArray[a][b]==type){
success_array.push(1);
}else{
success_array.push(0);
}
}
chenckResult();
}
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left * (canvas.width / rect.width),
y: evt.clientY - rect.top * (canvas.height / rect.height)
}
}
function chenckResult(){
if(success_array.toString()==[1,1,1,1,1].toString()){
if(type==1){
alert("黑子胜利!");
}else{
alert("白子胜利!");
}
GameStatus="off";
success_array=[];
return;
}else{
success_array=[];
}
}
init();
function Restrat(){
init();
GameStatus="on";
}
其实这些代码还有很多可以优化的位置,只是后来写完了一直有事儿,就没有进行细化,不过大家可以看看里面的一些逻辑,虽然逻辑比较复杂,但是能把这些全部想通的话其实也是一个不错的选择,之前js有一千多行,后来被我压缩成700多行了。。。但是还有很多可以压缩的空间,网上的方法我也看过,只需要两百多行就可以搞定,本来后来想写一个网上的方法的,一直忙到现在都没什么时间去写了,网上的方法逻辑比较简单,后来也就不想去动了 。
这个方法是用的纯数组实现的,虽然逻辑上,速率上比网上的慢很多,但是我想说的是这个逻辑还是比较适合游戏的,数组在游戏里或者是复杂的动画里真的是比较神器的东西(ps.纯属个人理解)。
谢谢您花时间看完这两篇博客,希望您不吝赐教,提出您宝贵的意见。