added hint pawns

This commit is contained in:
Wenszel 2021-04-25 18:23:30 +02:00
parent 3058c87fb6
commit 3c78b0cf8b
6 changed files with 179 additions and 34 deletions

View File

@ -48,9 +48,9 @@ router.post('/exit', function(req,res){
//return session data
router.get('/', (req,res)=>{
if(req.session.name){
// If session exist return sessions data to move player to game when he backs to site
if(req.session){
res.send({
name: req.session.name,
color: req.session.color,
playerId: req.session.playerId,
roomId: req.session.roomId,

View File

@ -40,7 +40,6 @@ router.post('/add', function (req, res) {
req.session.roomId = newRoom._id;
req.session.playerId = newRoom.players[0]._id;
req.session.color = newRoom.players[0].color;
req.session.name = req.body.name;
res.status(200).send(req.session.playerId);
})
.catch(err => res.status(400).json('Error: ' + err))
@ -59,7 +58,7 @@ router.post('/add', function (req, res) {
updateObj.full = true; // Room is full
updateObj.started = true; // Game started
updateObj.players[0].nowMoving = true; //First joined player moving
updateObj.pawns = startPositions
updateObj.pawns = getStartPositions();
}
RoomModel.findOneAndUpdate(
{ _id: results._id }, //find room by id
@ -67,8 +66,7 @@ router.post('/add', function (req, res) {
.then(()=>{
req.session.roomId = results._id;
req.session.playerId = updateObj.players[updateObj.players.length-1]._id;
req.session.name = req.body.name;
req.sessions.color = colors[players.length - 1];
req.session.color = colors[updateObj.players.length-1];
res.status(200).send(req.session.playerId);
});

View File

@ -7,6 +7,7 @@ import Navbar from './Navbar'
const Gameboard = ({id, color}) => {
const [pawns, setPawns] = useState([]);
const [players, setPlayers] = useState([]);
const [rolledNumber, setRolledNumber] = useState('');
const [nowMoving, setNowMoving] = useState(false);
const [started, setStarted] = useState(false);
//fetching players data to display them in navbar
@ -32,13 +33,19 @@ const Gameboard = ({id, color}) => {
}
useEffect(()=>{
//sending ajax every 1 sec
setInterval(fetchData, 1000);
const interval = setInterval(fetchData, 1000);
return () => clearInterval(interval);
},[]);
// Callback to handle dice rolling between dice and map component
const rolledNumberCallback = (number) => {
setRolledNumber(number);
}
return (
<>
<Navbar players={players} started={started}/>
{nowMoving ? <Dice nowMoving={nowMoving}/> : null}
<Map pawns={pawns} nowMoving={nowMoving} color={color}/>
{nowMoving ? <Dice nowMoving={nowMoving} rolledNumberCallback={rolledNumberCallback}/> : null}
<Map pawns={pawns} nowMoving={nowMoving} color={color} rolledNumber={rolledNumber}/>
</>
)

View File

@ -7,7 +7,7 @@ import four from '../../images/dice/4.png';
import five from '../../images/dice/5.png';
import six from '../../images/dice/6.png';
const Dice = () => {
const Dice = ({rolledNumberCallback}) => {
const [rolledNumber, setRolledNumber] = useState()
const [images] = useState([one, two, three, four, five, six]);
const handleRoll = () => {
@ -16,12 +16,14 @@ const Dice = () => {
const utterance = new SpeechSynthesisUtterance(response.data.number);
speechSynthesis.speak(utterance);
setRolledNumber(response.data.number);
rolledNumberCallback(response.data.number);
})
}
return(
<div>
{rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> : null }
<button onClick={handleRoll}>Roll number</button>
{rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> :
<button onClick={handleRoll}>Roll</button> }
</div>
)
}

View File

@ -1,23 +1,24 @@
import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import positions from './positions';
import './Map.css';
const Map = ({ pawns, nowMoving, color }) => {
const paintPawn = (context, x, y, color, id) =>{
const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
const [hintPawn, setHintPawn] = useState();
const paintPawn = (context, x, y, color) =>{
const circle = new Path2D();
circle.arc(x, y, 12, 0, 2 * Math.PI);
context.strokeStyle = 'black';
context.stroke(circle);
context.fillStyle = color;
context.fill(circle);
const currentPawnIndex = pawns.findIndex( pawn => pawn._id === id);
pawns[currentPawnIndex].circle = circle;
return circle;
}
const canvasRef = useRef(null);
const handleCanvasClick = event => {
if(!nowMoving){
// If hint pawn exist it means that pawn can move
if(hintPawn){
const canvas = canvasRef.current
const context = canvas.getContext('2d')
const rect = canvas.getBoundingClientRect(),
@ -25,42 +26,88 @@ const Map = ({ pawns, nowMoving, color }) => {
y = event.clientY - rect.top;
for(const pawn of pawns){
if (context.isPointInPath(pawn.circle, x, y)) {
alert(pawn._id);
setHintPawn(null);
}
}
}
}
const getHintPawnPosition = (pawn) => {
/*
Based on color (because specific color have specific base positions)
first if for each colors handle situation when pawn is in base
next if pawn is in the end or will go in there
else if pawn is on map
*/
switch (color){
case 'red':
if(pawn.position >= 0 && pawn.position <= 3){
return 16;
}
break;
case 'blue':
if(pawn.position >= 4 && pawn.position <= 7){
return 55;
}
break;
case 'green':
if(pawn.position >= 8 && pawn.position <= 11){
return 42;
}
break;
case 'yellow':
if(pawn.position >= 12 && pawn.position <= 15){
return 29;
}
break;
}
};
const handleMouseMove = event => {
if(!nowMoving){
const canvas = canvasRef.current
const context = canvas.getContext('2d')
if(nowMoving && rolledNumber){
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
const rect = canvas.getBoundingClientRect(),
x = event.clientX - rect.left,
y = event.clientY - rect.top;
document.querySelector("body").style.cursor = "default";
canvas.style.cursor = "default";
for (const pawn of pawns){
if(pawn.circle){
// Checks if current mouse location in above canvas pawn and if this pawn is same color as player
if (context.isPointInPath(pawn.circle, x, y) && pawn.color === color) {
document.querySelector("body").style.cursor = "pointer";
/*
This condition checks if mouse location is:
1) on pawn
2) is color of pawn same as player's
3) if pawn is on base is rolledNumber is 1 or 6 which allows pawn to exit base
And then sets cursor to pointer and paints hint pawn - where will be pawn after click
*/
if (context.isPointInPath(pawn.circle, x, y) && pawn.color === color && (pawn.position>15 || rolledNumber === 1 || rolledNumber === 6)) {
canvas.style.cursor = "pointer";
const pawnPosition = getHintPawnPosition(pawn);
setHintPawn({x: positions[pawnPosition].x, y: positions[pawnPosition].y, color: 'grey'});
break;
}else{
setHintPawn(null);
}
}
}
}
}
useEffect(() => {
};
const rerenderCanvas = () => {
const canvas = canvasRef.current
const context = canvas.getContext('2d')
var image = new Image();
image.src = 'https://img-9gag-fun.9cache.com/photo/a8GdpYZ_460s.jpg'
image.onload = function() {
context.drawImage(image, 0 , 0);
pawns.forEach( pawn => {
paintPawn(context, positions[pawn.position].x, positions[pawn.position].y, pawn.color, pawn._id);
})
pawns.forEach( (pawn, index) => {
pawns[index].circle = paintPawn(context, positions[pawn.position].x, positions[pawn.position].y, pawn.color);
});
if (hintPawn){
paintPawn(context, hintPawn.x, hintPawn.y, hintPawn.color);
}
}
}
// Rerender canvas when pawns have changed
useEffect(() => {
rerenderCanvas();
}, [pawns]);
return(
<canvas

View File

@ -19,6 +19,97 @@ const positions = [
{x: 392, y: 116},
{x: 392, y: 67},
{x: 343, y: 116},
// Map - starting from red field
{x: 45, y: 200},
{x: 76, y: 200},
{x: 107, y: 200},
{x: 138, y: 200},
{x: 169, y: 200},
{x: 200, y: 169},
{x: 200, y: 138},
{x: 200, y: 107},
{x: 200, y: 76},
{x: 200, y: 45},
{x: 200, y: 14},
// Top
{x: 230, y: 14},
{x: 261, y: 14},
{x: 261, y: 45},
{x: 261, y: 76},
{x: 261, y: 107},
{x: 261, y: 138},
{x: 261, y: 169},
{x: 291, y: 200},
{x: 321, y: 200},
{x: 352, y: 200},
{x: 383, y: 200},
{x: 414, y: 200},
{x: 445, y: 200},
// Right
{x: 445, y: 230},
{x: 445, y: 261},
{x: 414, y: 261},
{x: 383, y: 261},
{x: 352, y: 261},
{x: 321, y: 261},
{x: 291, y: 261},
{x: 261, y: 291},
{x: 261, y: 322},
{x: 261, y: 353},
{x: 261, y: 384},
{x: 261, y: 414},
{x: 261, y: 445},
// Bottom
{x: 230, y: 445},
{x: 200, y: 445},
{x: 200, y: 414},
{x: 200, y: 384},
{x: 200, y: 353},
{x: 200, y: 322},
{x: 200, y: 291},
{x: 169, y: 261},
{x: 138, y: 261},
{x: 107, y: 261},
{x: 76, y: 261},
{x: 45, y: 261},
{x: 15, y: 261},
// Left
{x: 15, y: 231},
// One behind red base
{x: 15, y: 200},
// Red end
{x: 45, y: 231},
{x: 76, y: 231},
{x: 107, y: 231},
{x: 138, y: 231},
{x: 169, y: 231},
// Blue end
{x: 231, y: 445},
{x: 231, y: 414},
{x: 231, y: 384},
{x: 231, y: 353},
{x: 231, y: 322},
{x: 231, y: 291},
// Green end
{x: 414, y: 231},
{x: 383, y: 231},
{x: 352, y: 231},
{x: 321, y: 231},
{x: 290, y: 231},
// Yellow base
{x: 230, y: 15},
{x: 230, y: 45},
{x: 230, y: 76},
{x: 230, y: 107},
{x: 230, y: 138},
{x: 230, y: 169},
];
export default positions;