Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aryeh merge with master #73

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
200fce3
Refactored mainPlayer reducer, turn functions, and when the game star…
harryttd Feb 12, 2017
5ad8a21
Still working on it.
harryttd Feb 12, 2017
d0699f3
Refactored uneeded code like making too many dispatch calls to the st…
harryttd Feb 13, 2017
582f2cf
Cleaned up some code. Got rid of extra dispatch calls to the store. N…
harryttd Feb 13, 2017
bd517e6
Cleaned up some code. When one player crashes does not crash other pl…
harryttd Feb 15, 2017
21fce66
Merge branch 'master' into collision-bug
harryttd Feb 15, 2017
7bebac2
updated readme
harryttd Feb 15, 2017
a61b9e9
Updated tests
harryttd Feb 15, 2017
a642510
Update README.md
harryttd Feb 15, 2017
8d94ab4
Updated stylesheet
harryttd Feb 17, 2017
2cdb822
Merge branch 'collision-bug' of https://github.com/harryttd/3D_Tron i…
harryttd Feb 21, 2017
49d247b
Updated Readme
harryttd Feb 21, 2017
4e196de
Merge pull request #2 from harryttd/collision-bug
harryttd Feb 21, 2017
bcab7c0
Going through code trying to clean up and fix bugs. Refactor
harryttd Feb 26, 2017
3e17ff5
Seems I got automatic dying fixed...
harryttd Feb 26, 2017
cab8140
Moved collision event listener to socket file and put it where we set…
harryttd Feb 26, 2017
fe84bf5
Moved collision listener back to componentDidMount in Game Component
harryttd Feb 26, 2017
45c96a9
Merge pull request #3 from harryttd/collision-bug
harryttd Feb 26, 2017
f7638f2
Delete extra packages from package.json
harryttd Feb 26, 2017
bf393e6
Merge pull request #4 from harryttd/package.json
harryttd Feb 26, 2017
3d08a3d
Cleaned up react components. Fixed server users reducer test.
harryttd Feb 26, 2017
fd2b86e
Passed down props directly to DeadWithWinner component.
harryttd Feb 26, 2017
107b68e
Merge pull request #5 from harryttd/dumb-components
harryttd Feb 26, 2017
04d1b4c
Delete import connect from InGame file
harryttd Feb 26, 2017
cd4de9d
.DS_Store banished!
harryttd Feb 26, 2017
2313d01
Move redux-devtools-extension to regular depen.
harryttd Mar 1, 2017
c1374d0
Move nodemon to dev dep.
harryttd Mar 1, 2017
c62055f
Made game reload when game only had one player.
harryttd Mar 1, 2017
c61f959
Got rid of redux dev tools as they were creating an issue.
harryttd Mar 1, 2017
1292fa2
Add use strict to files
harryttd Mar 2, 2017
426e5f1
Made LobbyRoom component "dumb".
harryttd Mar 2, 2017
0c4f61c
update readme
harryttd Mar 2, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@
This is 3D multiplayer version of the classic Tron game where players compete to be the last rider standing.

## Live Game
To play a live version of this game please click here.
To play a live version of this game please click here http://3d-tron.com.

## Game Play Design
3D Tron is a fan variant of the classic Tron game, the player guides a Light Cycle in an arena against opponents, while avoiding the walls and trails of light left behind by all Light Cycles. The player must maneuver quickly and precisely in order to force opponents to run into walls or trails of light.
3D Tron is a fan variant of the classic Tron game, where players guide a Light Cycle in an arena against opponents, while avoiding the walls and trails of light left behind by all Light Cycles. The players must maneuver quickly and precisely in order to force opponents to run into walls or trails of light.

## Controls
User arrow keys to turn
Avoid the walls and trails of light left behind by all Light Cycles
User arrow or "w a s d" keys to turn.
Avoid the walls and trails of light left behind by other players.

## Architecture
3D Tron is built on Node.js using Socket.IO for client-server interaction, Three.js and Whitestorm.js for 3D graphics rendering, Physi.js for the physics engine, React for HTML rendering, and Redux for both client and server app state and game state management.
3D Tron is built on Node.js using Socket.io for client-server interaction, Three.js and Whitestorm.js for 3D graphics rendering, Physi.js for the physics engine, React for HTML rendering, and Redux for both client and server app state and game state management.

Handling of the game logic is distributed between the client and the server. Clients run their own physics calculations to compute their next position and orientation, while the server manages and modifies the master game state according to game logic and client events such as collisions with objects or other players.

## Set up on local machine
- Clone the repository
- npm install
- npm start (Runs webpack and starts the server on port 3000)
26 changes: 9 additions & 17 deletions browser/components/App.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
import React, { Component } from 'react';
'use strict';
import React from 'react';
import { connect } from 'react-redux';

import Game from './Game';
import Landing from './Landing';
import LobbyRoom from './LobbyRoom';

const App = ({ gameState }) => {

return (
<div>
{gameState.isEnter && !gameState.isPlaying && <Landing /> }
{!gameState.isEnter && !gameState.isPlaying && <LobbyRoom /> }
{gameState.isPlaying && <Game />}
</div>
const App = ({ gameState }) => (
<div>
{ gameState.isEnter && !gameState.isPlaying && <Landing /> }
{ !gameState.isEnter && !gameState.isPlaying && <LobbyRoom /> }
{ gameState.isPlaying && <Game /> }
</div>
);

};
// if(this.props.gameState === 'landing') render Landing
// if asdfasd = playing || dead render game

const mapStateToProps = ({ gameState }) => ({ gameState });
const mapDispatchToProps = null;

export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
export default connect(mapStateToProps, mapDispatchToProps)(App);
60 changes: 27 additions & 33 deletions browser/components/Chat.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import socket from '../socket';
import { startChat, stopChat } from '../reducers/gameState';



class Chat extends Component {
constructor(props){
Expand All @@ -16,7 +14,7 @@ class Chat extends Component {
}

componentWillUpdate(){
this.refs.messageBox.scrollTop = this.refs.messageBox.scrollHeight;
this.refs.messageBox.scrollTop = this.refs.messageBox.scrollHeight;
}


Expand All @@ -35,38 +33,34 @@ class Chat extends Component {
render() {
return (
<div id="chat-box">
<div id="message-box">
<ul ref="messageBox"
id="message-list"
className="collection">
{ this.props.messages && this.props.messages.map((message, i) => {
return (
<li key={i} className="message-item">
{`${message.name}: ${message.text}`}
</li>
)
})}
</ul>
</div>
<input ref="chatInput"
value={this.state.message}
onChange={this.updateMessage}
onKeyPress={evt => { if (evt.key === 'Enter') this.sendMessage(); }}
maxLength={70}
type="text"
id="chat-bar"
placeholder="press 'enter' to send"/>
<div id="message-box">
<ul ref="messageBox"
id="message-list"
className="collection">
{ this.props.messages && this.props.messages.map((message, i) => {
return (
<li key={i} className="message-item">
{`${message.name}: ${message.text}`}
</li>
);
})}
</ul>
</div>
<input
ref="chatInput"
value={this.state.message}
onChange={this.updateMessage}
onKeyPress={evt => { if (evt.key === 'Enter') this.sendMessage(); }}
maxLength={70}
type="text"
id="chat-bar"
placeholder="press 'enter' to send" />
</div>
);
);
}
}

const mapStateToProps = ({ messages, gameState }) => ({ messages, gameState });
const mapDispatchToProps = null;

const mapDispatchToProps = dispatch => ({
});

export default connect(
mapStateToProps,
mapDispatchToProps
)(Chat);
export default connect(mapStateToProps, mapDispatchToProps)(Chat);
81 changes: 31 additions & 50 deletions browser/components/Game.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,57 @@
'use strict';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import math from 'mathjs';
import world, { speed } from '../game/world';
import { turnPlayer } from '../reducers/mainPlayer';
import store from '../store';
import world from '../game/world';
import socket from '../socket';
import { cameraSetOnStart } from '../game/gamePlayFunctions'
import { DeadNoWinner, Winner, DeadWithWinner} from './InGame'

console.log("SOCKET ID LOCAL STORAGE (IN THE FRONT END)", localStorage.getItem('mySocketId'));
import { turnPlayer } from '../game/directionsFunctions';
import { cameraSetOnStart } from '../game/gamePlayFunctions';
import { DeadNoWinner, Winner, DeadWithWinner } from './InGame';

class Game extends Component {
constructor(props) {
super(props);
}

componentDidMount() {
console.log("CDM PROPS", this.props)
const players = this.props.players;
const myPlayer = this.props.mainPlayer;
world.start();
myPlayer.ball.add(world.camera);
cameraSetOnStart(myPlayer);
players.forEach(player => {
player.ball.native.addEventListener('collision', (collidedWith) => {
console.log("player", player)
console.log("collidedWith", collidedWith)
socket.emit('ball-collision', {signature: player.signature, id: player.id});
}, true);
player.si = setInterval(player.tail, 10);
});
cameraSetOnStart(this.props.mainPlayer)
}

render(){
const TURN_AUDIO = document.createElement('audio');
TURN_AUDIO.src = 'mp3/shortBikeTurn.m4a';
TURN_AUDIO.load();

if (this.props.mainPlayer) {
const player = this.props.mainPlayer;
player.ball.add(world.camera);
myPlayer.ball.native.addEventListener('collision', (collidedWith) => {
// console.log("collidedWith", collidedWith);
socket.emit('ball-collision', {signature: myPlayer.signature, id: myPlayer.id});
});

document.addEventListener('keydown', (event) => {
const validKeys = [37, 39, 38, 40, 87, 65, 83, 68];
if (validKeys.includes(event.keyCode)) {
store.dispatch(turnPlayer(event.keyCode));
TURN_AUDIO.play();
}
});
document.addEventListener('keydown', (event) => {
const TURN_AUDIO = document.createElement('audio');
TURN_AUDIO.src = 'mp3/shortBikeTurn.m4a';
TURN_AUDIO.load();
const validKeys = [37, 39, 38, 40, 87, 65, 83, 68];
if (validKeys.includes(event.keyCode)) {
turnPlayer(event.keyCode, myPlayer);
TURN_AUDIO.play();
}
});
}

document.addEventListener('keyup', (event) => {
const validKeys = [37, 39, 38, 40, 87, 65, 83, 68];
if (validKeys.includes(event.keyCode)) {
TURN_AUDIO.stop();
}
});
render() {
return (
<div>
{
{
this.props.mainPlayer.status === 'dead' && this.props.players.filter(player => player.winner === true).length === 0 ? <DeadNoWinner /> : null
}
{
this.props.mainPlayer.status === 'dead' && !this.props.mainPlayer.winner && this.props.players.filter(player => player.winner === true).length === 1 ? <DeadWithWinner /> : null
{
this.props.mainPlayer.status === 'dead' && !this.props.mainPlayer.winner && this.props.players.filter(player => player.winner).length === 1 ? <DeadWithWinner players={this.props.players} /> : null
}
{
this.props.mainPlayer.winner === true ? <Winner /> : null

{
this.props.mainPlayer.winner ? <Winner /> : null
}
</div>

);
} else {
return null
}

);
}
}

Expand Down
80 changes: 32 additions & 48 deletions browser/components/InGame.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,35 @@
import React, { Component } from 'react';
'use strict';
import React from 'react';

export const DeadNoWinner = () => {
return(
<div>
<div className="input-field">
<div id="title">You Crashed!</div>
</div>
<div id="general">
Click and drag with your mouse to watch the rest of the game!
</div>
</div>
)
}
export const DeadNoWinner = () => (
<div>
<div className="end-game">
<div id="title">You Crashed!</div>
</div>
<div id="general">
Click and drag with your mouse to watch the rest of the game!
</div>
</div>
);

export const Winner = () => {
return(
<div>
<div className="input-field">
<div id="title">You Win!</div>
</div>
<div id="general">
Game will reload home page soon
</div>
</div>
)
}
export const Winner = () => (
<div>
<div className="end-game">
<div id="title">You Win!</div>
</div>
<div id="general">
Game will reload home page soon
</div>
</div>
);

class dWW extends Component {
constructor(props){
super(props)
}
render(){
let winner = this.props.players.filter(player => player.winner === true)[0].playerName
return(
<div>
<div className="input-field">
<div id="title">{winner} Wins!</div>
</div>
<div id="general">
Game will reload home page soon
</div>
</div>
)

}
}

import { connect } from 'react-redux'

export const DeadWithWinner = connect(({ players }) => ({ players }))(dWW)
export const DeadWithWinner = ({ players }) => (
<div>
<div className="end-game">
<div id="title">{players.find(player => player.winner).playerName} Wins!</div>
</div>
<div id="general">
Game will reload home page soon
</div>
</div>
);
Loading