lobby joining
This commit is contained in:
parent
4bec55e310
commit
24cac2006e
@ -12,7 +12,7 @@ app = socketio.WSGIApp(sio, static_files={
|
|||||||
games = []
|
games = []
|
||||||
|
|
||||||
def advertise_lobbies():
|
def advertise_lobbies():
|
||||||
sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': g.players} for g in games if not g.started])
|
sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': len(g.players)} for g in games if not g.started])
|
||||||
|
|
||||||
@sio.event
|
@sio.event
|
||||||
def connect(sid, environ):
|
def connect(sid, environ):
|
||||||
@ -21,7 +21,7 @@ def connect(sid, environ):
|
|||||||
|
|
||||||
@sio.event
|
@sio.event
|
||||||
def set_username(sid, username):
|
def set_username(sid, username):
|
||||||
sio.save_session(sid, Player(username))
|
sio.save_session(sid, Player(username, sid))
|
||||||
print(f'{sid} is now {username}')
|
print(f'{sid} is now {username}')
|
||||||
advertise_lobbies()
|
advertise_lobbies()
|
||||||
|
|
||||||
@ -31,17 +31,34 @@ def my_message(sid, data):
|
|||||||
|
|
||||||
@sio.event
|
@sio.event
|
||||||
def disconnect(sid):
|
def disconnect(sid):
|
||||||
|
if sio.get_session(sid).disconnect():
|
||||||
|
games.pop(games.index(sio.get_session(sid).game))
|
||||||
print('disconnect ', sid)
|
print('disconnect ', sid)
|
||||||
|
advertise_lobbies()
|
||||||
|
|
||||||
@sio.event
|
@sio.event
|
||||||
def create_room(sid, room_name):
|
def create_room(sid, room_name):
|
||||||
sio.leave_room(sid, 'lobby')
|
sio.leave_room(sid, 'lobby')
|
||||||
g = Game(room_name)
|
sio.enter_room(sid, room_name)
|
||||||
|
g = Game(room_name, sio)
|
||||||
g.add_player(sio.get_session(sid))
|
g.add_player(sio.get_session(sid))
|
||||||
games.append(g)
|
games.append(g)
|
||||||
sio.enter_room(sid, room_name)
|
|
||||||
print(f'{sid} created a room named {room_name}')
|
print(f'{sid} created a room named {room_name}')
|
||||||
advertise_lobbies()
|
advertise_lobbies()
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def join_room(sid, room_name):
|
||||||
|
print(f'{sid} joined a room named {room_name}')
|
||||||
|
sio.leave_room(sid, 'lobby')
|
||||||
|
sio.enter_room(sid, room_name)
|
||||||
|
i = [g.name for g in games].index(room_name)
|
||||||
|
games[i].add_player(sio.get_session(sid))
|
||||||
|
advertise_lobbies()
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def chat_message(sid, msg):
|
||||||
|
ses = sio.get_session(sid)
|
||||||
|
sio.emit('chat_message', room=ses.game.name, data=f'[{ses.name}]: {msg}')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
eventlet.wsgi.server(eventlet.listen(('', 5001)), app)
|
eventlet.wsgi.server(eventlet.listen(('', 5001)), app)
|
||||||
|
@ -1,24 +1,38 @@
|
|||||||
from typing import List, Set, Dict, Tuple, Optional
|
from typing import List, Set, Dict, Tuple, Optional
|
||||||
import random
|
import random
|
||||||
|
import socketio
|
||||||
import players
|
import players
|
||||||
from characters import all_characters
|
from characters import all_characters
|
||||||
from deck import Deck
|
from deck import Deck
|
||||||
import roles
|
import roles
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, name):
|
def __init__(self, name, sio:socketio):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.sio = sio
|
||||||
self.name = name
|
self.name = name
|
||||||
self.players: List[players.Player] = []
|
self.players: List[players.Player] = []
|
||||||
self.deck: Deck = None
|
self.deck: Deck = None
|
||||||
self.started = False
|
self.started = False
|
||||||
self.turn = 0
|
self.turn = 0
|
||||||
|
|
||||||
|
def handle_disconnect(self, player: players.Player):
|
||||||
|
print(f'player {player.name} left the game {self.name}')
|
||||||
|
self.players.pop(self.players.index(player))
|
||||||
|
if len(self.players) == 0:
|
||||||
|
print(f'no players left in game {self.name}')
|
||||||
|
return True
|
||||||
|
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players]})
|
||||||
|
return False
|
||||||
|
|
||||||
def add_player(self, player: players.Player):
|
def add_player(self, player: players.Player):
|
||||||
|
if player in self.players:
|
||||||
|
return
|
||||||
player.join_game(self)
|
player.join_game(self)
|
||||||
self.players.append(player)
|
self.players.append(player)
|
||||||
print(f'Added player {player.name} to game')
|
print(f'Added player {player.name} to game')
|
||||||
|
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players]})
|
||||||
|
|
||||||
def choose_characters(self):
|
def choose_characters(self):
|
||||||
char_cards = random.sample(all_characters(), len(self.players)*2)
|
char_cards = random.sample(all_characters(), len(self.players)*2)
|
||||||
for i in range(len(self.players)):
|
for i in range(len(self.players)):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import json
|
import json
|
||||||
|
import socketio
|
||||||
|
|
||||||
import roles
|
import roles
|
||||||
import cards
|
import cards
|
||||||
@ -13,9 +14,10 @@ class PendingAction(IntEnum):
|
|||||||
WAIT = 4
|
WAIT = 4
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self, name):
|
def __init__(self, name, sid):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.sid = sid
|
||||||
self.hand: cards.Card = []
|
self.hand: cards.Card = []
|
||||||
self.equipment: cards.Card = []
|
self.equipment: cards.Card = []
|
||||||
self.role: roles.Role = None
|
self.role: roles.Role = None
|
||||||
@ -34,6 +36,9 @@ class Player:
|
|||||||
self.game = game
|
self.game = game
|
||||||
print(f'I {self.name} joined {self.game}')
|
print(f'I {self.name} joined {self.game}')
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
return self.game.handle_disconnect(self)
|
||||||
|
|
||||||
def set_role(self, role: roles.Role):
|
def set_role(self, role: roles.Role):
|
||||||
self.role = role
|
self.role = role
|
||||||
print(f'I {self.name} am a {role.name}, my goal is "{role.goal}"')
|
print(f'I {self.name} am a {role.name}, my goal is "{role.goal}"')
|
||||||
|
@ -1,23 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
<div id="logo" class="center-stuff" style="margin-bottom:10pt;">
|
||||||
|
<h1 style="margin-bottom:0pt;">PewPew!</h1>
|
||||||
|
<i style="font-size: x-small;">Bang è un marchio registrato DVGiochi!</i>
|
||||||
|
</div>
|
||||||
<div v-if="isConnected">
|
<div v-if="isConnected">
|
||||||
<div v-if="!didSetUsername">
|
<div v-if="!didSetUsername">
|
||||||
Scegli un username:
|
Scegli un username:
|
||||||
<div>
|
<form @submit="setUsername">
|
||||||
<input v-model="username"/>
|
<input v-model="username" />
|
||||||
<input type="submit" @click="setUsername"/>
|
<input type="submit"/>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div v-if="!isInLobby" >
|
<div v-if="!isInLobby" >
|
||||||
<h2>Crea una lobby:</h2>
|
<Card :card="getSelfCard"/>
|
||||||
Nome: <input v-model="lobbyName"/>
|
<form @submit="createLobby">
|
||||||
<input type="submit" @click="createLobby"/>
|
<h2>Crea una lobby:</h2>
|
||||||
|
Nome: <input v-model="lobbyName"/>
|
||||||
|
<input type="submit" />
|
||||||
|
</form>
|
||||||
|
<h2>Lobby disponibili:</h2>
|
||||||
|
<div style="display: flex">
|
||||||
|
<Card v-for="lobby in openLobbies" v-bind:key="lobby.name" :card="getLobbyCard(lobby)" @click.native="joinLobby(lobby)"/>
|
||||||
|
<p v-if="noLobbyAvailable">Nessuna lobby disponibile</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Card v-for="lobby in openLobbies" v-bind:key="lobby" :card="lobby"/>
|
<Lobby :username="username" v-else/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else class="center-stuff">
|
||||||
<h2>Attenzione!</h2>
|
<h2>Attenzione!</h2>
|
||||||
<p>Connessione al server assente.</p>
|
<p>Connessione al server assente.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -26,20 +38,15 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Card from './components/Card.vue'
|
import Card from './components/Card.vue'
|
||||||
|
import Lobby from './components/Lobby.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
Card
|
Card,
|
||||||
|
Lobby,
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
card: {
|
|
||||||
name: "Bang!",
|
|
||||||
icon: "🔫",
|
|
||||||
number: 2,
|
|
||||||
suit: '♠',
|
|
||||||
is_equipment: false,
|
|
||||||
},
|
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
didSetUsername: false,
|
didSetUsername: false,
|
||||||
username: '',
|
username: '',
|
||||||
@ -47,6 +54,19 @@ export default {
|
|||||||
lobbyName: '',
|
lobbyName: '',
|
||||||
isInLobby: false,
|
isInLobby: false,
|
||||||
}),
|
}),
|
||||||
|
computed: {
|
||||||
|
noLobbyAvailable() {
|
||||||
|
return this.openLobbies && this.openLobbies.length == 0
|
||||||
|
},
|
||||||
|
getSelfCard() {
|
||||||
|
return {
|
||||||
|
name: this.username,
|
||||||
|
number: 'YOU',
|
||||||
|
icon: '🤠',
|
||||||
|
is_character: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
sockets: {
|
sockets: {
|
||||||
connect() {
|
connect() {
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
@ -59,9 +79,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setUsername(){
|
setUsername(e){
|
||||||
this.didSetUsername = true
|
this.didSetUsername = true
|
||||||
this.$socket.emit('set_username', this.username)
|
this.$socket.emit('set_username', this.username)
|
||||||
|
e.preventDefault();
|
||||||
},
|
},
|
||||||
getLobbyCard(lobby) {
|
getLobbyCard(lobby) {
|
||||||
return {
|
return {
|
||||||
@ -72,22 +93,36 @@ export default {
|
|||||||
is_equipment: true,
|
is_equipment: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createLobby() {
|
createLobby(e) {
|
||||||
if (this.lobbyName.trim().length > 0) {
|
if (this.lobbyName.trim().length > 0) {
|
||||||
this.$socket.emit('create_room', this.lobbyName)
|
this.$socket.emit('create_room', this.lobbyName)
|
||||||
this.isInLobby = true;
|
this.isInLobby = true;
|
||||||
}
|
}
|
||||||
}
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
joinLobby(lobby) {
|
||||||
|
this.$socket.emit('join_room', lobby.name)
|
||||||
|
this.isInLobby = true;
|
||||||
|
},
|
||||||
|
// room() {
|
||||||
|
// },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin-top: 60px;
|
margin: 60px;
|
||||||
|
}
|
||||||
|
.center-stuff {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{ card: true, equipment: card.is_equipment }" @click="equip(card)">
|
<div :class="{ card: true, equipment: card.is_equipment, character:card.is_character }">
|
||||||
<h3>{{card.name}}</h3>
|
<h3>{{card.name}}</h3>
|
||||||
<emoji>{{card.icon}}</emoji>
|
<div class="emoji">{{card.icon}}</div>
|
||||||
<span>{{card.number}}{{card.suit}}</span>
|
<span>{{card.number}}{{card.suit}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'HelloWorld',
|
name: 'Card',
|
||||||
props: {
|
props: {
|
||||||
card: Object
|
card: Object
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
top: -10pt;
|
top: -10pt;
|
||||||
}
|
}
|
||||||
.card emoji {
|
.card .emoji {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'HelloWorld',
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
73
frontend/src/components/Lobby.vue
Normal file
73
frontend/src/components/Lobby.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Lobby: {{ lobbyName }}</h1>
|
||||||
|
<h3>Giocatori</h3>
|
||||||
|
<div style="display:flex">
|
||||||
|
<Card v-for="p in players" v-bind:key="p" :card="getPlayerCard(p)"/>
|
||||||
|
</div>
|
||||||
|
<h3>Chat</h3>
|
||||||
|
<div id="chatbox" style="max-height:300px; overflow:auto;">
|
||||||
|
<p v-for="msg in messages" v-bind:key="msg">{{msg}}</p>
|
||||||
|
</div>
|
||||||
|
<form @submit="sendChatMessage">
|
||||||
|
<input v-model="text"/>
|
||||||
|
<input type="submit"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Card from '@/components/Card.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Lobby',
|
||||||
|
components: {
|
||||||
|
Card,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
username: String
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
lobbyName: '',
|
||||||
|
started: false,
|
||||||
|
players: [],
|
||||||
|
messages: [],
|
||||||
|
text: ''
|
||||||
|
}),
|
||||||
|
sockets: {
|
||||||
|
room(data) {
|
||||||
|
console.log(data)
|
||||||
|
this.lobbyName = data.name
|
||||||
|
this.started = data.started
|
||||||
|
this.players = data.players
|
||||||
|
},
|
||||||
|
chat_message(msg) {
|
||||||
|
this.messages.push(msg)
|
||||||
|
let container = this.$el.querySelector("#chatbox");
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sendChatMessage(e) {
|
||||||
|
if (this.text.trim().length > 0){
|
||||||
|
this.$socket.emit('chat_message', this.text.trim())
|
||||||
|
this.text = ''
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
getPlayerCard(username) {
|
||||||
|
return {
|
||||||
|
name: username,
|
||||||
|
number: (this.username == username) ? 'YOU' : '',
|
||||||
|
icon: '🤠',
|
||||||
|
is_character: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user