added timer
This commit is contained in:
parent
3c78b0cf8b
commit
b9c6db9586
@ -23,5 +23,9 @@ router.get('/roll', function (req, res){
|
|||||||
res.send({number: Math.ceil(Math.random() * 6)});
|
res.send({number: Math.ceil(Math.random() * 6)});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post('/move', function (req, res){
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
@ -18,6 +18,7 @@ var changeReadyState = (req, res, exit) =>{
|
|||||||
}
|
}
|
||||||
if(updatedPlayers.filter(player => player.ready).length >= 2){
|
if(updatedPlayers.filter(player => player.ready).length >= 2){
|
||||||
updatedDoc.started = true;
|
updatedDoc.started = true;
|
||||||
|
updatedDoc.nextMoveTime = Date.now()+15;
|
||||||
updatedDoc.players[0].nowMoving = true;
|
updatedDoc.players[0].nowMoving = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@ router.post('/add', function (req, res) {
|
|||||||
if (players.length === 4) {
|
if (players.length === 4) {
|
||||||
updateObj.full = true; // Room is full
|
updateObj.full = true; // Room is full
|
||||||
updateObj.started = true; // Game started
|
updateObj.started = true; // Game started
|
||||||
|
updateObj.nextMoveTime = Date.now()+15;
|
||||||
updateObj.players[0].nowMoving = true; //First joined player moving
|
updateObj.players[0].nowMoving = true; //First joined player moving
|
||||||
updateObj.pawns = getStartPositions();
|
updateObj.pawns = getStartPositions();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ var RoomSchema = new Schema({
|
|||||||
createDate: Date,
|
createDate: Date,
|
||||||
started: Boolean,
|
started: Boolean,
|
||||||
full: Boolean,
|
full: Boolean,
|
||||||
timer: Number,
|
nextMoveTime: Number,
|
||||||
players: [{
|
players: [{
|
||||||
name: String,
|
name: String,
|
||||||
color: String,
|
color: String,
|
||||||
|
|||||||
27
src/App.js
27
src/App.js
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, createContext } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import { Beforeunload } from 'react-beforeunload';
|
import { Beforeunload } from 'react-beforeunload';
|
||||||
@ -7,10 +7,10 @@ import { BrowserRouter as Router , Route , Redirect, Switch } from 'react-router
|
|||||||
import Gameboard from './components/Gameboard'
|
import Gameboard from './components/Gameboard'
|
||||||
import NameInput from './components/NameInput';
|
import NameInput from './components/NameInput';
|
||||||
|
|
||||||
function App() {
|
export const PlayerDataContext = createContext();
|
||||||
|
|
||||||
const [id, setId] = useState('');
|
function App() {
|
||||||
const [color, setColor] = useState('');
|
const [playerData, setPlayerData] = useState();
|
||||||
const [redirect, setRedirect] = useState();
|
const [redirect, setRedirect] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -19,11 +19,12 @@ function App() {
|
|||||||
mode: 'cors'
|
mode: 'cors'
|
||||||
})
|
})
|
||||||
.then( response => {
|
.then( response => {
|
||||||
setId(response.data.playerId);
|
setPlayerData(response.data)
|
||||||
setColor(response.data.color);
|
console.log(response.data);
|
||||||
|
|
||||||
response.data.roomId!=null ? setRedirect(true) : setRedirect(false);
|
response.data.roomId!=null ? setRedirect(true) : setRedirect(false);
|
||||||
});
|
});
|
||||||
},[id])
|
},[]);
|
||||||
|
|
||||||
const handleExit = e => {
|
const handleExit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -32,16 +33,16 @@ function App() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const idCallback = (id)=>{
|
const idCallback = () => {
|
||||||
axios.get('http://localhost:3000/player/', {
|
axios.get('http://localhost:3000/player/', {
|
||||||
withCredentials:true,
|
withCredentials:true,
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
setId(response.data.playerId);
|
setPlayerData(response.data);
|
||||||
setColor(response.data.color);
|
console.log(response.data);
|
||||||
setRedirect(true)
|
setRedirect(true);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,9 @@ function App() {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route path="/game">
|
<Route path="/game">
|
||||||
<Beforeunload onBeforeunload={handleExit}>
|
<Beforeunload onBeforeunload={handleExit}>
|
||||||
<Gameboard id={id} color={color}/>
|
<PlayerDataContext.Provider value={playerData}>
|
||||||
|
<Gameboard/>
|
||||||
|
</PlayerDataContext.Provider>
|
||||||
</Beforeunload>
|
</Beforeunload>
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|||||||
@ -1,26 +1,33 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
|
import { PlayerDataContext } from '../App'
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Map from './game-board-components/Map'
|
import Map from './game-board-components/Map'
|
||||||
import Dice from './game-board-components/Dice'
|
import Dice from './game-board-components/Dice'
|
||||||
import Navbar from './Navbar'
|
import Navbar from './Navbar'
|
||||||
|
|
||||||
const Gameboard = ({id, color}) => {
|
const Gameboard = () => {
|
||||||
|
// Context data
|
||||||
|
const context = useContext(PlayerDataContext);
|
||||||
|
const [id, setId] = useState();
|
||||||
|
// Render data
|
||||||
const [pawns, setPawns] = useState([]);
|
const [pawns, setPawns] = useState([]);
|
||||||
const [players, setPlayers] = useState([]);
|
const [players, setPlayers] = useState([]);
|
||||||
|
// Game logic data
|
||||||
const [rolledNumber, setRolledNumber] = useState('');
|
const [rolledNumber, setRolledNumber] = useState('');
|
||||||
|
const [time, setTime] = 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 game data
|
||||||
const fetchData = () => {
|
const fetchData = () => {
|
||||||
axios.get('http://localhost:3000/room/',{
|
axios.get('http://localhost:3000/room/',{
|
||||||
withCredentials:true,
|
withCredentials:true,
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
}).then((response)=>{
|
}).then((response)=>{
|
||||||
|
// Filling navbar with empty player nick container
|
||||||
while(response.data.players.length !== 4){
|
while(response.data.players.length !== 4){
|
||||||
response.data.players.push({
|
response.data.players.push({name: "...",});
|
||||||
name: "...",
|
};
|
||||||
})
|
// Checks if client is currently moving player by session ID
|
||||||
}
|
|
||||||
if(id===response.data.players.find(player => player.nowMoving === true)?._id){
|
if(id===response.data.players.find(player => player.nowMoving === true)?._id){
|
||||||
setNowMoving(true);
|
setNowMoving(true);
|
||||||
}else{
|
}else{
|
||||||
@ -28,10 +35,12 @@ const Gameboard = ({id, color}) => {
|
|||||||
}
|
}
|
||||||
setPlayers(response.data.players);
|
setPlayers(response.data.players);
|
||||||
setPawns(response.data.pawns);
|
setPawns(response.data.pawns);
|
||||||
|
setTime(response.data.nextMoveTime);
|
||||||
setStarted(response.data.started);
|
setStarted(response.data.started);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setId(context.playerId);
|
||||||
//sending ajax every 1 sec
|
//sending ajax every 1 sec
|
||||||
const interval = setInterval(fetchData, 1000);
|
const interval = setInterval(fetchData, 1000);
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
@ -43,9 +52,9 @@ const Gameboard = ({id, color}) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar players={players} started={started}/>
|
<Navbar players={players} started={started} time={time}/>
|
||||||
{nowMoving ? <Dice nowMoving={nowMoving} rolledNumberCallback={rolledNumberCallback}/> : null}
|
{nowMoving ? <Dice nowMoving={nowMoving} rolledNumberCallback={rolledNumberCallback}/> : null}
|
||||||
<Map pawns={pawns} nowMoving={nowMoving} color={color} rolledNumber={rolledNumber}/>
|
<Map pawns={pawns} nowMoving={nowMoving} rolledNumber={rolledNumber}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -2,11 +2,11 @@ import React from 'react';
|
|||||||
import NameContainer from './navbar-components/NameContainer'
|
import NameContainer from './navbar-components/NameContainer'
|
||||||
import ReadyButton from './navbar-components/ReadyButton'
|
import ReadyButton from './navbar-components/ReadyButton'
|
||||||
import './Navbar.css';
|
import './Navbar.css';
|
||||||
const Navbar = ( { players, started }) => {
|
const Navbar = ({ players, started, time }) => {
|
||||||
return(
|
return(
|
||||||
<div className = "navbar-container">
|
<div className = "navbar-container">
|
||||||
{players.map((player, index) =>
|
{players.map((player, index) =>
|
||||||
<NameContainer key={index} player = {player}/>
|
<NameContainer key = {index} player = {player} time = {time}/>
|
||||||
)}
|
)}
|
||||||
{started ? null : <ReadyButton/>}
|
{started ? null : <ReadyButton/>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState, useContext } from 'react';
|
||||||
|
import { PlayerDataContext } from '../../App';
|
||||||
|
import axios from 'axios';
|
||||||
import positions from './positions';
|
import positions from './positions';
|
||||||
import './Map.css';
|
import './Map.css';
|
||||||
|
|
||||||
const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
const Map = ({ pawns, nowMoving, rolledNumber }) => {
|
||||||
|
const context = useContext(PlayerDataContext);
|
||||||
|
const [color, setColor] = useState();
|
||||||
const [hintPawn, setHintPawn] = useState();
|
const [hintPawn, setHintPawn] = useState();
|
||||||
|
|
||||||
const paintPawn = (context, x, y, color) =>{
|
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);
|
||||||
@ -26,6 +31,11 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
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)) {
|
||||||
|
axios.post('http://localhost:3000/game/move', {
|
||||||
|
withCredentials: true,
|
||||||
|
mode: 'cors',
|
||||||
|
data: {_id: pawn._id}
|
||||||
|
});
|
||||||
setHintPawn(null);
|
setHintPawn(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,6 +75,7 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
if(nowMoving && rolledNumber){
|
if(nowMoving && rolledNumber){
|
||||||
const canvas = canvasRef.current;
|
const canvas = canvasRef.current;
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
|
// Gets x and y cords of mouse on canvas
|
||||||
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;
|
||||||
@ -81,7 +92,7 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
if (context.isPointInPath(pawn.circle, x, y) && pawn.color === color && (pawn.position>15 || rolledNumber === 1 || rolledNumber === 6)) {
|
if (context.isPointInPath(pawn.circle, x, y) && pawn.color === color && (pawn.position>15 || rolledNumber === 1 || rolledNumber === 6)) {
|
||||||
canvas.style.cursor = "pointer";
|
canvas.style.cursor = "pointer";
|
||||||
const pawnPosition = getHintPawnPosition(pawn);
|
const pawnPosition = getHintPawnPosition(pawn);
|
||||||
setHintPawn({x: positions[pawnPosition].x, y: positions[pawnPosition].y, color: 'grey'});
|
setHintPawn({id: pawn._id, x: positions[pawnPosition].x, y: positions[pawnPosition].y, color: 'grey'});
|
||||||
break;
|
break;
|
||||||
}else{
|
}else{
|
||||||
setHintPawn(null);
|
setHintPawn(null);
|
||||||
@ -91,10 +102,10 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const rerenderCanvas = () => {
|
const rerenderCanvas = () => {
|
||||||
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, index) => {
|
pawns.forEach( (pawn, index) => {
|
||||||
@ -107,8 +118,10 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
}
|
}
|
||||||
// Rerender canvas when pawns have changed
|
// Rerender canvas when pawns have changed
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setColor(context.color);
|
||||||
rerenderCanvas();
|
rerenderCanvas();
|
||||||
}, [pawns]);
|
}, [pawns]);
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<canvas
|
<canvas
|
||||||
className="canvas-container"
|
className="canvas-container"
|
||||||
@ -120,4 +133,4 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default Map
|
export default Map;
|
||||||
@ -5,6 +5,17 @@
|
|||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.timer{
|
||||||
|
background-color: darkblue;
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
top: -20px;
|
||||||
|
left: 15px;
|
||||||
|
width: 30px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
@ -1,10 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './NameContainer.css'
|
import './NameContainer.css';
|
||||||
const NameContainer = ( {player} ) => {
|
const NameContainer = ( {player, time} ) => {
|
||||||
|
const getRemainingTime = () => {
|
||||||
|
return Math.floor((time - Date.now())/1000);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="name-container"
|
<div className="name-container"
|
||||||
style={ player.ready ? { backgroundColor: player.color} : { backgroundColor: 'grey'} }>
|
style={ player.ready ? { backgroundColor: player.color} : { backgroundColor: 'grey'} }>
|
||||||
{player.name}
|
{player.name}
|
||||||
|
{player.nowMoving ? <div className="timer"> {getRemainingTime()} </div> : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user