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 //return session data
router.get('/', (req,res)=>{ 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({ res.send({
name: req.session.name,
color: req.session.color, color: req.session.color,
playerId: req.session.playerId, playerId: req.session.playerId,
roomId: req.session.roomId, roomId: req.session.roomId,

View File

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

View File

@ -7,6 +7,7 @@ import Navbar from './Navbar'
const Gameboard = ({id, color}) => { const Gameboard = ({id, color}) => {
const [pawns, setPawns] = useState([]); const [pawns, setPawns] = useState([]);
const [players, setPlayers] = useState([]); const [players, setPlayers] = useState([]);
const [rolledNumber, setRolledNumber] = useState('');
const [nowMoving, setNowMoving] = useState(false); const [nowMoving, setNowMoving] = useState(false);
const [started, setStarted] = useState(false); const [started, setStarted] = useState(false);
//fetching players data to display them in navbar //fetching players data to display them in navbar
@ -32,13 +33,19 @@ const Gameboard = ({id, color}) => {
} }
useEffect(()=>{ useEffect(()=>{
//sending ajax every 1 sec //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 ( return (
<> <>
<Navbar players={players} started={started}/> <Navbar players={players} started={started}/>
{nowMoving ? <Dice nowMoving={nowMoving}/> : null} {nowMoving ? <Dice nowMoving={nowMoving} rolledNumberCallback={rolledNumberCallback}/> : null}
<Map pawns={pawns} nowMoving={nowMoving} color={color}/> <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 five from '../../images/dice/5.png';
import six from '../../images/dice/6.png'; import six from '../../images/dice/6.png';
const Dice = () => { const Dice = ({rolledNumberCallback}) => {
const [rolledNumber, setRolledNumber] = useState() const [rolledNumber, setRolledNumber] = useState()
const [images] = useState([one, two, three, four, five, six]); const [images] = useState([one, two, three, four, five, six]);
const handleRoll = () => { const handleRoll = () => {
@ -16,12 +16,14 @@ const Dice = () => {
const utterance = new SpeechSynthesisUtterance(response.data.number); const utterance = new SpeechSynthesisUtterance(response.data.number);
speechSynthesis.speak(utterance); speechSynthesis.speak(utterance);
setRolledNumber(response.data.number); setRolledNumber(response.data.number);
rolledNumberCallback(response.data.number);
}) })
} }
return( return(
<div> <div>
{rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> : null } {rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> :
<button onClick={handleRoll}>Roll number</button> <button onClick={handleRoll}>Roll</button> }
</div> </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 positions from './positions';
import './Map.css'; import './Map.css';
const Map = ({ pawns, nowMoving, color }) => { const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
const paintPawn = (context, x, y, color, id) =>{ const [hintPawn, setHintPawn] = useState();
const paintPawn = (context, x, y, color) =>{
const circle = new Path2D(); const circle = new Path2D();
circle.arc(x, y, 12, 0, 2 * Math.PI); circle.arc(x, y, 12, 0, 2 * Math.PI);
context.strokeStyle = 'black'; context.strokeStyle = 'black';
context.stroke(circle); context.stroke(circle);
context.fillStyle = color; context.fillStyle = color;
context.fill(circle); context.fill(circle);
const currentPawnIndex = pawns.findIndex( pawn => pawn._id === id); return circle;
pawns[currentPawnIndex].circle = circle;
} }
const canvasRef = useRef(null); const canvasRef = useRef(null);
const handleCanvasClick = event => { const handleCanvasClick = event => {
if(!nowMoving){ // If hint pawn exist it means that pawn can move
if(hintPawn){
const canvas = canvasRef.current const canvas = canvasRef.current
const context = canvas.getContext('2d') const context = canvas.getContext('2d')
const rect = canvas.getBoundingClientRect(), const rect = canvas.getBoundingClientRect(),
@ -25,42 +26,88 @@ const Map = ({ pawns, nowMoving, color }) => {
y = event.clientY - rect.top; y = event.clientY - rect.top;
for(const pawn of pawns){ for(const pawn of pawns){
if (context.isPointInPath(pawn.circle, x, y)) { 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 => { const handleMouseMove = event => {
if(!nowMoving){ if(nowMoving && rolledNumber){
const canvas = canvasRef.current const canvas = canvasRef.current;
const context = canvas.getContext('2d') const context = canvas.getContext('2d');
const rect = canvas.getBoundingClientRect(), const rect = canvas.getBoundingClientRect(),
x = event.clientX - rect.left, x = event.clientX - rect.left,
y = event.clientY - rect.top; y = event.clientY - rect.top;
document.querySelector("body").style.cursor = "default"; canvas.style.cursor = "default";
for (const pawn of pawns){ for (const pawn of pawns){
if(pawn.circle){ 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) { This condition checks if mouse location is:
document.querySelector("body").style.cursor = "pointer"; 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; break;
}else{
setHintPawn(null);
} }
} }
} }
} }
} };
const rerenderCanvas = () => {
useEffect(() => {
const canvas = canvasRef.current const canvas = canvasRef.current
const context = canvas.getContext('2d') const context = canvas.getContext('2d')
var image = new Image(); var image = new Image();
image.src = 'https://img-9gag-fun.9cache.com/photo/a8GdpYZ_460s.jpg' image.src = 'https://img-9gag-fun.9cache.com/photo/a8GdpYZ_460s.jpg'
image.onload = function() { image.onload = function() {
context.drawImage(image, 0 , 0); context.drawImage(image, 0 , 0);
pawns.forEach( pawn => { pawns.forEach( (pawn, index) => {
paintPawn(context, positions[pawn.position].x, positions[pawn.position].y, pawn.color, pawn._id); 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]); }, [pawns]);
return( return(
<canvas <canvas

View File

@ -19,6 +19,97 @@ const positions = [
{x: 392, y: 116}, {x: 392, y: 116},
{x: 392, y: 67}, {x: 392, y: 67},
{x: 343, y: 116}, {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; export default positions;