8、WebSocket实现聊天系统
修复Bug
多人游戏时,一个窗口接收q
,每个窗口都会出发q
命令。
解决:
game/static/js/src/playground/palyer/zbase.js
this.playground.game_map.$canvas.keydown(function (e) {// 监听键盘按键
在game/static/js/src/playground/game_map/zbase.js
中
this.$canvas = $(`<canvas tabindex=0></canvas>`);
start() {
this.$canvas.focus(); // 聚焦窗口
}
前端
输入框+ 类图历史记录框
game/static/js/src/playground/chat_field/zbase.js
class ChatField {
constructor(playground) {
this.playground = playground;
this.$history = $(`<div class = "hyld-game-chat-field-history">聊天记录</div>`);
this.$input = $(`<input type="text" class="hyld-game-chat-field-input">`);
this.$history.hide();
this.$input.hide();
this.func_id = null; // 防止监听函数定时消失不恰当
this.playground.$playground.append(this.$history);
this.playground.$playground.append(this.$input);
this.start();
}
start() {
this.add_listening_events();
}
add_listening_events() {
let outer = this;
this.$input.keydown(function (e) {
if (e.which === 27) { // ESC
outer.hide_input();
return false;
} else if (e.which === 13) { // ENTER
let username = outer.playground.root.settings.username;
let text = outer.$input.val();
if (text) {
outer.$input.val(""); // 清空输入框
outer.add_message(username, text);
outer.playground.mps.send_message(username, text);
}
return false;
}
});
}
render_message(message) {
return $(`<div>${message}</div>`);
}
add_message(username, text) {
this.show_history();
let message = `[${username}]${text}`;
this.$history.append(this.render_message(message));
this.$history.scrollTop(this.$history[0].scrollHeight);
}
show_history() {
let outer = this;
this.$history.fadeIn();
if (this.func_id) clearTimeout(this.func_id);
this.func_id = setTimeout(function () {
outer.$history.fadeOut();
outer.func_id = null;
}, 3000);
}
show_input() {
this.show_history();
this.$input.show();
this.$input.focus();
}
hide_input() {
this.$input.hide();
this.playground.game_map.$canvas.focus();
}
}
send_message(username, text) {
console.log(username);
let outer = this;
this.ws.send(JSON.stringify({
'event': "message",
'uuid': outer.uuid,
'username': username,
'text': text,
}));
}
receive_message(uuid, username, text) {
console.log(username);
this.playground.chat_field.add_message(username, text);
}
后端
async def message(self, data):
await self.channel_layer.group_send(
self.room_name,
{
'type': "group_send_event",
'event': "message",
'uuid': data['uuid'],
'username': data['username'],
'text': data['text'],
}
)
async def group_send_event(self, data):
await self.send(text_data=json.dumps(data))
# 接收前端信息
async def receive(self, text_data):
data = json.loads(text_data)
event = data['event']
if event == "create_player":
await self.create_player(data)
elif event == "move_to":
await self.move_to(data)
elif event == "shoot_fireball":
await self.shoot_fireball(data)
elif event == "attack":
await self.attack(data)
elif event == "blink":
await self.blink(data)
elif event == "message":
await self.message(data)