# React斗兽棋 **Repository Path**: lin-liangyou/react-beast-fighting-chess ## Basic Information - **Project Name**: React斗兽棋 - **Description**: 传统斗兽棋玩法的实现,用react实现 - **Primary Language**: JavaScript - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-09-10 - **Last Updated**: 2022-06-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: React, Ant-Design, 棋类游戏 ## README # 如何使用? ## Available Scripts 下载源码后进入目录,你可以使用以下命令: ### `yarn install` 安装依赖包,过程会有点久。 ### `yarn start` 启动项目。 Runs the app in the development mode.\ Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.\ You will also see any lint errors in the console. ### `yarn build` Builds the app for production to the `build` folder.\ It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes.\ Your app is ready to be deployed! @[TOC](基于React + Antd 实现的斗兽棋web应用) # 项目简介 很高兴能以这种方式认识你,这个项目源自于学习了React官方的井字棋入门,想换一种方式,实战一下。 ## 功能规划 - [x] 已实现 - [ ] 未实现 - - [x] 棋盘渲染 - - [x] 棋子移动 - - [x] 根据棋子特性的特别移动规则 - - [x] 地形限制 - - [x] 陷阱 - - [x] 进入洞穴结束 - - [ ] 更改选棋 - - [ ] 贴图渲染 - - [ ] 界面优化 ## 项目源码 具体源码前往:[https://gitee.com/lin-liangyou/react-beast-fighting-chess](https://gitee.com/lin-liangyou/react-beast-fighting-chess) ### 棋盘渲染 和React官方教学案例一样思路,将棋盘的棋格单独成组件,设立属性如`mapitem`,然后使用`gamemap`包裹起来处理。 #### mapitem ```javascript import React from 'react'; import './item.css'; const Item = (props)=>{ return( ) } export default Item; ``` #### gamemap(部分) ```javascript const Map = ()=>{ //... const listRush = () =>{ const mapAll = []; let mapLine = []; list.forEach(function(item,index) { const { listName, type } = mapInit(index); mapLine.push( itemTouch(event) } index={index}/>); if( (index + 1) % 7 === 0 ){ mapLine.push(
); let parentLine =
{mapLine}
mapAll.push(parentLine); mapLine = []; } }) return mapAll; } return (
{`next player:${nextPlayer}`}
{ listRush() }
) } export default Map; ``` #### map.json 为了代码长度缩减,将用到的静态数据封装到`map.json`里面,`list`是地形布局,`mapPOS`则是每个棋盘对应的ID,其他的如此类推,`ALsit`与`BList`则是存储棋子的数组,顺序按照`listName` ```json { "list": [ 0,0,2,3,2,0,0, 0,0,0,2,0,0,0, 0,0,0,0,0,0,0, 0,1,1,0,1,1,0, 0,1,1,0,1,1,0, 0,1,1,0,1,1,0, 0,0,0,0,0,0,0, 0,0,0,2,0,0,0, 0,0,2,3,2,0,0 ], "mapPOS": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62 ], "mapRiver":[ 22, 23, 25, 26, 29, 30, 32, 33, 36, 37, 39, 40 ], "mapRiverBank":[ 15, 16, 18, 19, 21, 24, 27, 28, 31, 34, 35, 38, 41, 43, 44, 46, 47 ], "mapTrap":[ 2, 4, 10, 52, 58 ,60 ], "gameOver":[ 3, 59 ], "listName":[ "鼠","猫","狗","狼","豹","虎","狮","象" ], "AList":[ 20, 12, 8, 18, 16, 6, 0, 14 ], "BList":[ 42, 50, 54, 44, 46, 56, 62, 48 ] } ``` ### 棋子移动 && 规则特性 && 地形规则 && 游戏结束 #### gamemap(部分) ```javascript const itemTouch = (e)=>{ let point = Number(e.target.dataset.index); //判断是否为首次选子 if(choose[0] === 99){//选子状态 //合理判断 if(nextPlayer === 'Red'){ if(AList.indexOf(point) === -1){ message.warn('选子错误!'); return; }else{//合理 -> 记录棋子类型 setChessType( AList.indexOf(point) ); } }else{ if(BList.indexOf(point) === -1){ message.warn('选子错误!'); return; }else{//合理 -> 记录棋子类型 setChessType( BList.indexOf(point) ); } } //合理 -> 选子 setChoose([point,99]); }else{//落子状态 //落子逻辑 -> 落子点判断 const fristPoint = mapPOS.indexOf(choose[0]); const comparePoint = mapPOS.indexOf(point); const number = comparePoint - fristPoint; if( Math.abs(number) === 7 || Math.abs(number) === 1){//距离计算 value:1 //下水判断 if( mapRiver.indexOf(point) !== -1 ){// 落子点 是否为水 if(chessType === 0){ }else{ message.warn('落子错误,只有鼠才能入水!'); return } } }else if(chessType === 6 || chessType === 5){ console.log(`当前位置:${choose[0]}`); if(mapRiverBank.indexOf(choose[0]) !== -1){//河岸判断 if( Math.abs(number) === 28 || Math.abs(number) === 3){//距离计算 value:3 || 2 }else{ message.warn('落子错误,你怎么跃的?!'); return; } }else{ message.warn('落子错误,前往河岸才可跳跃!'); return; } }else{ message.warn('落子错误,行动格错误!'); return; } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // 吃子 && 行动 逻辑过程 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- if(nextPlayer === 'Red'){//玩家判断 -> Red行动 if( AList.indexOf(point) === -1){//踩子判断 //吃子判断 const enemy = BList.indexOf(point); if(enemy !== -1){// 落子点 踩敌判断 // 踩敌 -> 大小比拼 if( chessType >= enemy ){ //列表移除 BList[enemy] = 99; }else if( chessType === 0 && enemy === 7){//特殊点 1 鼠象关系 //列表移除 BList[enemy] = 99; }else if( mapTrap.indexOf(point) !== -1 ){//陷阱判断 //列表移除 BList[enemy] = 99; }else{ message.warn(`落子错误,打不过!它比你大${enemy-chessType}级`); return; } } //棋格行动 const obj = AList.indexOf(choose[0]); AList[obj] = point; }else{ message.warn('落子错误,落子点有同伴!'); return; } }else{//Blue行动 if( BList.indexOf(point) === -1){//踩子判断 //吃子判断 const enemy = AList.indexOf(point); if(enemy !== -1){// 落子点 踩敌判断 // 踩敌 -> 大小比拼 if( chessType >= enemy ){ //列表移除 AList[enemy] = 99; }else if( chessType === 0 && enemy === 7){ //列表移除 AList[enemy] = 99; }else if( mapTrap.indexOf(point) !== -1 ){//陷阱判断 //列表移除 AList[enemy] = 99; }else{ message.warn(`落子错误,打不过!它比你大${enemy-chessType}级`); return; } } //棋格行动 const obj = BList.indexOf(choose[0]); BList[obj] = point; }else{ message.warn('落子错误,落子点有同伴!'); return; } } //游戏结束状态判断 if(gameOver.indexOf(point) !== -1){ alert(`游戏结束,恭喜${nextPlayer}胜利\n点击确认重新开始!!`); window.location.reload(); } //落子还原 -=-=- 结束动作 setChoose([99,99]); setChessType(null); if( nextPlayer === 'Red' )setNextPlayer('Blue'); else setNextPlayer('Red'); } } ``` 新人第一次发帖,欢迎大家指正批评。