112 lines
3.9 KiB
JavaScript
112 lines
3.9 KiB
JavaScript
import React, { useEffect, useRef, useState, useContext } from 'react';
|
|
import { PlayerDataContext, SocketContext } from '../../../App';
|
|
|
|
import mapImage from '../../../images/map.jpg';
|
|
import positions from '../positions';
|
|
import pawnImages from '../../../constants/pawnImages';
|
|
import canPawnMove from './canPawnMove';
|
|
import getPositionAfterMove from './getPositionAfterMove';
|
|
|
|
const Map = ({ pawns, nowMoving, rolledNumber }) => {
|
|
const player = useContext(PlayerDataContext);
|
|
const socket = useContext(SocketContext);
|
|
const canvasRef = useRef(null);
|
|
|
|
const [hintPawn, setHintPawn] = useState();
|
|
|
|
const paintPawn = (context, x, y, color) => {
|
|
const touchableArea = new Path2D();
|
|
touchableArea.arc(x, y, 12, 0, 2 * Math.PI);
|
|
const image = new Image();
|
|
image.src = pawnImages[color];
|
|
// image.onload = function () {
|
|
context.drawImage(image, x - 17, y - 14, 35, 30);
|
|
return touchableArea;
|
|
};
|
|
|
|
const handleCanvasClick = event => {
|
|
if (hintPawn) {
|
|
const canvas = canvasRef.current;
|
|
const ctx = canvas.getContext('2d');
|
|
const rect = canvas.getBoundingClientRect(),
|
|
cursorX = event.clientX - rect.left,
|
|
cursorY = event.clientY - rect.top;
|
|
for (const pawn of pawns) {
|
|
if (ctx.isPointInPath(pawn.touchableArea, cursorX, cursorY)) {
|
|
socket.emit('game:move', pawn._id);
|
|
}
|
|
}
|
|
setHintPawn(null);
|
|
}
|
|
};
|
|
|
|
const handleMouseMove = event => {
|
|
if (nowMoving && rolledNumber) {
|
|
const canvas = canvasRef.current;
|
|
const ctx = canvas.getContext('2d');
|
|
const rect = canvas.getBoundingClientRect(),
|
|
x = event.clientX - rect.left,
|
|
y = event.clientY - rect.top;
|
|
canvas.style.cursor = 'default';
|
|
for (const pawn of pawns) {
|
|
if (pawn.touchableArea) {
|
|
if (
|
|
ctx.isPointInPath(pawn.touchableArea, x, y) &&
|
|
player.color === pawn.color &&
|
|
canPawnMove(pawn, rolledNumber)
|
|
) {
|
|
const pawnPosition = getPositionAfterMove(pawn, rolledNumber);
|
|
if (pawnPosition) {
|
|
canvas.style.cursor = 'pointer';
|
|
setHintPawn({ id: pawn._id, position: pawnPosition, color: 'grey' });
|
|
break;
|
|
}
|
|
} else {
|
|
setHintPawn(null);
|
|
}
|
|
} else {
|
|
setHintPawn(null);
|
|
}
|
|
}
|
|
} else {
|
|
setHintPawn(null);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const rerenderCanvas = () => {
|
|
const canvas = canvasRef.current;
|
|
const ctx = canvas.getContext('2d');
|
|
const image = new Image();
|
|
image.src = mapImage;
|
|
image.onload = function () {
|
|
ctx.drawImage(image, 0, 0);
|
|
pawns.forEach((pawn, index) => {
|
|
pawns[index].touchableArea = paintPawn(
|
|
ctx,
|
|
positions[pawn.position].x,
|
|
positions[pawn.position].y,
|
|
pawn.color
|
|
);
|
|
});
|
|
if (hintPawn) {
|
|
paintPawn(ctx, positions[hintPawn.position].x, positions[hintPawn.position].y, hintPawn.color);
|
|
}
|
|
};
|
|
};
|
|
rerenderCanvas();
|
|
}, [hintPawn, pawns]);
|
|
|
|
return (
|
|
<canvas
|
|
className='canvas-container'
|
|
width={460}
|
|
height={460}
|
|
ref={canvasRef}
|
|
onClick={handleCanvasClick}
|
|
onMouseMove={handleMouseMove}
|
|
/>
|
|
);
|
|
};
|
|
export default Map;
|