您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 天水分类信息网,免费分类信息发布

Html5 Canvas实现斗地主游戏的示例代码分析

2024/4/7 4:46:08发布13次查看
现在我看了html5以及canvas相关知识和斗地主的demo后,自己用demo上的素材试着写了个斗地主,代码没重构好,欢迎赐教。
话不多说,下面就一步一步解释下吧
只有一个common.js文件
1、资源类
var resource = class.create(); $.extend(resource.prototype, { initialize: function () { }, images: [ { path: 'img/bg1.png', x: 0, y: 0, w: 800, h: 480, data: null, type: 61, visible: true }, { path: 'img/beimian.jpg', x: 320, y: 5, w: 100, h: 121, data: null, type: 62, visible: true }, { path: 'img/btn.jpg', x: 300, y: 281, w: 140, h: 50, data: null, type: 63, visible: true, text: '开始', textx: 366, texty: 310 }, { x: 0, y: 0, type: 66, istext: true, visible: false }, { path: 'img/1.jpg', data: null, type: 16, visible: false }, { path: 'img/2.jpg', data: null, type: 17, visible: false }, { path: 'img/3.jpg', data: null, type: 3, visible: false, se: 1 }, { path: 'img/4.jpg', data: null, type: 4, visible: false, se: 1 }, { path: 'img/5.jpg', data: null, type: 5, visible: false, se: 1 }, { path: 'img/6.jpg', data: null, type: 6, visible: false, se: 1 }, { path: 'img/7.jpg', data: null, type: 7, visible: false, se: 1 }, { path: 'img/8.jpg', data: null, type: 8, visible: false, se: 1 }, { path: 'img/9.jpg', data: null, type: 9, visible: false, se: 1 }, { path: 'img/10.jpg', data: null, type: 10, visible: false, se: 1 }, { path: 'img/11.jpg', data: null, type: 11, visible: false, se: 1 }, { path: 'img/12.jpg', data: null, type: 12, visible: false, se: 1 }, { path: 'img/13.jpg', data: null, type: 13, visible: false, se: 1 }, { path: 'img/14.jpg', data: null, type: 14, visible: false, se: 1 }, { path: 'img/15.jpg', data: null, type: 15, visible: false, se: 1 }, { path: 'img/16.jpg', data: null, type: 3, visible: false, se: 4 }, { path: 'img/17.jpg', data: null, type: 4, visible: false, se: 4 }, { path: 'img/18.jpg', data: null, type: 5, visible: false, se: 4 }, { path: 'img/19.jpg', data: null, type: 6, visible: false, se: 4 }, { path: 'img/20.jpg', data: null, type: 7, visible: false, se: 4 }, { path: 'img/21.jpg', data: null, type: 8, visible: false, se: 4 }, { path: 'img/22.jpg', data: null, type: 9, visible: false, se: 4 }, { path: 'img/23.jpg', data: null, type: 10, visible: false, se: 4 }, { path: 'img/24.jpg', data: null, type: 11, visible: false, se: 4 }, { path: 'img/25.jpg', data: null, type: 12, visible: false, se: 4 }, { path: 'img/26.jpg', data: null, type: 13, visible: false, se: 4 }, { path: 'img/27.jpg', data: null, type: 14, visible: false, se: 4 }, { path: 'img/28.jpg', data: null, type: 15, visible: false, se: 4 }, { path: 'img/29.jpg', data: null, type: 3, visible: false, se: 3 }, { path: 'img/30.jpg', data: null, type: 4, visible: false, se: 3 }, { path: 'img/31.jpg', data: null, type: 5, visible: false, se: 3 }, { path: 'img/32.jpg', data: null, type: 6, visible: false, se: 3 }, { path: 'img/33.jpg', data: null, type: 7, visible: false, se: 3 }, { path: 'img/34.jpg', data: null, type: 8, visible: false, se: 3 }, { path: 'img/35.jpg', data: null, type: 9, visible: false, se: 3 }, { path: 'img/36.jpg', data: null, type: 10, visible: false, se: 3 }, { path: 'img/37.jpg', data: null, type: 11, visible: false, se: 3 }, { path: 'img/38.jpg', data: null, type: 12, visible: false, se: 3 }, { path: 'img/39.jpg', data: null, type: 13, visible: false, se: 3 }, { path: 'img/40.jpg', data: null, type: 14, visible: false, se: 3 }, { path: 'img/41.jpg', data: null, type: 15, visible: false, se: 3 }, { path: 'img/42.jpg', data: null, type: 3, visible: false, se: 2 }, { path: 'img/43.jpg', data: null, type: 4, visible: false, se: 2 }, { path: 'img/44.jpg', data: null, type: 5, visible: false, se: 2 }, { path: 'img/45.jpg', data: null, type: 6, visible: false, se: 2 }, { path: 'img/46.jpg', data: null, type: 7, visible: false, se: 2 }, { path: 'img/47.jpg', data: null, type: 8, visible: false, se: 2 }, { path: 'img/48.jpg', data: null, type: 9, visible: false, se: 2 }, { path: 'img/49.jpg', data: null, type: 10, visible: false, se: 2 }, { path: 'img/50.jpg', data: null, type: 11, visible: false, se: 2 }, { path: 'img/51.jpg', data: null, type: 12, visible: false, se: 2 }, { path: 'img/52.jpg', data: null, type: 13, visible: false, se: 2 }, { path: 'img/53.jpg', data: null, type: 14, visible: false, se: 2 }, { path: 'img/54.jpg', data: null, type: 15, visible: false, se: 2 } ] });
resource.images是素材数组(几个按钮,文本,54张牌,背景图片等),大家可以下载demo看看
2、lables类,在canvas画布上画文本的,比如按钮文字,相关知识请看canvas教程
var labels = class.create(); $.extend(labels.prototype, { initialize: function (cxt) { this.cxt = cxt; }, settext: function (text, postion) { this.cxt.font = 'bold 20px serif'; this.cxt.fillstyle = '#000000'; this.cxt.textalign = 'center'; this.cxt.filltext(text, postion.x, postion.y); } });
这个类的方法settext主要是根据设置的字体,字体大小,字体颜色,在canvas上画文本的,this.cxt这个是canvas上下文(每个教程的叫法不一样),首先this.cxt.font = 'bold 20px serif';这个是设置字体大小,样式等,this.cxt.fillstyle = '#000000';这个
是设置字体颜色,this.cxt.textalign = 'center';这个是设置字体对齐方式,this.cxt.filltext(text, postion.x, postion.y);这个是开始在canvas上画文本,postion.x, postion.y分别是x坐标和y坐标。
3、ddzgame游戏类,主要功能就是初始化斗地主,发牌,抢地主等,出牌未完待续,后续更新
var ddzgame = class.create(); ddzgame.statics = { dealednums: 0, isleftfirstdeal: true }; $.extend(ddzgame.prototype, { initialize: function () { ddzgame.statics.isgetlander = false; ddzgame.statics.dealtime = 66; this.leftpokers = []; this.rightpokers = []; this.mypokers = []; this.lastpokers = [];//最后3张牌 this.leftplays = []; this.rightplays = []; this.myplays = []; this.mybtnpostion = { y: 245, x: 162 }; this.isstart = false; this.res = new resource(); this.allpokers = new array(); this.lander = 0;//地主,1右边,2my,3左边 this.isgetlander = {}; this.gmcanvas = document.getelementbyid('gmcanvas'); this.cxt = this.gmcanvas.getcontext('2d'); this.lbl = new labels(this.cxt); this.init(); this.initevt(); }, initevt: function () { this.gmcanvas.onclick = $.proxy(function (e) { var box = this.gmcanvas.getboundingclientrect(); ddzgame.statics.mousepostion = { x: e.pagex - box.left, y: e.pagey - box.top }; this.oncontrolclick(); }, this); }, oncontrolclick: function () { var isclick = false; for (var i = 0; i < this.controls.length; i++) { var c = this.controls[i]; var postion = ddzgame.statics.mousepostion; if (c.onclick) { if (postion.x >= c.x && postion.x <= c.x + c.w && postion.y >= c.y && postion.y <= c.y + c.h) { c.onclick(); isclick = true; break; } } } if (!isclick) { for (var i = 0; i < this.mypokers.length; i++) { var c = this.mypokers[i]; var postion = ddzgame.statics.mousepostion; if (c.onclick) { if (postion.x >= c.x && postion.x <= c.x + c.w && postion.y >= c.y && postion.y <= c.y + c.h) { c.onclick(); isclick = true; break; } } } } }, loadimages: function (callback) { var loadednums = 0; var totalnums = this.res.images.length - 1; this.controls = []; $.each(this.res.images, $.proxy(function (i, o) { if (!o.path) { return true; } o.data = new image(); o.data.src = o.path; o.data.onload = $.proxy(function () { if (o.type <= 17) { this.allpokers.push(o); } else this.controls.push(o); loadednums++; if (loadednums >= totalnums) { callback.call(this); } }, this); }, this)); }, drawimage: function (callback, isunvisiblelast) {//isvisiblelast 是否让底牌不可见 $.each(this.controls, $.proxy(function (i, o) { if (!o.visible) return true; if (o.type == 62) { var x = 0; for (var i = 0; i < 54 - ddzgame.statics.dealednums ; i++) { if (i == 0) x = o.x; this.cxt.drawimage(o.data, o.x, o.y, o.w, o.h); o.x++; } o.x = x; } else if (!o.istext) { this.cxt.drawimage(o.data, o.x, o.y, o.w, o.h); } if (o.type == 63) { this.lbl.settext(o.text, { x: o.textx, y: o.texty }); if (!o.onclick) o.onclick = $.proxy(function () { o.onclick = null; o.visible = false; this.drawimage(); this.dealing(); }, this); } if (o.type == 66) { this.lbl.settext(o.text, { x: o.x, y: o.y }); } }, this)); /*克隆*/ var copyleftpokers = this.leftpokers.slice(); var copyrightpokers = this.rightpokers.slice(); var copymypokers = this.mypokers.slice(); var copylastpokers = this.lastpokers.slice(); var isdealendleft = false; var isdealendright = false; var isdealendmy = false; var isdealendlast = false; var beimain = $.grep(this.res.images, $.proxy(function (o, i) { return o.type == 62; }, this))[0]; var drawpokers = function (arry, direction, isbeimian, identiy, axis) { if (arry && arry.length > 0) { var o = arry[0]; var x = 0, y = 0; if (!ddzgame.statics[direction]) { ddzgame.statics[direction] = this[direction]; } if (!o.x) { x = ddzgame.statics[direction].x; y = ddzgame.statics[direction].y; o.x = this[direction].x; o.y = this[direction].y; } else { x = o.x; y = o.y; } if (!o.visible) { return true; } o.w = 18; o.h = 129; if (arry.length == 1) { o.w = 105; o.h = 150; } var img = o.data; if (isbeimian) { img = beimain.data; } else if (direction == 'mypannel') { o.onclick = $.proxy(function () { if (!this.isstart) return; if (!o.isplay) { o.isplay = true; o.y -= 30; } else { o.isplay = false; o.y += 30; } ddzgame.statics.dealtime = 0; this.drawimage(); }, this); } this.cxt.drawimage(img, x, y); ddzgame.statics[direction][axis] += identiy; arry.splice(0, 1); if (ddzgame.statics.dealtime > 0) ddzgame.statics[direction + 'handle'] = settimeout($.proxy(function () { drawpokers.call(this, arry, direction, isbeimian, identiy, axis); }, this), ddzgame.statics.dealtime); else drawpokers.call(this, arry, direction, isbeimian, identiy, axis); } else if (ddzgame.statics[direction + 'handle'] || ddzgame.statics.dealtime == 0) { cleartimeout(ddzgame.statics[direction + 'handle']); if (direction == 'leftpannel' && copyleftpokers.length == 0) { isdealendleft = true; } if (direction == 'rightpannel' && copyrightpokers.length == 0) { isdealendright = true; } if (direction == 'mypannel' && copymypokers.length == 0) { isdealendmy = true; } if (direction == 'lastpannel' && copylastpokers.length == 0) { isdealendlast = true; } if (isdealendleft && isdealendright && isdealendmy && isdealendlast) { /*发牌完毕*/ /*抢地主*/ if (callback) callback(); } } }; drawpokers.call(this, copyleftpokers, 'leftpannel', true, 26, 'y'); drawpokers.call(this, copyrightpokers, 'rightpannel', true, 26, 'y'); drawpokers.call(this, copymypokers, 'mypannel', false, 19, 'x'); drawpokers.call(this, copylastpokers, 'lastpannel', isunvisiblelast, 126, 'x'); }, init: function () { this.loadimages(this.drawimage); }, dealing: function () {//发牌 this.leftpannel = { x: 5, y: 18 }; this.rightpannel = { x: 691, y: 18 }; this.mypannel = { x: 198, y: 330 }; this.lastpannel = { x: 243, y: 5 }; if (ddzgame.statics.dealednums >= 51) { //发牌完毕 $.each(this.allpokers, $.proxy(function (i, o) { o.visible = true; this.lastpokers.push(o); }, this)); this.mypokers.sort(function (a, b) { if (a.type != b.type) return b.type - a.type; return b.se - a.se; }); $.grep(this.res.images, $.proxy(function (o, i) { return o.type == 62; }, this))[0].visible = false; this.drawimage($.proxy(function () { this.getlander(); }, this), true); } else { /*1、left*/ var index = math.floor(math.random() * (this.allpokers.length - 1) + 0); var c = this.allpokers.splice(index, 1); c[0].visible = true; this.leftpokers.push(c[0]); ddzgame.statics.dealednums++; /*2、right*/ index = math.floor(math.random() * (this.allpokers.length - 1) + 0); c = this.allpokers.splice(index, 1); c[0].visible = true; this.rightpokers.push(c[0]); ddzgame.statics.dealednums++; index = math.floor(math.random() * (this.allpokers.length - 1) + 0); c = this.allpokers.splice(index, 1); c[0].visible = true; this.mypokers.push(c[0]); ddzgame.statics.dealednums++; this.dealing(); } }, getlander: function (firstget, minscore, curscore) { /*随机出谁先叫地主*/ //if (curscore && !this.isgetlander[1] && !this.isgetlander[2] && !this.isgetlander[3]) { // //**game over ! // alert('无人抢地主'); // return; //} var postion = { 1: { y: 100, x: 640 }, 3: { y: 100, x: 126 }, 2: { x: 216, y: 297 } }; if (!curscore) { if (!minscore) minscore = 1; if (!firstget) firstget = math.floor(math.random() * (3 - 1 + 1) + 1); if (firstget == 1 || firstget == 3) { //电脑抢地主 if (this.isgetlander[firstget] == -1 || this.isgetlander[firstget]) { $.each(this.controls, $.proxy(function (i, o) { if (o.lander) { o.visible = false; } }, this)); var max = 0; if (this.isgetlander[1] > this.isgetlander[2]) { max = this.isgetlander[1]; this.lander = 1; } else { max = this.isgetlander[2]; this.lander = 2; } if (max < this.isgetlander[3]) { max = this.isgetlander[3]; this.lander = 3; } if (max == 0) { alert('game over !'); return; } var txt = max + '分'; var t = {}; var tobj = $.grep(this.res.images, function (o, i) { return o.type == 66; })[0]; $.extend(t, tobj);//复制对象 if (this.curscore == 4) { txt = '不抢'; } t.text = txt; t.x = postion[this.lander].x; t.y = postion[this.lander].y; t.visible = true; this.controls.push(t); //this.drawimage($.proxy(function () { // this.fandipai(this.lander); //}, this)); this.fandipai(this.lander); return; } console.log('电脑抢地主'); this.curscore = math.floor(math.random() * (4 - minscore + 1) + minscore); this.isgetlander[firstget] = this.curscore == 4 ? -1 : this.curscore; var txt = this.curscore + '分'; var t = {}; var tobj = $.grep(this.res.images, function (o, i) { return o.type == 66; })[0]; $.extend(t, tobj);//复制对象 if (this.curscore == 4) { txt = '不抢'; } t.text = txt; t.x = postion[firstget].x; t.y = postion[firstget].y; t.visible = true; this.controls.push(t); if (this.curscore == 3) { this.lander = firstget; //ddzgame.statics.isgetlander = true; //ddzgame.statics.dealtime = 0; var dz = {}; $.extend(dz, tobj);//复制对象 dz.text = '地主'; dz.x = t.x + 30; dz.y = t.y; dz.visible = true; this.controls.push(dz); //this.drawimage($.proxy(function () { this.play(this.lander, '电脑地主'); }, this));//电脑抢到地主优先出牌 this.fandipai(this.lander); return; } else { if (this.curscore == 4) { var test = 'abcdefg'; } var nextget = firstget == 1 ? 2 : 1; minscore = this.curscore == 4 ? minscore : this.curscore + 1; this.curscore = this.curscore == 4 ? 0 : this.curscore; ddzgame.statics.dealtime = 0; this.drawimage($.proxy(function () { this.getlander(nextget, minscore); }, this), true);//电脑抢到地主优先出牌 return; } } } if (curscore) { /*代码写的很垃圾,这点没用面向对象*/ /*my已经叫过地主,按钮需要隐藏*/ $.each(this.controls, $.proxy(function (i, o) { if (o.lander) { o.visible = false; } }, this)); this.curscore = curscore; var txt = this.curscore + '分'; var t = {}; var tobj = $.grep(this.res.images, function (o, i) { return o.type == 66; })[0]; $.extend(t, tobj);//复制对象 if (this.curscore == 4) { txt = '不抢'; } t.text = txt; t.x = postion[2].x; t.y = postion[2].y; t.visible = true; this.controls.push(t); this.isgetlander[2] = curscore == 4 ? -1 : curscore; if (this.curscore == 3 || (this.isgetlander[1] && this.isgetlander[3] && this.curscore != 4)) { this.lander = 2; //ddzgame.statics.isgetlander = true; //ddzgame.statics.dealtime = 0; var dz = {}; $.extend(dz, tobj);//复制对象 dz.text = '地主'; dz.x = t.x + 50; dz.y = t.y; dz.visible = true; this.controls.push(dz); //this.drawimage($.proxy(function () { this.play(this.lander, '我是地主'); }, this), false);//电脑抢到地主优先出牌 this.fandipai(this.lander); return; } else { minscore = this.curscore == 4 ? minscore : this.curscore + 1; this.curscore = this.curscore == 4 ? 0 : this.curscore; if (!this.isgetlander[3]) { ddzgame.statics.dealtime = 0; this.drawimage($.proxy(function () { this.getlander(3, minscore) }, this), true); return; } else { //已经转了一圈,则比较抢地主的分数大小 var max = 0; if (this.isgetlander[1] > this.isgetlander[2]) { max = this.isgetlander[1]; this.lander = 1; } else { max = this.isgetlander[2]; this.lander = 2; } if (max < this.isgetlander[3]) { max = this.isgetlander[3]; this.lander = 3; } if (max == 0) { alert('game over !'); return; } var txt = '地主'; var t = {}; var tobj = $.grep(this.res.images, function (o, i) { return o.type == 66; })[0]; $.extend(t, tobj);//复制对象 t.text = txt; t.x = postion[this.lander].x; t.y = postion[this.lander].y; if (this.lander != 2) { t.x += 30; } else { t.x += 50; } t.visible = true; this.controls.push(t); //ddzgame.statics.dealtime = 0; //this.drawimage($.proxy(function () { this.play(this.lander, '抢地主啊'); }, this), false); this.fandipai(this.lander); return; } } } else if (this.isgetlander[2] == -1 || this.isgetlander[2]) { $.each(this.controls, $.proxy(function (i, o) { if (o.lander) { o.visible = false; } }, this)); var max = 0; if (this.isgetlander[1] > this.isgetlander[2]) { max = this.isgetlander[1]; this.lander = 1; } else { max = this.isgetlander[2]; this.lander = 2; } if (max < this.isgetlander[3]) { max = this.isgetlander[3]; this.lander = 3; } if (max == 0) { alert('game over !'); return; } var txt = max + '分'; var t = {}; var tobj = $.grep(this.res.images, function (o, i) { return o.type == 66; })[0]; $.extend(t, tobj);//复制对象 if (this.curscore == 4) { txt = '不抢'; } t.text = txt; t.x = postion[this.lander].x; t.y = postion[this.lander].y; t.visible = true; this.controls.push(t); //ddzgame.statics.dealtime = 0; //this.drawimage($.proxy(function () { this.play(this.lander, '抢地主啊'); }, this), false); this.fandipai(this.lander); return; } //if (ddzgame.statics.isgetlander) { // return; //} //ddzgame.statics.isgetlander = true;//是否在抢地主 console.log('我抢地主'); var btnobj = $.grep(this.res.images, $.proxy(function (o, i) { return o.type == 63; }, this))[0]; if (!this.curscore) { this.curscore = 0; } var txtx = 0; for (var i = 1; i <= 3; i++) { if (i > this.curscore) { var btn = {}; $.extend(btn, btnobj); btn.text = i + '分'; btn.x = this.mybtnpostion.x; btn.y = this.mybtnpostion.y; btn.visible = true; btn.type = 63; btn.textx = this.mybtnpostion.x + 30; btn.texty = 286; btn.h = 50; btn.w = 81; btn.lander = true; btn.onclick = (function (i, obj) { return function () { obj.getlander(3, i + 1, i); }; })(i, this) ddzgame.statics.dealtime = 0; this.controls.push(btn); this.mybtnpostion.x += btn.w + 10; } } if (ddzgame.statics.dealtime == 0) { var btn = {}; $.extend(btn, btnobj); btn.text = '不抢'; btn.x = this.mybtnpostion.x; btn.y = this.mybtnpostion.y; btn.visible = true; btn.type = 63; btn.textx = this.mybtnpostion.x + 30; btn.texty = 286; btn.h = 50; btn.w = 81; btn.lander = true; btn.onclick = $.proxy(function () { this.getlander(3, minscore, 4); }, this); this.controls.push(btn); this.drawimage(null, true); } }, fandipai: function (lander) {//翻底牌 ddzgame.statics.dealtime = 0; var p = ''; if (lander == 1) { p = 'rightpokers'; } else if (lander == 2) { p = 'mypokers'; } else if (lander == 3) { p = 'leftpokers'; } /*谁抢到地主,底牌归谁*/ $.each(this.lastpokers, $.proxy(function (i, o) { var c = {}; $.extend(c, o); c.x = null; c.y = null; this[p].push(c); test = c.path; }, this)); if (lander == 2) { this.mypokers.sort(function (a, b) { a.x = null; a.y = null; b.x = null; b.y = null; if (a.type != b.type) return b.type - a.type; return b.se - a.se; }); this.mypannel = { x: 198, y: 330 }; ddzgame.statics['mypannel'] = null; } this.drawimage($.proxy(function () { this.isstart = true; this.play(lander, '是地主啊'); }, this), false); }, play: function (lander, msg) {//出牌 //alert(''); } });
view code
initialize:这个函数是构造函数,初始化一些起始变量。
initevt这个里是初始化canvas事件,canvas点击事件不像svg那样,因为canvas是一帧一帧画上去的,html dom里是看不到里面的每个元素,javascript自然也无法获取到canvas里的某个元素,那canvas元素点击事件是怎么处理的了?
首先定义下canvas这个画布的事件,然后定义获取鼠标的坐标,再算出在canvas相对坐标,因为每个元素也都有自己的坐标和宽高,所以可以根据这个坐标判断这个坐标是否在某个元素内。
oncontrolclick:这个函数是根据上面算出的坐标,判断此坐标在哪个元素内,如果在元素内,并且定义了onclick函数(注:此处并不是真正的元素事件,只是对象的一个函数属性),然后调用onclick函数,执行相应的代码。
loadimages:这个是加载所有图片,图片加载完成之后,就开始在canvas上画初始的元素。
init:这个函数就是调用loadimages函数,然后所有图片加载完毕之后,调用回调函数,在canvas上画初始的元素
dealing :这个是发牌,每方的牌都是随机的,if(ddzgame.statics.dealednums >= 51)发了51张牌之后,就剩3张底牌,然后再把这51张牌和3张底牌画在canvas上
getlander :这个是抢地主,谁先抢地主是随机的,如果是先随机到电脑抢地主,那抢地主的分数也是随机的。
以上就是html5 canvas实现斗地主游戏的示例代码分析的详细内容。
天水分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录