SRPT
by Sam Fereday
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.6.2/custom/phaser-arcade-physics.min.js"></script>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/recompose/0.26.0/Recompose.min.js"></script>
<div id="container"></div>
CSS
/*
* Skeleton V2.0.4
* Copyright 2014, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 12/29/2014
*/
/* Table of contents
––––––––––––––––––––––––––––––––––––––––––––––––––
- Grid
- Base Styles
- Typography
- Links
- Buttons
- Forms
- Lists
- Code
- Tables
- Spacing
- Utilities
- Clearing
- Media Queries
*/
/* Grid
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.container {
position: relative;
width: 100%;
max-width: 960px;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box;
}
.column,
.columns {
width: 100%;
float: left;
box-sizing: border-box;
}
/* For devices larger than 400px */
@media (min-width: 400px) {
.container {
width: 85%;
padding: 0;
}
}
/* For devices larger than 550px */
@media (min-width: 550px) {
.container {
width: 80%;
}
.column,
.columns {
margin-left: 4%;
}
.column:first-child,
.columns:first-child {
margin-left: 0;
}
.one.column,
.one.columns {
width: 4.66666666667%;
}
.two.columns {
width: 13.3333333333%;
}
.three.columns {
width: 22%;
}
.four.columns {
width: 30.6666666667%;
}
.five.columns {
width: 39.3333333333%;
}
.six.columns {
width: 48%;
}
.seven.columns {
width: 56.6666666667%;
}
.eight.columns {
width: 65.3333333333%;
}
.nine.columns {
width: 74.0%;
}
.ten.columns {
width: 82.6666666667%;
}
.eleven.columns {
width: 91.3333333333%;
}
.twelve.columns {
width: 100%;
margin-left: 0;
}
.one-third.column {
width: 30.6666666667%;
}
.two-thirds.column {
width: 65.3333333333%;
}
.one-half.column {
width: 48%;
}
/* Offsets */
.offset-by-one.column,
.offset-by-one.columns {
margin-left: 8.66666666667%;
}
.offset-by-two.column,
.offset-by-two.columns {
margin-left: 17.3333333333%;
}
.offset-by-three.column,
.offset-by-three.columns {
...
Babel + JSX
// DATA AREA
// Default location is anywhere that isn't found in locations list, and its coordinates can be generated
// when the ship has left warp. 0 is just a placeholder.
const DEFAULT_LOCATION = {
id: 'unknown',
x: 0,
y: 0,
meta: {
name: 'Unknown Quadrant'
}
};
// Assume light years for now :P
const LOCATIONS = [{
id: 'loc-1',
x: 100,
y: 2,
meta: {
name: 'Erebus Terminal'
}
}, {
id: 'loc-2',
x: 1,
y: 5,
meta: {
name: 'Novis Alpha'
}
}, {
id: 'loc-3',
x: 200,
y: 300,
meta: {
name: 'Heliuos Prime'
}
}];
// UTILS
const findLocationById = (id, arr) => {
return arr.find(x => x.id === id);
};
const distanceApprox = (p1, p2) => {
// https://gist.github.com/aurbano/4693462
const x = p2.x - p1.x;
const y = p2.y - p1.y;
return 1.426776695 * Math.min(0.7071067812 * (Math.abs(x) + Math.abs(y)), Math.max(Math.abs(x), Math.abs(y)));
};
// EVENTS GLOBAL
class Events {
constructor()
{
this.events = [];
this.subscribers = [];
}
getEventById(id) {
return this.events.find(ev => ev === id);
}
subscribe(id, cb) {
if(this.subscribers.some(x => x.id === id)) {
return;
}
this.subscribers.push({
id, cb
});
}
add(id) {
if(this.getEventById(id)) {
return;
}
this.events.push(id);
}
trigger(eventId, ...args) {
const ev = this.getEventById(eventId);
const subscribed = this.subscribers.filter(sub => sub.id === ev);
for(let i = 0; i < subscribed.length; i++) {
let { cb, ctx } = subscribed[i];
if(typeof cb === 'function') {
cb(...args);
}
}
}
}
const events = new Events();
// REACT UI AREA
const { compose, withState, withHandlers, lifecycle } = Recompose;
const AppComponent = ({
locations,
nextLocationId,
currentLocationId,
onHandleChange,
onTravelRequest
}) => {
return (
[
<select onChange={onHandleChange}>
{locations && locations.length &&
locations.map(({id, meta:...