Compare commits

..

5 Commits
dev ... alf

4
.gitignore vendored

@ -1,5 +1 @@
.vscode/ .vscode/
build/
node_modules/
venv/
*.pyc

@ -1,11 +0,0 @@
serve:
./node_modules/.bin/webpack-dev-server --mode development
build:
./node_modules/.bin/webpack --mode production
lint:
./node_modules/.bin/eslint src
format:
./node_modules/.bin/prettier --write src/**/*.js

@ -1,8 +1 @@
#Hello there # EbermergenTD
## Available scripts
- `npm start`: starts a development server (`make` or `make serve`)
- `npm run build`: make a production build (`make build`)
- `npm run lint`: lint js files using eslint (`make lint`)
- `npm run format`: format js files using prettier (`make format`)

2
server/.gitignore vendored

@ -0,0 +1,2 @@
venv
*.pyc

@ -0,0 +1,12 @@
# Backend for EbermergenTD
## Install
Requirements: python3, python3-venv and pip
## Available scripts
- `make venv`: creates a python virtual environment
- `make install`: installs python dependencies
- `make run`: runs the development server
- `make test`: runs unittests

@ -5,9 +5,13 @@ from flask_cors import CORS
from ebermergen.models.game import Game from ebermergen.models.game import Game
from .lib import generate_map from .lib import generate_map
from .lib.ebermergen_game import EbermergenGame
app = Flask(__name__) app = Flask(__name__)
CORS(app) CORS(app)
games = {}
@app.route('/') @app.route('/')
def index(): def index():
@ -29,3 +33,21 @@ def state():
a = Game() a = Game()
a.seed_map() a.seed_map()
return jsonify(a.serialize()) return jsonify(a.serialize())
@app.route('/lala')
def lala():
return jsonify({k: v.state for (k, v) in games.items()})
@app.route('/new-game/<name>', methods=['GET', 'POST'])
def new_game(name):
games[name] = EbermergenGame()
games[name].start_game()
return jsonify({'message': 'success'})
@app.route('/action/<name>/<type>')
def action(name, type):
games[name].perform_action(type, {})
return jsonify({'message': 'success'})

@ -0,0 +1,50 @@
import atexit
import time
import threading
import queue
from .gameloop import GameLoop
def tick(dt, first, second):
print('%.2f' % dt, first, second)
pass
def worker(state, action_queue):
state['counter'] = 0
state['actions'] = []
loop = GameLoop(tick=tick, fps=1, fixed_dt=True, args=(1, 2))
while True:
item = action_queue.get()
if item['action'] == 'STOP':
loop.stop()
if item['action'] == 'START':
loop.start()
state['counter'] += 1
state['actions'].append(item['action'])
class EbermergenGame:
"""Runs a single game instance
Holds the serialized state.
Provides methods to perform actions.
"""
def __init__(self):
self.state = {}
self.actions = queue.Queue()
self.thread = threading.Thread(
target=worker, args=(self.state, self.actions))
def start_game(self):
self.thread.start()
atexit.register(self.interupt)
def interupt(self):
# handle gracefull shutdown
pass
def perform_action(self, action, payload={}):
self.actions.put({'action': action, 'payload': payload})

@ -0,0 +1,46 @@
import threading
import time
import random
class GameLoop():
"""Implements a loop that calls tick every 1/fps
tick gets called with the time delta to the last call as parameter
if fixed_dt is True the tick function gets called with 1/fps
"""
def __init__(self, fps=1, tick=None, fixed_dt=False, args=None):
self.fps = fps
self.tick = tick if tick is not None else self.default_tick
self.args = args or tuple()
self.fixed_dt = fixed_dt
self.running = False
self.last_frame_time = time.time()
self.thread = threading.Thread(target=self.loop)
def loop(self):
while self.running:
current_time = time.time()
dt = current_time - self.last_frame_time
self.last_frame_time = current_time
if self.fixed_dt:
self.tick(1 / self.fps, *self.args)
else:
self.tick(dt, *self.args)
sleep_time = (1 / self.fps) - (time.time() - self.last_frame_time)
if sleep_time > 0:
time.sleep(sleep_time)
def start(self):
self.running = True
self.thread.start()
def stop(self):
self.running = False
def default_tick(self, dt):
print('ticked. Last tick was %.2f seconds ago' % dt)
time.sleep(random.choice([0.4, 0.5, 0.6, 1.4, 2.1]) * 1/self.fps)

@ -5,6 +5,8 @@ from .player import Player
from .map import Map from .map import Map
from .entities import Town from .entities import Town
from ebermergen.lib.gameloop import GameLoop
class Game: class Game:
def __init__(self): def __init__(self):

2
web/.gitignore vendored

@ -0,0 +1,2 @@
node_modules/
build/

@ -0,0 +1,14 @@
# Hello there
## Install
Requirements: node and npm
- `npm install`: installs dependencies in node_modules
## Available scripts
- `npm start`: starts a development server
- `npm run build`: make a production build
- `npm run lint`: lint js files using eslint
- `npm run format`: format js files using prettier
Loading…
Cancel
Save