可以点击跳到任意位置
click3.png click2.png click1.png
添加L形规则
屏幕快照 2018-03-12 16.51.53.pngDragSource
DropTarget
新建一个文件,为什么需要新建??
最后显示完整源码:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Board from './Board'
import Knight from './Knight'
import { observe } from './Game'
observe(knightPosition =>
ReactDOM.render(
<Board knightPosition={knightPosition}/>,
document.getElementById('root')
))
从Game.js 里导入observe,可以看到observe方法里,将参数赋值给observer,再调用emitChange方法。
参数是 knightPosition,也就是骑士的位置,【1,7】
knightPosition是Board的一个属性
// Game.js
let knightPosition = [1,7]
let observer = null
function emitChange() {
observer(knightPosition)
}
export function observe(o) {
observer = o;
emitChange();
}
export function moveKnight(toX, toY){
knightPosition = [toX, toY]
emitChange()
}
export function canMoveKnight(toX, toY) {
const [x, y] = knightPosition;
const dx = toX - x;
const dy = toY - y;
return (Math.abs(dx) === 2 && Math.abs(dy) === 1) ||
(Math.abs(dx) === 1 && Math.abs(dy) === 2);
}
// Knight.js
import React, { Component } from 'react';
import { ItemTypes } from './Constants'
import { DragSource } from 'react-dnd'
const knightSource = {
beginDrag(props) {
return {}
}
}
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}
}
class Knight extends Component {
render() {
const { connectDragSource, isDragging } = this.props
return connectDragSource(
<div style={{
opacity: isDragging ? 0.5 : 1,
fontSize: 25,
fontWeight: 'bold',
cursor: 'move'
}}>
♘
</div>
)
}
}
export default DragSource(ItemTypes.KNIGHT, knightSource, collect)(Knight)
// Square.js
import React, { Component } from 'react'
export default class Square extends Component {
render(){
const { black } = this.props;
const fill = black ? 'black' : 'white';
const stroke = black ? 'white' : 'black';
return (<div style={{
backgroundColor: fill,
color: stroke,
width: '30px',
height: '30px'
}}>
{this.props.children}
</div>
)
}
}
// Board.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Knight from './Knight'
import Square from './Square'
import { canMoveKnight, moveKnight } from './Game'
import { DragDropContext } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import BoardSquare from './BoardSquare'
class Board extends Component {
handleSquareClick(toX, toY) {
if (canMoveKnight(toX, toY)) {
moveKnight(toX, toY);
}
}
renderSquare(i) {
const x = i % 8;
const y = Math.floor(i / 8);
return (
<div key={i}
style={{width: '30px', height: '30px'}}>
<BoardSquare x={x} y={y}>
{this.renderPiece(x,y)}
</BoardSquare>
</div>
)
}
renderPiece(x,y){
const [knightX, knightY] = this.props.knightPosition
if (x === knightX && y === knightY){
return <Knight />
}
}
render(){
const squares = [];
for (let i = 0; i < 64; i++){
squares.push(this.renderSquare(i));
}
return (
<div style={{width: '240px',height: '240px',display:'flex',flexWrap:'wrap'}}>
{squares}
</div>
)
}
}
export default DragDropContext(HTML5Backend)(Board)
// BoardSquare.js
import React, {Component} from 'react'
import Square from './Square'
import { canMoveKnight, moveKnight } from './Game'
import { ItemTypes } from './Constants'
import { DropTarget } from 'react-dnd'
const squareTarget = {
drop(props) {
moveKnight(props.x, props.y)
},
canDrop(props){
return canMoveKnight(props.x, props.y)
}
}
function collect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop()
}
}
class BoardSquare extends Component {
renderOverlay(color){
return (
<div style={{position:'absolute',top:0,left:0,height:'100%',width:'100%',zIndex:1,opacity:0.5,backgroundColor:color}}/>
)
}
render(){
const { x, y, connectDropTarget, isOver, canDrop } = this.props;
const black = (x + y) % 2 === 1;
return connectDropTarget(
<div style={{position:'relative', width:'100%', height:'100%'}}>
<Square black={black}>
{this.props.children}
</Square>
{isOver && !canDrop && this.renderOverlay('red')}
{!isOver && canDrop && this.renderOverlay('yellow')}
{isOver && canDrop && this.renderOverlay('green')}
</div>
)
}
}
export default DropTarget(ItemTypes.KNIGHT, squareTarget, collect)(BoardSquare)
// Constants.js
export const ItemTypes = {
KNIGHT: 'knight'
}
网友评论