目录
前期回顾
本文实现了包含形象的斗地主网页游戏,js循环动画,简单生动的画面设计。非常丝滑有意思,欢迎对此代码感兴趣的朋友前来下载参考。
如果大家非常好奇该段代码所带来的网页游戏效果的话,那就直接拷贝到自己电脑上,不上传了资源了,方便大家直接玩乐,如果对你有些微帮助还请收藏以备下次及时找到!
本文直接复制可以用,
效果如下
目录结构
GameEntity.js
/**
* 实体类;有些实体其中的行为,
* 可能没有严格符合面向对象规范,
* 原因在于对象与过程之间的界限难以区分
*/
// 玩家
class Player{
constructor(BoardList, name, color){
this.Color = color
// Board对象
this.BoardList = BoardList
this.name = name
this.GroupBoard = null
}
// 通过ID获取牌
GetBoardOfID(id){
if(this.BoardList.length>0){
for(let i=0;i<this.BoardList.length;i++){
if(this.BoardList[i].id == id)
return i
}
}
return -1
}
// 根据ID删除节点
DeleteIDOfBoard(id){
if(this.BoardList.length<1) return
let index_ = this.GetBoardOfID(id)
this.BoardList.splice(index_, 1)
}
// 将手中的牌按照顺序排列
BoardListSort(){
BoardSort(this.BoardList)
}
// 提示出牌
AutoSendBoard(){
// 提示出牌需要满足几个条件,
// 首先上家没有出牌时,那么按照最大的类型出牌(炸弹除外),如Y2>Y1
// 如果上家有出牌,那么需要判断当前牌组之中是否有相对应类型的牌
// 玩家需要自己维护自己所有的牌总量(机器人由程序维护),如一手牌组当中有几个飞机几个顺子
}
// 将当前的牌聚类为一个个的牌组合;返回牌组合数组
// 如:987654333 return: Y5,Y3,Y2
ClusterType(){
}
}
// 牌对象
// type ♥,♠,♦,♣
class Board{
constructor(surface, type, id){
this.surface = surface
this.type = type
this.id = type + id
this.DrawBoardFront = CreateBorad(width/2-30, height/2-45, this)
this.DrawBoardFront._id = id
// id必须是要唯一的
this.DrawBoardBack = BoardBack(width/2-30, height/2-45, this)
this.DrawBoardBack._id = '0'+id
}
}
// 组合牌
class BoardCombin{
constructor(BoardList, Type, Value, length){
this.BoardList = BoardList
this.Type = Type
this.Value = Value
this.Length = length
}
}
// 这里可以优化,使用有限状态机会更好,逻辑更清晰
// 判定出牌边界,类型一致,牌的数量一致,不小于桌面价值量
// 单: 1; Y1
// 对: 2; Y2 *
// 三带: 3~5; Y3
// 顺: 5~12; Y4
// 连对: 6~16; Y5 *
// 飞机: 6~16; Y6
// 四带二: 6~8; Y7 *
// 炸弹: 4 Y8 *
// 王炸: 2 Y8 *
// 牌组分类器
class BoardType{
constructor(BoardList, Boards){
this.Boards = BoardList
this.BoardList = new Array()
if(Boards!=null)
this.BoardList = Boards
// 将牌对象划为简单的字面量
this.BoardListValue = new Array();
for(let i=0;i<BoardList.length;i++){
this.BoardList.push( BoardList[i].surface )
this.BoardListValue.push(BoardMarkMap.get(BoardList[i].surface))
}
}
// 获取出牌的类型,判定牌是否严格属于哪一类型
GetType(){
var length = this.BoardList.length;
// 单牌
if(length === 1){
return this.FiltrateSign(this.BoardList)
}
// 对子,王炸
if(length === 2){
return this.FiltrateTow(this.BoardList)
}
// 三带,炸弹
if(length>=3 && length<=5){
return this.FiltrateThree(this.BoardList)
}
// 飞机,连对,顺子,四带二
if(length>=5 && length<=16){
return this.FiltrateLine(this.BoardList)
}
}
// 单牌过滤
FiltrateSign(BoardList_){
var value_ = BoardMarkMap.get(BoardList_[0])
return new BoardCombin(this.Boards, "Y1", value_, 1)
}
// 双牌过滤=》王炸
FiltrateTow(BoardList_){
if(BoardList_[0]===BoardList_[1]){
var value_ = BoardMarkMap.get(BoardList_[0])
return new BoardCombin(this.Boards, "Y2", value_, 2)
} else{
return this.FiltrateKingMax(BoardList_)
}
}
// 三带过滤=》顺子=》炸弹
FiltrateThree(BoardList_){
var temp = BoardList_.join('')
// 其中任一一张牌出现三次以上
var reg = /(\d|J|Q|K|A)\1{2}/
var index = temp.search(reg)
if(!reg.test(temp)) {
// 如果没有匹配到三带,那么有可能是顺子
if(temp.length===5)
return this.FiltrateLine(BoardList_)
return null
};
var value_ = BoardMarkMap.get(BoardList_[index])
// 判断是三不带|三带一|三带对
temp = temp.replace(reg, '')
if(temp.length==0)
return new BoardCombin(this.Boards, "Y3", value_, 3)
if(temp.length==1 && temp!=BoardList_[index])
return new BoardCombin(this.Boards, "Y3", value_, 4)
else if(temp.length==1){
return this.FiltrateBomb(BoardList_);
}
if(temp.length==2 && temp[0] == temp[1])
return new BoardCombin(this.Boards, "Y3", value_, 5)
return null
}
// 顺子过滤=》连对=》飞机=》四带二
FiltrateLine(BoardList_){
var temp = BoardList_.join('')
// 如果牌组数量大于5,那么更有可能是连对或者飞机,四带二
if(temp.length>5){
var tempData = null;
// 过滤连对,过滤四带二,只有偶数才可
if(temp.length%2===0)
{
tempData = this.FiltrateLineTwo(BoardList_)
if(tempData != null) return tempData
var tempData = this.FiltrateFour(BoardList_)
if(tempData != null) return tempData
}
// 飞机过滤
tempData = this.FiltrateAir(BoardList_)
if(tempData != null) return tempData
}
// 如果出现2,小鬼,大鬼那么就不是顺子
var reg = /(2|C|G)/
if(reg.test(temp)) return null;
var value_ = this.BoardListValue[0]
for(var i=1; i<BoardList_.length; i++){
// 顺子必须是连续的,即每个数之间相差要等于1
if(this.BoardListValue[i-1]-this.BoardListValue[i]!=1)
return null;
}
return new BoardCombin(this.Boards,'Y4', value_, BoardList_.length)
}
// 飞机过滤
// 飞机可带两张单牌,或者两个对子,亦或者不带
FiltrateAir(BoardList_){
var temp = BoardList_.join('')
// 其中任多张牌出现三次
var reg = /(0|[3-9]|J|Q|K|A)\1{2}/g // 三带
var tempList_1 = temp.match(reg)
if(tempList_1==null) return null
var recode = 0
// 飞机至少要是两个连起来的三带
for(var i=1; i<tempList_1.length; i++){
var i1 = BoardMarkMap.get(tempList_1[i][0])
var i2 = BoardMarkMap.get(tempList_1[i-1][0])
if(i2-i1==1){
temp = temp.replace(tempList_1[i],'')
temp = temp.replace(tempList_1[i-1],'')
}else
recode++
}
var len = tempList_1.length-recode
if(len<2) return null
// 返回牌组对象
var value_ = BoardMarkMap.get(tempList_1[0][0])
// 三不带