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)});
|
||||
});
|
||||
|
||||
router.post('/move', function (req, res){
|
||||
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
||||
@ -18,6 +18,7 @@ var changeReadyState = (req, res, exit) =>{
|
||||
}
|
||||
if(updatedPlayers.filter(player => player.ready).length >= 2){
|
||||
updatedDoc.started = true;
|
||||
updatedDoc.nextMoveTime = Date.now()+15;
|
||||
updatedDoc.players[0].nowMoving = true;
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +57,7 @@ router.post('/add', function (req, res) {
|
||||
if (players.length === 4) {
|
||||
updateObj.full = true; // Room is full
|
||||
updateObj.started = true; // Game started
|
||||
updateObj.nextMoveTime = Date.now()+15;
|
||||
updateObj.players[0].nowMoving = true; //First joined player moving
|
||||
updateObj.pawns = getStartPositions();
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ var RoomSchema = new Schema({
|
||||
createDate: Date,
|
||||
started: Boolean,
|
||||
full: Boolean,
|
||||
timer: Number,
|
||||
nextMoveTime: Number,
|
||||
players: [{
|
||||
name: 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 { Beforeunload } from 'react-beforeunload';
|
||||
@ -7,10 +7,10 @@ import { BrowserRouter as Router , Route , Redirect, Switch } from 'react-router
|
||||
import Gameboard from './components/Gameboard'
|
||||
import NameInput from './components/NameInput';
|
||||
|
||||
function App() {
|
||||
export const PlayerDataContext = createContext();
|
||||
|
||||
const [id, setId] = useState('');
|
||||
const [color, setColor] = useState('');
|
||||
function App() {
|
||||
const [playerData, setPlayerData] = useState();
|
||||
const [redirect, setRedirect] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
@ -19,11 +19,12 @@ function App() {
|
||||
mode: 'cors'
|
||||
})
|
||||
.then( response => {
|
||||
setId(response.data.playerId);
|
||||
setColor(response.data.color);
|
||||
setPlayerData(response.data)
|
||||
console.log(response.data);
|
||||
|
||||
response.data.roomId!=null ? setRedirect(true) : setRedirect(false);
|
||||
});
|
||||
},[id])
|
||||
},[]);
|
||||
|
||||
const handleExit = e => {
|
||||
e.preventDefault();
|
||||
@ -32,16 +33,16 @@ function App() {
|
||||
});
|
||||
}
|
||||
|
||||
const idCallback = (id)=>{
|
||||
const idCallback = () => {
|
||||
axios.get('http://localhost:3000/player/', {
|
||||
withCredentials:true,
|
||||
mode: 'cors',
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then(response => {
|
||||
setId(response.data.playerId);
|
||||
setColor(response.data.color);
|
||||
setRedirect(true)
|
||||
setPlayerData(response.data);
|
||||
console.log(response.data);
|
||||
setRedirect(true);
|
||||
})
|
||||
}
|
||||
|
||||
@ -57,7 +58,9 @@ function App() {
|
||||
</Route>
|
||||
<Route path="/game">
|
||||
<Beforeunload onBeforeunload={handleExit}>
|
||||
<Gameboard id={id} color={color}/>
|
||||
<PlayerDataContext.Provider value={playerData}>
|
||||
<Gameboard/>
|
||||
</PlayerDataContext.Provider>
|
||||
</Beforeunload>
|
||||
</Route>
|
||||
</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 Map from './game-board-components/Map'
|
||||
import Dice from './game-board-components/Dice'
|
||||
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 [players, setPlayers] = useState([]);
|
||||
// Game logic data
|
||||
const [rolledNumber, setRolledNumber] = useState('');
|
||||
const [time, setTime] = useState();
|
||||
const [nowMoving, setNowMoving] = useState(false);
|
||||
const [started, setStarted] = useState(false);
|
||||
//fetching players data to display them in navbar
|
||||
// Fetching game data
|
||||
const fetchData = () => {
|
||||
axios.get('http://localhost:3000/room/',{
|
||||
withCredentials:true,
|
||||
mode: 'cors',
|
||||
}).then((response)=>{
|
||||
// Filling navbar with empty player nick container
|
||||
while(response.data.players.length !== 4){
|
||||
response.data.players.push({
|
||||
name: "...",
|
||||
})
|
||||
}
|
||||
response.data.players.push({name: "...",});
|
||||
};
|
||||
// Checks if client is currently moving player by session ID
|
||||
if(id===response.data.players.find(player => player.nowMoving === true)?._id){
|
||||
setNowMoving(true);
|
||||
}else{
|
||||
@ -28,10 +35,12 @@ const Gameboard = ({id, color}) => {
|
||||
}
|
||||
setPlayers(response.data.players);
|
||||
setPawns(response.data.pawns);
|
||||
setTime(response.data.nextMoveTime);
|
||||
setStarted(response.data.started);
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
setId(context.playerId);
|
||||
//sending ajax every 1 sec
|
||||
const interval = setInterval(fetchData, 1000);
|
||||
return () => clearInterval(interval);
|
||||
@ -43,9 +52,9 @@ const Gameboard = ({id, color}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar players={players} started={started}/>
|
||||
<Navbar players={players} started={started} time={time}/>
|
||||
{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 ReadyButton from './navbar-components/ReadyButton'
|
||||
import './Navbar.css';
|
||||
const Navbar = ( { players, started }) => {
|
||||
const Navbar = ({ players, started, time }) => {
|
||||
return(
|
||||
<div className = "navbar-container">
|
||||
{players.map((player, index) =>
|
||||
<NameContainer key={index} player = {player}/>
|
||||
<NameContainer key = {index} player = {player} time = {time}/>
|
||||
)}
|
||||
{started ? null : <ReadyButton/>}
|
||||
</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 './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 paintPawn = (context, x, y, color) =>{
|
||||
const circle = new Path2D();
|
||||
circle.arc(x, y, 12, 0, 2 * Math.PI);
|
||||
@ -26,6 +31,11 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
||||
y = event.clientY - rect.top;
|
||||
for(const pawn of pawns){
|
||||
if (context.isPointInPath(pawn.circle, x, y)) {
|
||||
axios.post('http://localhost:3000/game/move', {
|
||||
withCredentials: true,
|
||||
mode: 'cors',
|
||||
data: {_id: pawn._id}
|
||||
});
|
||||
setHintPawn(null);
|
||||
}
|
||||
}
|
||||
@ -65,6 +75,7 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
||||
if(nowMoving && rolledNumber){
|
||||
const canvas = canvasRef.current;
|
||||
const context = canvas.getContext('2d');
|
||||
// Gets x and y cords of mouse on canvas
|
||||
const rect = canvas.getBoundingClientRect(),
|
||||
x = event.clientX - rect.left,
|
||||
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)) {
|
||||
canvas.style.cursor = "pointer";
|
||||
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;
|
||||
}else{
|
||||
setHintPawn(null);
|
||||
@ -91,10 +102,10 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
||||
}
|
||||
};
|
||||
const rerenderCanvas = () => {
|
||||
const canvas = canvasRef.current
|
||||
const context = canvas.getContext('2d')
|
||||
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.src = 'https://img-9gag-fun.9cache.com/photo/a8GdpYZ_460s.jpg';
|
||||
image.onload = function() {
|
||||
context.drawImage(image, 0 , 0);
|
||||
pawns.forEach( (pawn, index) => {
|
||||
@ -107,8 +118,10 @@ const Map = ({ pawns, nowMoving, color, rolledNumber }) => {
|
||||
}
|
||||
// Rerender canvas when pawns have changed
|
||||
useEffect(() => {
|
||||
setColor(context.color);
|
||||
rerenderCanvas();
|
||||
}, [pawns]);
|
||||
|
||||
return(
|
||||
<canvas
|
||||
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;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: 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 './NameContainer.css'
|
||||
const NameContainer = ( {player} ) => {
|
||||
import './NameContainer.css';
|
||||
const NameContainer = ( {player, time} ) => {
|
||||
const getRemainingTime = () => {
|
||||
return Math.floor((time - Date.now())/1000);
|
||||
}
|
||||
return (
|
||||
<div className="name-container"
|
||||
style={ player.ready ? { backgroundColor: player.color} : { backgroundColor: 'grey'} }>
|
||||
{player.name}
|
||||
{player.nowMoving ? <div className="timer"> {getRemainingTime()} </div> : null}
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user