edited css and readme

This commit is contained in:
Wenszel 2021-04-30 12:24:19 +02:00
parent 7304922e86
commit c8773ed546
16 changed files with 67 additions and 67 deletions

View File

@ -1,11 +1,13 @@
# Online multiplayer Ludo
WORK IN PROGRESS ...
## About
**Ludo** is a strategy board game for two to four players, in which the players race their four tokens from start to finish according to the rolls of a single die. Like other cross and circle games, Ludo is derived from the Indian game Pachisi, but simpler. The game and its variations are popular in many countries and under various names. [Read more](https://en.wikipedia.org/wiki/Ludo_(board_game))
## Interface
![Interface](https://github.com/Wenszel/mern-ludo/blob/main/src/images/readme1.png?raw=true)
## Installation
Play this game [here]()
Play this game [here](https://smaga-wiktor-ludo.herokuapp.com)
```
npm i
npm start
@ -18,12 +20,15 @@ node server.js
### Backend
- Node.js
- Express
- express-session
- MongoDB
- Express-session
- MongoDB, Mongoose
- MongoDB sessions store
- Maybe Redis in future
### Frontend
- React
- Axios
- Material UI
- Canvas
## ToDo
- Redis
- SocketIO
- Add more game logic

View File

@ -32,7 +32,7 @@ router.post('/move', function (req, res){
doc.players[index+1].nowMoving = true;
}
// Updating timer
doc.nextMoveTime = Date.now()+30000;
doc.nextMoveTime = Date.now()+15000;
RoomModel.findOneAndUpdate({_id: req.session.roomId}, doc, function(err, doc){
res.send("Correctly Moved!");
});

View File

@ -18,7 +18,8 @@ var changeReadyState = (req, res, exit) =>{
}
if(updatedPlayers.filter(player => player.ready).length >= 2){
updatedDoc.started = true;
updatedDoc.nextMoveTime = Date.now()+30000;
updatedDoc.players = updatedDoc.players.map(player => player.ready === true);
updatedDoc.nextMoveTime = Date.now() + 15000;
updatedDoc.players[0].nowMoving = true;
}

View File

@ -58,7 +58,8 @@ 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()+30000;
updateObj.nextMoveTime = Date.now() + 15000;
updateObj.players = updateObj.players.map(player => player.ready === true);
updateObj.players[0].nowMoving = true; //First joined player moving
updateObj.pawns = getStartPositions();
}
@ -100,7 +101,7 @@ router.get('/', function(req,res){
}else{
doc.players[index + 1].nowMoving = true;
}
doc.nextMoveTime = Date.now()+30000;
doc.nextMoveTime = Date.now()+15000;
RoomModel.findOneAndUpdate({_id: req.session.roomId}, doc, function(err, docs){
if(err){
res.status(500).send(err)

View File

@ -2,20 +2,17 @@ const express = require("express");
const cors = require('cors');
const cookieParser = require('cookie-parser')
const session = require('express-session')
const bodyParser = require('body-parser');
const app = express();
app.use(cookieParser());
app.use(bodyParser.urlencoded({
app.use(express.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(express.json());
app.set('trust proxy', 1)
app.use(cors({
origin: [
'localhost:3001',
'http://localhost:3001',
'https://localhost:3001'
],
credentials: true,
}))

View File

@ -16,12 +16,9 @@ function App() {
useEffect(() => {
axios.get('http://localhost:3000/player', {
withCredentials:true,
mode: 'cors'
})
.then( response => {
.then(response => {
setPlayerData(response.data)
console.log(response.data);
response.data.roomId!=null ? setRedirect(true) : setRedirect(false);
});
},[]);
@ -29,15 +26,13 @@ function App() {
const handleExit = e => {
e.preventDefault();
window.addEventListener('unload', () => {
axios.post('http://localhost:3000/player/exit', {withCredentials:true, mode: 'cors'})
axios.post('http://localhost:3000/player/exit', {withCredentials:true, })
});
}
const idCallback = () => {
axios.get('http://localhost:3000/player/', {
withCredentials:true,
mode: 'cors',
headers: { "Content-Type": "application/json" },
})
.then(response => {
setPlayerData(response.data);

View File

@ -20,7 +20,6 @@ const Gameboard = () => {
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){
@ -36,6 +35,7 @@ const Gameboard = () => {
setNowMoving(false);
}
}
checkWin();
setPlayers(response.data.players);
setPawns(response.data.pawns);
setTime(response.data.nextMoveTime);
@ -43,6 +43,7 @@ const Gameboard = () => {
})
}
const checkWin = () => {
// Player wins when all pawns with same color are inside end base
if(pawns.filter(pawn => pawn.color === 'red' && pawn.position === 73).length === 4){
alert("Red Won")
}else if(pawns.filter(pawn => pawn.color === 'blue' && pawn.position === 79).length === 4){

View File

@ -1,7 +0,0 @@
.navbar-container{
display: flex;
flex-direction: row;
}
.navbar-container>div{
margin-right: 10px;
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import NameContainer from './navbar-components/NameContainer'
import ReadyButton from './navbar-components/ReadyButton'
import './Navbar.css';
const Navbar = ({ players, started, time }) => {
return(
<div className = "navbar-container">

View File

@ -8,7 +8,7 @@ import five from '../../images/dice/5.png';
import six from '../../images/dice/6.png';
const Dice = ({ rolledNumberCallback, nowMoving }) => {
const [rolledNumber, setRolledNumber] = useState()
const [rolledNumber, setRolledNumber] = useState();
const [images] = useState([one, two, three, four, five, six]);
const handleRoll = () => {
axios.get('http://localhost:3000/game/roll').then(response => {
@ -19,8 +19,8 @@ const Dice = ({ rolledNumberCallback, nowMoving }) => {
})
}
return(
<div>
{rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> : nowMoving ? <button onClick={handleRoll}>Roll</button> : null }
<div className="dice-container">
{rolledNumber ? <img src={images[rolledNumber - 1]} width="100" height="100"/> : nowMoving ? <button onClick={handleRoll}> Roll </button> : null}
</div>
)
}

View File

@ -1,3 +0,0 @@
.canvas-container{
margin: 10px;
}

View File

@ -2,7 +2,6 @@ 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, rolledNumber }) => {
const context = useContext(PlayerDataContext);
@ -44,8 +43,8 @@ const Map = ({ pawns, nowMoving, rolledNumber }) => {
}else{
return false;
}
}
const handleCanvasClick = event => {
// If hint pawn exist it means that pawn can move
if(hintPawn){
@ -56,10 +55,8 @@ const Map = ({ pawns, nowMoving, rolledNumber }) => {
y = event.clientY - rect.top;
for(const pawn of pawns){
if (ctx.isPointInPath(pawn.circle, x, y)) {
axios.post('http://localhost:3000/game/move', {pawnId: pawn._id, position: hintPawn.position},
{
withCredentials: true,
}).then(() => {
axios.post('http://localhost:3000/game/move', {pawnId: pawn._id, position: hintPawn.position}, {withCredentials: true})
.then(() => {
setHintPawn(null);
});
@ -125,7 +122,6 @@ const Map = ({ pawns, nowMoving, rolledNumber }) => {
return position + rolledNumber;
}
}
};
const handleMouseMove = event => {
if(nowMoving && rolledNumber){

View File

@ -1,21 +0,0 @@
.name-container{
width: 100px;
height: 50px;
border-radius: 5px;
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;
}

View File

@ -1,5 +1,5 @@
import React from 'react';
import './NameContainer.css';
const NameContainer = ( {player, time} ) => {
const getRemainingTime = () => {
return Math.round((time - Date.now())/1000)+1;
@ -11,7 +11,6 @@ const NameContainer = ( {player, time} ) => {
{player.nowMoving ? <div className="timer"> {getRemainingTime()} </div> : null}
</div>
)
}
export default NameContainer;

BIN
src/images/readme1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -4,3 +4,39 @@ body{
flex-direction: column;
align-items: center;
}
.canvas-container{
margin: 10px;
}
.dice-container{
position: absolute;
top: 30%;
left: 20%;
}
.navbar-container{
display: flex;
flex-direction: row;
}
.navbar-container>div{
margin-right: 10px;
}
.name-container{
width: 100px;
height: 50px;
border-radius: 5px;
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;
}