Skip to content

Commit

Permalink
Trains (#3)
Browse files Browse the repository at this point in the history
* WIP for store layout and two markets

* More wip

* View components are working

* Initial layout for market buys and player inventory

* Added store items and stub functions for buy and sell

* Buy operations working

* Sell functionality working

* Put store inventories in a separate module

* Namespaced the store and refactored to match

* WIP for adding trains

* Engine working with tick events

* Stub out a train component

* Standardized the engine and clock ticks

* Train movement working in one direction

* Returns the nested inventory objects with the train

* Shows the current status of the train

* Departures working
  • Loading branch information
pemcne authored Jul 18, 2018
1 parent cd0de90 commit aa71e65
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 111 deletions.
47 changes: 22 additions & 25 deletions src/Engine.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
// Set up the event bus
import EventBus from '@/modules/EventBus.js'
import {TIMESCALE, TICKRATE} from '@/modules/Constants'

export default {
store: null,
eventBus: EventBus,
buyItem (item, amount, cost) {
this.store.dispatch('buy', {
item,
amount,
cost
})
clock: {
count: 0,
hour: 0,
day: 0,
month: 0,
increment () {
this.count++
if (this.count * TIMESCALE >= 1) {
this.hour++
this.count = 0
EventBus.$emit('tick-hour')
}
if (this.hour >= 24) {
this.hour = 0
this.day++
EventBus.$emit('tick-day')
}
}
},
tick () {
const timestamp = Math.floor(new Date() / 1000)
EventBus.emit('tick', {current: timestamp, previous: this.store.getters.timestamp})
this.store.dispatch('setTime', {timestamp})
EventBus.$emit('tick', TIMESCALE)
this.clock.increment()
},
start () {
this.interval = setInterval(() => this.tick(), 1000)

// Set up the other listeners
EventBus.on('tick', () => this.income())
this.interval = setInterval(() => this.tick(), TICKRATE)
},
stop () {
clearInterval(this.interval)
EventBus.reset()
},
income () {
let income = 0
for (const key in this.store.getters.inventory) {
const resource = this.store.getters.resource(key)
const amount = this.store.getters.inventory[key]
income += amount * resource.income
}
this.store.dispatch('income', {
amount: income
})
}
}
4 changes: 2 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ new Vue({
counter: 0
},
mounted () {
// Engine.store = this.$store
// Engine.start()
Engine.store = this.$store
Engine.start()
},
beforeDestroy () {
Engine.stop()
Expand Down
2 changes: 2 additions & 0 deletions src/modules/Constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const TIMESCALE = 0.05
export const TICKRATE = 50
84 changes: 2 additions & 82 deletions src/modules/EventBus.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,2 @@
// Originally borrowed from https://gist.github.com/zangue/7384f593df908d4a7ee2

class EventBus {
constructor () {
this.listeners = {}
}

_getListenerIdx (eventName, callback, scope) {
let eventListeners = this.listeners[eventName]
let i
let idx = -1

if (!eventListeners || eventListeners.length === 0) {
return idx
}
for (i = 0; i < eventListeners.length; i++) {
if (eventListeners[i].callback === callback &&
(!scope || scope === eventListeners[i].scope)) {
idx = i
break
}
}
return idx
}

on (eventName, callback, scope) {
let listener,
idx

if (!eventName) {
throw new Error('Event name cannot be null or undefined')
}

if (!callback || typeof (callback) !== 'function') {
throw new Error('Listener must be of type function.')
}

idx = this._getListenerIdx(eventName, callback, scope)

if (idx >= 0) return

listener = {
callback: callback,
scope: scope
}

this.listeners[eventName] = this.listeners[eventName] || []
this.listeners[eventName].push(listener)
}

unsubscribe (eventName, callback, scope) {
let idx
if (!eventName || !callback || !this.listeners[eventName]) {
return
}
idx = this._getListenerIdx(eventName, callback, scope)
if (idx === -1) return
this.listeners[eventName].splice(idx, 1)
}

emit (eventName, args) {
let eventListeners = this.listeners[eventName]

if (!eventName || !this.listeners[eventName]) {
return
}

args = args || {}

eventListeners.forEach((listener) => {
listener.callback.call(listener.scope, args)
})
}

reset () {
this.listeners = {}
}
}

// Singleton
let eventBus = new EventBus()
export default eventBus
import Vue from 'vue'
export default new Vue()
4 changes: 3 additions & 1 deletion src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Vue from 'vue'
import Vuex from 'vuex'
import inventory from './modules/inventory'
import market from './modules/market'
import trains from './modules/trains'
// import VuexPersist from 'vuex-persist'

Vue.use(Vuex)
Expand All @@ -17,6 +18,7 @@ export default new Vuex.Store({
state,
modules: {
inventory,
market
market,
trains
}
})
6 changes: 6 additions & 0 deletions src/store/modules/inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export default {
quantities: {
'wood': 1
}
},
'asdf': {
items: ['wood'],
quantities: {
'wood': 1
}
}
},
getters: {
Expand Down
86 changes: 86 additions & 0 deletions src/store/modules/trains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
export default {
namespaced: true,
state: {
trains: ['train1'],
'train1': {
cars: [
'train1-car1'
],
acceleration: 3,
deceleration: -7,
maxSpeed: 30,
currentSpeed: 0,
fuel: 100,
position: {
distanceTo: 200,
destination: 'city1',
source: 'city2'
},
atStation: false,
route: [
'city1',
'city2'
],
routeIndex: 0
},
'train1-car1': {
inventory: 'asdf'
}
},
getters: {
getTrain: (state, getters, _, rootGetters) => trainId => {
// Get a copy of the train object from the state
let train = Object.assign({}, state[trainId])
// For all of the cars, get the inventory object
train.cars = train.cars.map(i => {
const carInventory = state[i].inventory
const inventory = rootGetters['inventory/getInventory'](carInventory)
return {
name: i,
inventory
}
})
return train
}
},
actions: {
update ({commit}, {trainId, position, fuel, atStation, currentSpeed}) {
commit('UPDATE_POSITION', {
trainId,
position
})
commit('UPDATE_FUEL', {
trainId,
fuel
})
commit('UPDATE_STATION', {
trainId,
atStation
})
commit('UPDATE_SPEED', {
trainId,
currentSpeed
})
},
depart ({commit}, {trainId}) {
commit('UPDATE_STATION', {
trainId,
atStation: false
})
}
},
mutations: {
UPDATE_POSITION (state, {trainId, position}) {
state[trainId].position = position
},
UPDATE_FUEL (state, {trainId, fuel}) {
state[trainId].fuel = fuel
},
UPDATE_STATION (state, {trainId, atStation}) {
state[trainId].atStation = atStation
},
UPDATE_SPEED (state, {trainId, currentSpeed}) {
state[trainId].currentSpeed = currentSpeed
}
}
}
6 changes: 5 additions & 1 deletion src/view/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
<div id="app">
<Market v-for="market in markets" :key="market" v-bind:name="market"/>
<Player />
Train here:
<Train trainId="train1"/>
</div>
</template>

<script>
import Market from './components/Market'
import Player from './components/Player'
import Train from './components/Train'
import {createNamespacedHelpers} from 'vuex'
// Set up the helpers
Expand All @@ -20,7 +23,8 @@ export default {
name: 'App',
components: {
Market,
Player
Player,
Train
},
computed: {
...mapState({
Expand Down
Loading

0 comments on commit aa71e65

Please sign in to comment.