drag and drop play implemented, audio integrated
This commit is contained in:
Generated
+37
@@ -8,6 +8,7 @@
|
||||
"name": "chess-",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@mantine/core": "^6.0.14",
|
||||
"@mantine/hooks": "^6.0.14",
|
||||
@@ -376,6 +377,42 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dnd-kit/accessibility": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
|
||||
"integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dnd-kit/core": {
|
||||
"version": "6.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz",
|
||||
"integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==",
|
||||
"dependencies": {
|
||||
"@dnd-kit/accessibility": "^3.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.1",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dnd-kit/utilities": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
|
||||
"integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/babel-plugin": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@mantine/core": "^6.0.14",
|
||||
"@mantine/hooks": "^6.0.14",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,10 +1,14 @@
|
||||
import React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import Piece from './Piece';
|
||||
import { socket } from '../socket';
|
||||
import { Box, Flex } from '@mantine/core';
|
||||
import { useDroppable } from '@dnd-kit/core'
|
||||
|
||||
const Cell = ({ cellProps, selectedPiece, dispatch, myColor }) => {
|
||||
const { row, col, piece, marked } = cellProps;
|
||||
const { isOver, setNodeRef } = useDroppable({ id: row + "-" + col });
|
||||
const [isDropped, setIsDropped] = useState(false);
|
||||
|
||||
let bgColor = (selectedPiece?.row === row && selectedPiece?.col === col) ? 'bg-gray-100' : ((row + col) % 2 ? 'bg-stone-800' : 'bg-neutral-200');
|
||||
bgColor = marked && piece ? `bg-red-300` : bgColor;
|
||||
|
||||
@@ -25,10 +29,10 @@ const Cell = ({ cellProps, selectedPiece, dispatch, myColor }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const content = marked ? <Mark /> : <Piece piece={piece} />;
|
||||
const content = marked ? <Mark /> : <Piece piece={piece} row={row} col={col} dispatch={dispatch} />;
|
||||
|
||||
return (
|
||||
<Flex onClick={handleClick} w="75px" h="75px" bg={(row + col) % 2 ? 'gray' : 'white'} className={`w-12 h-12 md:w-20 md:h-20 ${bgColor} flex justify-center items-center relative`}>
|
||||
<Flex ref={setNodeRef} onClick={handleClick} w="75px" h="75px" bg={(row + col) % 2 ? 'gray' : 'white'} className={`w-12 h-12 md:w-20 md:h-20 ${bgColor} flex justify-center items-center relative`}>
|
||||
{content}
|
||||
</Flex>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Image } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDraggable } from '@dnd-kit/core'
|
||||
|
||||
const Piece = ({ piece }) => {
|
||||
const Piece = ({ piece, row, col, dispatch }) => {
|
||||
if (piece === null) return null;
|
||||
const { type, color } = piece;
|
||||
let logo;
|
||||
@@ -25,8 +26,25 @@ const Piece = ({ piece }) => {
|
||||
logo = color === 'W' ? 'king_white' : 'king_black';
|
||||
break;
|
||||
}
|
||||
|
||||
const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({
|
||||
id: row + '-' + col, data: {
|
||||
...piece, row, col
|
||||
}
|
||||
});
|
||||
const style = transform ? {
|
||||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
||||
cursor: isDragging ? 'grabbing' : 'pointer',
|
||||
zIndex: isDragging ? 100 : 20
|
||||
} : undefined;
|
||||
useEffect(() => {
|
||||
if (isDragging) {
|
||||
dispatch({ type: 'SELECT_PIECE', val: { row, col, color } });
|
||||
}
|
||||
}, [isDragging])
|
||||
|
||||
return (
|
||||
<Image src={`/src/assets/${logo}.png`} />
|
||||
<Image ref={setNodeRef} style={style} sx={{ cursor: 'pointer' }} {...listeners} {...attributes} src={`/src/assets/${logo}.png`} />
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import { blackColor, chessBoardInit, getPieceHint, pieces, whiteColor } from '..
|
||||
import Cell from '../../components/Cell';
|
||||
import { socket } from '../../socket';
|
||||
import { Flex } from '@mantine/core';
|
||||
import { DndContext } from '@dnd-kit/core'
|
||||
|
||||
|
||||
let myColor = 'W';
|
||||
|
||||
@@ -43,9 +45,15 @@ const reducer = (state, action) => {
|
||||
}
|
||||
|
||||
const ChessBoard = () => {
|
||||
const moveAudioRef = useRef(null);
|
||||
const captureAudioRef = useRef(null);
|
||||
const gameEndAudioRef = useRef(null);
|
||||
const checkAudioRef = useRef(null);
|
||||
|
||||
const [gameState, dispatch] = useReducer(reducer, {
|
||||
chessBoard: chessBoardInit(myColor), selectedPiece: null, possibleMoves: [], capturedPieces: [], myTurn: myColor === whiteColor
|
||||
});
|
||||
// console.log(gameState)
|
||||
|
||||
const chessBoardRef = useRef(gameState.chessBoard);
|
||||
chessBoardRef.current = gameState.chessBoard;
|
||||
@@ -68,7 +76,32 @@ const ChessBoard = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<DndContext onDragEnd={evt => {
|
||||
let [currentRow, currentCol] = evt.active.id.split('-');
|
||||
let [targetRow, targetCol] = evt.over.id.split('-');
|
||||
let piece = evt.active.data.current;
|
||||
if (gameState.chessBoard[targetRow][targetCol] && gameState.chessBoard[targetRow][targetCol]?.color !== myColor) {
|
||||
console.log('Captured by dragging');
|
||||
let payload = { fromRow: currentRow, fromCol: currentCol, toRow: targetRow, toCol: targetCol, color: piece.color };
|
||||
socket.emit('move', payload);
|
||||
captureAudioRef.current.play();
|
||||
dispatch({ type: 'CAPTURE_PIECE', val: payload }) // capture piece
|
||||
return;
|
||||
}
|
||||
let targetMarked = false;
|
||||
gameState.possibleMoves.forEach((move) => {
|
||||
if (move.row == targetRow && move.col == targetCol)
|
||||
targetMarked = true;
|
||||
});
|
||||
if (targetMarked) {
|
||||
console.log('Moved by dragging')
|
||||
let payload = { fromRow: currentRow, fromCol: currentCol, toRow: targetRow, toCol: targetCol };
|
||||
socket.emit('move', payload);
|
||||
moveAudioRef.current.play();
|
||||
dispatch({ type: 'MOVE_PIECE', val: payload, }); // move piece
|
||||
return;
|
||||
}
|
||||
}}>
|
||||
<Flex w="600px">
|
||||
<div>
|
||||
{gameState.chessBoard.map((line, row) => {
|
||||
@@ -83,21 +116,26 @@ const ChessBoard = () => {
|
||||
}
|
||||
}
|
||||
let piece = cell ? { type: cell.type, color: cell.color } : null;
|
||||
return <Cell
|
||||
key={col * 3 + 1}
|
||||
selectedPiece={gameState.selectedPiece}
|
||||
cellProps={{ row, col, piece, marked }}
|
||||
dispatch={dispatch}
|
||||
myColor={myColor}
|
||||
myTurn={gameState.myTurn}
|
||||
/>
|
||||
return (
|
||||
<Cell
|
||||
key={col * 3 + 1}
|
||||
selectedPiece={gameState.selectedPiece}
|
||||
cellProps={{ row, col, piece, marked }}
|
||||
dispatch={dispatch}
|
||||
myColor={myColor}
|
||||
myTurn={gameState.myTurn}
|
||||
/>)
|
||||
})}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Flex>
|
||||
</React.Fragment>
|
||||
<audio src='/src/assets/move-self.mp3' ref={moveAudioRef} />
|
||||
<audio src='/src/assets/capture.mp3' ref={captureAudioRef} />
|
||||
<audio src='/src/assets/game-end.webm.mp3' ref={gameEndAudioRef} />
|
||||
<audio src='/src/assets/move-check.mp3' ref={checkAudioRef} />
|
||||
</DndContext>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user