来自我朋友得原创小游戏、顺行棋

106 阅读1分钟

来自我朋友得原创小游戏、顺行棋
我朋友sa-admin等著作者,java资深从业者

<!DOCTYPE html>
<html>
	<head>
		<title>顺行棋</title>
		<meta charset="UTF-8">
		<style>
			body{
				background-color: #EEE;
			}
			
			.error-fox{margin: 50px auto; text-align: center; color: red;}
			
			.game-fox,.qipan-fox{
				width: 400px;
				height: 400px;
				border: 0px #000 solid;
				margin: 0px auto;
				box-shadow: 5px 5px 20px #000;
				position: relative;
			}
			
			.qipan{
				box-shadow: 0 0 1px #DDD;
				position: absolute;
				width: 100px;
				height: 100px;
			}
			.card{
				box-shadow: 0 0 0px #DDD;
				position: absolute;
				width: 100px;
				height: 100px;
				cursor: pointer;
			}
			.c-tran-4{transition: all 0.2s;}
			
			.card-nr{
				width: 50px;
				height: 50px;
				left: 25px;
				top: 25px;
				line-height: 15px;
				text-align: center;
				position: absolute;
				background-color: #FFF;
				background-size: 100% 100%;
				cursor: pointer;
				transition: all 0.2s;
			}
			.qipan-nr{
				position: absolute;
				width: 100px;
				height: 100px;
				cursor: pointer;
			}
			
			/* 飞跳洞 */
			.card-ftd{
				font-size: 0.5em;
			}
			
			/* 不同状态不同类 */
			.card-cs-1{
				background-image: url(img/card-bg.jpg); 
			}
			.card-cs-4{
				width: 60px;
				height: 60px;
				left: 20px;
				top: 20px;
				box-shadow: 0 0 30px #94D8F6;
				z-index: 99;
			}
			
			/* 翻牌特效 */
			.card-fanpai{
				transform: rotateY(90deg);	
			}
			.card-hover{
				box-shadow: 0 0 20px #94D8F6;
			}
			
			
			/* 做标 */
			.zuobiao{
				width: 10px;
				height: 10px;
				border-radius: 50%;
				background-color: green;
				box-shadow: 0 0 10px green;
				margin: 45px;
				transition: all 0.5s;
				transform: scale(0, 0);
			}
			.zuobiao-show{
				transform: scale(1, 1);
			}
			
			/* 线段 */
			.xd-td{
				width: 100px;
				height: 100px;
				position: absolute;
				border: 1px #aaa solid;
			}
			
			
		</style>
	</head>
	<body>

		<div id="app">
			规则:
			井>丁>剪刀石头布<br>
			吃了飞可以横着或者竖着飞<br>
			吃了跳可以斜着飞<br>
			吃了冬可以增加攻击力,同等级的话可以吃掉对方,但是不增加防御力<br>
			<div class="error-fox">vs</div>
			<div style=" text-align: center;">
				<p style="color: red;">
					<span v-if="game.p == game.p1"> --> P1 <-- </span>
					<span v-if="game.p != game.p1">P1</span>
				</p>
				<p style="color: blue;">
					<span v-if="game.p == game.p2"> --> P2 <-- </span>
					<span v-if="game.p != game.p2">P2</span>
				</p>
			</div>
			
			
			<div class="game-fox">
				<!-- 棋子 -->
				<div class="card-fox">
					<div class="card" 
						v-for="(card, index) in card_array" 
						:class=" 'c-tran-' + card.status "
						:style="{left: (card.x * 100) + 'px', top: (card.y * 100) + 'px'}">
						<div class="card-nr" 
							:class="['card-cs-' + card.status, card.fanpai == true ? 'card-fanpai' : null, card.hover == true ? 'card-hover' : null]"  
							>
							<br>
							<span v-if="card.status != 1" :style="{color: card.color}">{{card.name}}</span>
							<br>
							<span class="card-ftd">{{card.tools}}</span>
						</div>
					</div>
				</div>
				<!-- 棋盘 -->
				<div class="qipan-fox">
					<div class="qipan">
						<div class="qipan-nr" 
							v-for="qipan in qipan_array" 
							@mouseover="qipan_mouseover(qipan) "
							@mouseout="qipan_mouseout(qipan) "
							@click="click_qipan(qipan)" 
							:style="{left: (qipan.x * 100) + 'px', top: (qipan.y * 100) + 'px'}"> 
							<div class="zuobiao" :class=" qipan.zb_show == true ? 'zuobiao-show' : '' "></div>
						</div>
					</div>
				</div>
				
				<!-- 棋盘线 -->
				<div style="width: 300px; height: 300px; position: absolute; left: 50px; top: 50px; z-index: -1;">
					<div class="xd-td" style="left: 0px; top: 0px;"> </div>
					<div class="xd-td" style="left: 0px; top: 100px;"> </div>
					<div class="xd-td" style="left: 0px; top: 200px;"> </div>
					
					<div class="xd-td" style="left: 100px; top: 0px;"> </div>
					<div class="xd-td" style="left: 100px; top: 100px;"> </div>
					<div class="xd-td" style="left: 100px; top: 200px;"> </div>
					
					<div class="xd-td" style="left: 200px; top: 0px;"> </div>
					<div class="xd-td" style="left: 200px; top: 100px;"> </div>
					<div class="xd-td" style="left: 200px; top: 200px;"> </div>
				</div>
				
			</div>
			
			
		</div>

		<script src="https://cdn.jsdelivr.net/npm/vue"></script>
		<!-- <script src="../sa.js"></script> -->
		<script>
			
			var game = {
				p1: {
					g: 1, 
					color: 'red'
				}, 
				p2:  {
					g: 2, 
					color: 'blue'
				}
			}
			game.p = game.p1;	// 当前p 
			
			
			
			// 所有状态
			/*
			 * 1 = 未翻开
			 * 2 = 已翻开
			 * 3 = 鼠标悬浮
			 * 4 = 已选中 
			 */
			
			var card_array = [
				{g: 1, color: 'red', id: 1, name: '井', x: 0, y: 0, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 2, name: '丁', x: 1, y: 0, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 3, name: '石头', x: 2, y: 0, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 4, name: '剪刀', x: 3, y: 0, status: 1, fanpai: false, hover: false, tools: ''}, 
				
				{g: 1, color: 'red', id: 5, name: '布', x: 0, y: 1, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 6, name: '飞', x: 1, y: 1, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 7, name: '跳', x: 2, y: 1, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 1, color: 'red', id: 8, name: '冬', x: 3, y: 1, status: 1, fanpai: false, hover: false, tools: ''}, 
				
				{g: 2, color: 'blue', id: 1, name: '井', x: 0, y: 2, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 2, name: '丁', x: 1, y: 2, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 3, name: '石头', x: 2, y: 2, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 4, name: '剪刀', x: 3, y: 2, status: 1, fanpai: false, hover: false, tools: ''}, 
				
				{g: 2, color: 'blue', id: 5, name: '布', x: 0, y: 3, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 6, name: '飞', x: 1, y: 3, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 7, name: '跳', x: 2, y: 3, status: 1, fanpai: false, hover: false, tools: ''}, 
				{g: 2, color: 'blue', id: 8, name: '冬', x: 3, y: 3, status: 1, fanpai: false, hover: false, tools: ''}, 
			];
			
			// x坐标, y坐标, 状态  
			function getCard(x, y, status) {
				return {x: x, y: y, status: status};
			}
			
			// 生成所有 card
			function getCardArray() {
				var arr = [];
			}
			
			new Vue({
				el: '#app',
				data: {
					game: game,		// 游戏 
					card_array: [],	// 棋子
					qipan_array: [		// 棋盘
						{x: 0, y: 0, zb_show: false}, {x: 1, y: 0, zb_show: false}, {x: 2, y: 0, zb_show: false}, {x: 3, y: 0, zb_show: false},
						{x: 0, y: 1, zb_show: false}, {x: 1, y: 1, zb_show: false}, {x: 2, y: 1, zb_show: false}, {x: 3, y: 1, zb_show: false},
						{x: 0, y: 2, zb_show: false}, {x: 1, y: 2, zb_show: false}, {x: 2, y: 2, zb_show: false}, {x: 3, y: 2, zb_show: false},
						{x: 0, y: 3, zb_show: false}, {x: 1, y: 3, zb_show: false}, {x: 2, y: 3, zb_show: false}, {x: 3, y: 3, zb_show: false}
					],
					card_native: {}	// 当前选中的那个 
				},
				methods: {
					// 根据XY找棋盘
					getQipanByXY: function(x, y) {
						return this.qipan_array[x + y * 4 ];
					},
					// 根据棋盘找棋子
					getCardByQP: function(qipan) {
						for (var i = 0; i < this.card_array.length; i++) {
							if(this.card_array[i].x == qipan.x && this.card_array[i].y == qipan.y) {
								return this.card_array[i];
							}
						}
					},
					// 获得高亮棋子
					getCardGao: function() {
						for (var i = 0; i < this.card_array.length; i++) {
							if(this.card_array[i].status == 4) {
								return this.card_array[i];
							}
						}
					},
					// 棋盘悬浮 - 进入
					qipan_mouseover: function(qipan) {
						var card = this.getCardByQP(qipan);
						if(card != null && card.status != 4) {
							card.hover = true;
						}
					},
					// 棋盘悬浮 - 出
					qipan_mouseout: function(qipan) {
						var card = this.getCardByQP(qipan);
						if(card != null) {
							card.hover = false;
						}
					},
					// 点击棋盘
					click_qipan: function(qipan) {
						
						var card = this.getCardByQP(qipan);
						
						// 检查是否动子
						if(qipan.zb_show == true) {
							var card_gao = this.getCardGao(card);
							this.runCard(card_gao, qipan);
							toggleP();	// 切换P 
							return;
						}
						
						
						// 所有zb消失高亮 
						this.setZbsNot();	
						
						// 所有card失去活动
						this.setCardNot(card);
						
						this.click_card(card);
					},
					// 点击卡片
					click_card: function(card) {
						
						
						if(card == null){
							return;
						}
						
						// 如果是 1 == 未翻开 , 那就把它翻开 
						if(card.status == 1) {
							card.fanpai = true;	// 激发翻牌特效 
							setTimeout(function() {
								card.fanpai = false;
								card.status = 2;
							}, 200);
							toggleP();	// 切换P 
							return;
						}
						
						// 如果是 4 == 已选中 , 那就把它取消选中 
						if(card.status == 4) {
							return card.status = 2;

						}
						
						// 验证是否为本p 
						if(game.p.g != card.g) {
							return setError('这是对方的棋子');
						}
						
						// 如果是 2 == 已翻开 , 那就把它选中 
						if(card.status == 2) {
							card.status = 4;
							this.setZbs(card);
						}
						
					},
					// 动子
					runCard: function(card, qipan) {
						var card_2 = this.getCardByQP(qipan);	// 目标card
						card.x = qipan.x;
						card.y = qipan.y;
						
						// 如果是空位, 直接移动 
						if(card_2 == null) {
							
						} else {
							// 如果同g 
							if(card.g == card_2.g) {
								// 如果是吃装备
								if(card.id <= 5 && card_2.id > 5) {
									this.eatCard(card_2);
									card.tools += card_2.name;
								}
							} else {
								// 不同g 
								// 如果有冬, 通吃 
								if(card.tools.indexOf('冬') != -1) {
									this.eatCard(card_2);
								} else {
									// 无冬
									// 同id
									if (card.id == card_2.id) {
										this.eatCard(card);
										this.eatCard(card_2);
										setError('兑子:【' + card.name + '】');
									} else {
										// 根据前面的算法, 走到这一步必须是吃子
										this.eatCard(card_2);
									}
								}
								
							}
							
						}
						
						// 用此方法处理动画bug
						// 在这200s间隙里,可以非法操作
						setTimeout(function() {
							this.setCardNot();
							this.setZbsNot();
						}.bind(this), 200)
						
					},
					// 所有card取消高亮, 并有一个例外 
					setCardNot: function(card) {
						for(var i = 0; i < this.card_array.length; i++) {
							if(this.card_array[i].status == 4 && this.card_array[i] != card) {
								this.card_array[i].status = 2;
							}
						}
					},
					// 所有zb取消高亮
					setZbsNot: function() {
						this.qipan_array.forEach(function(item) {
							item.zb_show = false;
						});
					},
					// 推算一下zuobiao-show
					setZbs: function(card) {
						
						//var zbs_arr = [];	// 做标show起数组
						var x = card.x;
						var y = card.y;
						
						var zb_arr = [{x: x, y: y - 1}, {x: x + 1, y: y}, {x: x, y: y + 1}, {x: x - 1, y: y}];	// 所有坐标数组 
						var yx_arr = [];	// 有效坐标 
						var qipan_arr = [];		// 棋盘数组
						
						// 如果有飞 
						if(card.tools.indexOf('飞') != -1) {
							zb_arr.push({x: x, y: y - 2}, {x: x + 2, y: y}, {x: x, y: y + 2}, {x: x - 2, y: y});
							zb_arr.push({x: x, y: y - 3}, {x: x + 3, y: y}, {x: x, y: y + 3}, {x: x - 3, y: y});
						}
						
						// 如果有跳
						if(card.tools.indexOf('跳') != -1) {
							zb_arr.push({x: x + 1, y: y + 1}, {x: x + 1, y: y - 1}, {x: x - 1, y: y + 1}, {x: x - 1, y: y - 1});
							zb_arr.push({x: x + 2, y: y + 2}, {x: x + 2, y: y - 2}, {x: x - 2, y: y + 2}, {x: x - 2, y: y - 2});
							zb_arr.push({x: x + 3, y: y + 3}, {x: x + 3, y: y - 3}, {x: x - 3, y: y + 3}, {x: x - 3, y: y - 3});
						}
						
						// 找出有效坐标
						for (var i = 0; i < zb_arr.length; i++) {
							
							var zb = zb_arr[i];
							
							// 略过 无效坐标
							if(zb.x < 0 || zb.x > 3 || zb.y < 0 || zb.y > 3 ) {
								continue;
							}
							
							// 如果是空, 直接装
							var card_2 = this.getCardByQP(zb);	// 获得棋子 
							if(card_2 == null) {
								yx_arr.push(zb);
								continue;
							}
							
							// 略过 未翻开
							if(card_2.status == 1) {
								continue;
							}
							
							// 如果同 g
							if(card.g == card_2.g) {
								if(card.id <=5 && card_2.id >5) {
									yx_arr.push(zb);
								}
							} else {
								// 不同g
								// 如果同id, 直接装
								if(card.id == card_2.id) {
									yx_arr.push(zb);
								} else {
									// 不同id
									// 如果有冬, 全可杀
									if(card.tools.indexOf('冬') != -1) {
										yx_arr.push(zb);
									} else {
										// 没有冬
										// 如果可杀
										if(is_sha(card.id, card_2.id)) {
											yx_arr.push(zb);
										}
									}
									
								}
								
							}
							
							
						}
						
						// alert(yx_arr.length);
						// 使其高亮 
						yx_arr.forEach(function(item) {
							var qipan = this.getQipanByXY(item.x, item.y);
							if(qipan) {
								qipan.zb_show = true;
							}
						}.bind(this));
						
					},
					// 吃子
					eatCard: function(card) {
						// 移除此子
						var index = this.card_array.indexOf(card);
						if (index > -1) {
						    this.card_array.splice(index, 1);
						}
						// 吃掉子: 
						setError("吃子:【" + card.name + "】!");
					}
				},
				created: function(){
					var zb_arr = [		// 坐标集合 
						{x: 0, y: 0}, {x: 1, y: 0}, {x: 2, y: 0}, {x: 3, y: 0},
						{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1},
						{x: 0, y: 2}, {x: 1, y: 2}, {x: 2, y: 2}, {x: 3, y: 2},
						{x: 0, y: 3}, {x: 1, y: 3}, {x: 2, y: 3}, {x: 3, y: 3}
					]
					var new_arr = [];
					
					for (var i = 0; i < card_array.length; i++) {
						var index = randomNum(0, card_array.length - 1);	// 随机一个坐标
						var index_zb = randomNum(0, card_array.length - 1);	// 随机一个坐标
						var card = card_array[index];	
						var zb = zb_arr[index_zb];
						card_array.splice(index, 1);	// 删除 
						zb_arr.splice(index_zb, 1);	// 删除 
						i--;
						
						card.x = zb.x; 
						card.y = zb.y; 
						new_arr.push(card);
					}
					
					card_array.forEach(function(item) {
						var index = randomNum(0, zb_arr.length - 1);
						var zb = zb_arr[index];	// 随机一个坐标
						zb_arr.splice(index, 1);	// 删除 
						// 赋值
						item.x = zb.x; 
						item.y = zb.y; 
					})
					
					// 
					
					// 动画添加到棋盘 
					var i = 0;
					var time = setInterval(function() {
						this.card_array.push(new_arr[i]);
						// 如果没了
						i++;
						if(i == new_arr.length) {
							clearInterval(time);
						}
					}.bind(this), 100);
					
				}
			})
			
			// 判断a能否杀b
			function is_sha(aid, bid) {
				// 杀
				var arr = [
					[],
					[2, 3, 4   , 6, 7, 8],
					[4, 5   , 6, 7, 8],
					[2, 4   , 6, 7, 8],
					[5   , 6, 7, 8],
					[1, 3   , 6, 7, 8],
					[],
					[],
					[]
				];
				return arr[aid].indexOf(bid) != -1;
			}
			
			// 随机数 
			function randomNum(minNum, maxNum) {
				return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10)
			}
			
			// 写入错误提示
			function setError(msg) {
				document.querySelector('.error-fox').innerHTML = msg;
				clearTimeout(window.err_js);
				window.err_js = setTimeout(function() {
					document.querySelector('.error-fox').innerHTML = 'vs';
				}, 2000);
			}
			
			// 为game切换p
			function toggleP() {
				if(game.p == game.p1) {
					game.p = game.p2;
				} else {
					game.p = game.p1;
				}
			}
			
		</script>

	</body>
</html>