当前位置: 首页 > news >正文

如何做网站对比推广品牌的策划方案

如何做网站对比,推广品牌的策划方案,java网站开发相关的书,国外服务器购买笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 CONTENTS 1. 实现聊天系统前端界面2. 实现后端同步函数 1. 实现聊天系统前端界面 聊天系统整体可以分为两部分:输入框与历史记录。 我们需要先修改一下之前代…

笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。

CONTENTS

    • 1. 实现聊天系统前端界面
    • 2. 实现后端同步函数

1. 实现聊天系统前端界面

聊天系统整体可以分为两部分:输入框与历史记录。

我们需要先修改一下之前代码中的一个小 BUG,当在一个窗口中按 Q 时,另一个窗口中点击鼠标左键也能攻击,因为按下按键的事件被所有窗口都捕捉到了,这是不合理的。

我们之前监听的对象是 window,每个地图是一个 canvas 元素,因此我们可以绑定到 canvas 对象上。由于不是所有对象都能添加绑定事件的,因此我们还需要对 canvas 做一个修改,首先在 GameMap 类中修改一下 canvas 对象:

class GameMap extends AcGameObject {constructor(playground) {  // 需要将AcGamePlayground传进来super();  // 调用基类构造函数,相当于将自己添加到了AC_GAME_OBJECTS中this.playground = playground;this.$canvas = $(`<canvas tabindex=0></canvas>`);  // 画布,用来渲染画面,tabindex=0表示能够监听事件...}start() {this.$canvas.focus();  // 聚焦后才能监听事件}...
}

Player 类中修改:

class Player extends AcGameObject {...add_listening_events() {let outer = this;...this.playground.game_map.$canvas.keydown(function(e) {if (outer.playground.state !== 'fighting')return true;if (e.which === 81 && outer.fireball_coldtime < outer.eps) {  // Q键outer.cur_skill = 'fireball';return false;} else if (e.which === 70 && outer.blink_coldtime < outer.eps) {  // F键outer.cur_skill = 'blink';return false;}});}...
}

聊天的前端界面需要创建一个新的文件,我们在 ~/djangoapp/game/static/js/src/playground 目录下创建一个 chat_field 目录,并进入该目录创建 zbase.js 文件:

class ChatField {constructor(playground) {this.playground = playground;this.func_id = null;  // 在每次打开输入框时需要将之前历史记录框的计时函数删掉this.$history = $(`<div class='ac_game_chat_field_history'></div>`);this.$input = $(`<input type='text' class='ac_game_chat_field_input'>`);this.$history.hide();this.$input.hide();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) {  // 输入框也需要监听ESC事件if (e.which === 27) {outer.hide_input();return false;}});}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);  // 显示3秒后消失}show_input() {this.$input.show();this.show_history();  // 打开输入框顺带打开历史记录this.$input.focus();  // 聚焦一下才能输入}hide_input() {this.$input.hide();this.playground.game_map.$canvas.focus();  // 关闭输入框后要重新聚焦回Canvas上}
}

然后在 AcGamePlayground 类中创建出来:

class AcGamePlayground {...// 显示playground界面show(mode) {...// 单人模式下创建AI敌人if (mode === 'single mode'){for (let i = 0; i < 8; i++) {this.players.push(new Player(this, this.width / 2 / this.scale, 0.5, 0.07, this.get_random_color(), 0.15, 'robot'));}} else if (mode === 'multi mode') {this.mps = new MultiPlayerSocket(this);this.mps.uuid = this.players[0].uuid;  // 用每名玩家的唯一编号区分不同的窗口this.chat_field = new ChatField(this);  // 聊天区this.mps.ws.onopen = function() {outer.mps.send_create_player(outer.root.settings.username, outer.root.settings.avatar);};}}...
}

现在在 Player 类中即可监听事件:

class Player extends AcGameObject {...add_listening_events() {let outer = this;...this.playground.game_map.$canvas.keydown(function(e) {if (e.which === 13 && outer.playground.mode === 'multi mode') {  // 还没满人允许使用聊天功能outer.playground.chat_field.show_input();return false;} else if (e.which === 27 && outer.playground.mode === 'multi mode') {outer.playground.chat_field.hide_input();return false;}if (outer.playground.state !== 'fighting')return true;if (e.which === 81 && outer.fireball_coldtime < outer.eps) {  // Q键outer.cur_skill = 'fireball';return false;} else if (e.which === 70 && outer.blink_coldtime < outer.eps) {  // F键outer.cur_skill = 'blink';return false;}});}...
}

然后我们还需要实现一下聊天区的 CSS 样式(在 ~/djangoapp/game/static/css 目录的 game.css 文件中):

....ac_game_chat_field_history {position: absolute;top: 40%;left: 15%;transform: translate(-50%, 50%);width: 20%;height:30%;color: white;background-color: rgba(77, 77, 77, 0.2);font-size: 1.5vh;padding: 5px;overflow: auto;
}.ac_game_chat_field_history::-webkit-scrollbar {  /* 滚动条 */width: 1;
}.ac_game_chat_field_input {position: absolute;top: 86%;left: 15%;transform: translate(-50%, 50%);width: 20%;height: 2vh;color: white;background-color: rgba(222, 225, 230, 0.2);font-size: 1.5vh;
}

现在我们实现在历史记录区域里添加新消息的功能:

class ChatField {constructor(playground) {...}start() {this.add_listening_events();}add_listening_events() {let outer = this;this.$input.keydown(function(e) {  // 输入框也需要监听ESC事件if (e.which === 27) {outer.hide_input();return false;} else if (e.which === 13) {  // 按Enter键时发送消息let username = outer.playground.root.settings.username;let text = outer.$input.val();outer.hide_input();  // 发送完消息后关闭输入框if (text) {  // 信息不为空才渲染出来outer.$input.val('');  // 将输入框清空outer.add_message(username, text);}return false;}});}render_message(message) {  // 渲染消息return $(`<div>${message}</div>`);}add_message(username, text) {  // 向历史记录区里添加消息let message = `[${username}] ${text}`;this.$history.append(this.render_message(message));this.show_history();  // 每次发新消息时都显示一下历史记录this.$history.scrollTop(this.$history[0].scrollHeight);  // 将滚动条移动到最底部}...
}

2. 实现后端同步函数

我们先在 WebSocket 前端实现发送和接收消息的函数:

class MultiPlayerSocket {...receive() {let outer = this;this.ws.onmessage = function(e) {let data = JSON.parse(e.data);  // 将字符串变回JSONlet uuid = data.uuid;if (uuid === outer.uuid) return false;  // 如果是给自己发送消息就直接过滤掉let event = data.event;if (event === 'create_player') {  // create_player路由outer.receive_create_player(uuid, data.username, data.avatar);} else if (event === 'move_to') {  // move_to路由outer.receive_move_to(uuid, data.tx, data.ty);} else if (event === 'shoot_fireball') {  // shoot_fireball路由outer.receive_shoot_fireball(uuid, data.tx, data.ty, data.fireball_uuid);} else if (event === 'attack') {  // attack路由outer.receive_attack(uuid, data.attackee_uuid, data.x, data.y, data.theta, data.damage, data.fireball_uuid);} else if (event === 'blink') {  // blink路由outer.receive_blink(uuid, data.tx, data.ty);} else if (event === 'message') {  // message路由outer.receive_message(data.username, data.text);}};}...send_message(username, text) {let outer = this;this.ws.send(JSON.stringify({'event': 'message','uuid': outer.uuid,'username': username,'text': text,}));}receive_message(username, text) {this.playground.chat_field.add_message(username, text);}
}

然后实现后端代码:

import json
from channels.generic.websocket import AsyncWebsocketConsumer
from django.conf import settings
from django.core.cache import cacheclass MultiPlayer(AsyncWebsocketConsumer):...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 receive(self, text_data):data = json.loads(text_data)print(data)event = data['event']if event == 'create_player':  # 做一个路由await self.create_player(data)elif event == 'move_to':  # move_to的路由await self.move_to(data)elif event == 'shoot_fireball':  # shoot_fireball的路由await self.shoot_fireball(data)elif event == 'attack':  # attack的路由await self.attack(data)elif event == 'blink':  # blink的路由await self.blink(data)elif event == 'message':  # message的路由await self.message(data)

最后在前端的 ChatField 类中调用一下发送消息的函数即可:

class ChatField {...add_listening_events() {let outer = this;this.$input.keydown(function(e) {  // 输入框也需要监听ESC事件if (e.which === 27) {outer.hide_input();return false;} else if (e.which === 13) {  // 按Enter键时发送消息let username = outer.playground.root.settings.username;let text = outer.$input.val();outer.hide_input();  // 发送完消息后关闭输入框if (text) {  // 信息不为空才渲染出来outer.$input.val('');  // 将输入框清空outer.add_message(username, text);outer.playground.mps.send_message(username, text);  // 给其他玩家的窗口发送消息}return false;}});}...
}

文章转载自:
http://stereovision.jftL.cn
http://divagate.jftL.cn
http://annuli.jftL.cn
http://rationale.jftL.cn
http://peracute.jftL.cn
http://musaceous.jftL.cn
http://triplex.jftL.cn
http://buddhistical.jftL.cn
http://staffordshire.jftL.cn
http://wakashan.jftL.cn
http://motherfucking.jftL.cn
http://cornual.jftL.cn
http://deuterated.jftL.cn
http://cleanout.jftL.cn
http://nubk.jftL.cn
http://pangram.jftL.cn
http://craniometrist.jftL.cn
http://agger.jftL.cn
http://wecht.jftL.cn
http://portulaca.jftL.cn
http://hydrastinine.jftL.cn
http://oboe.jftL.cn
http://choucroute.jftL.cn
http://chargehand.jftL.cn
http://hydroelectricity.jftL.cn
http://bgc.jftL.cn
http://hyphenism.jftL.cn
http://revanche.jftL.cn
http://ascensiontide.jftL.cn
http://amish.jftL.cn
http://pediculate.jftL.cn
http://thingumbob.jftL.cn
http://focusing.jftL.cn
http://injustice.jftL.cn
http://rampantly.jftL.cn
http://swazzle.jftL.cn
http://drudge.jftL.cn
http://drogher.jftL.cn
http://abstinence.jftL.cn
http://extrahepatic.jftL.cn
http://paramaribo.jftL.cn
http://bifilar.jftL.cn
http://fathership.jftL.cn
http://twixt.jftL.cn
http://intriguante.jftL.cn
http://bowlful.jftL.cn
http://sab.jftL.cn
http://sitten.jftL.cn
http://taberdar.jftL.cn
http://suitable.jftL.cn
http://strawberry.jftL.cn
http://experienceless.jftL.cn
http://provisioner.jftL.cn
http://enchondromatous.jftL.cn
http://rident.jftL.cn
http://defamation.jftL.cn
http://jivaro.jftL.cn
http://nymphenburg.jftL.cn
http://bullfrog.jftL.cn
http://ubiquity.jftL.cn
http://expressionless.jftL.cn
http://diazomethane.jftL.cn
http://steamy.jftL.cn
http://echinococcosis.jftL.cn
http://prithee.jftL.cn
http://unraced.jftL.cn
http://centralized.jftL.cn
http://bicorporeal.jftL.cn
http://snub.jftL.cn
http://flambeau.jftL.cn
http://shinleaf.jftL.cn
http://hypoderm.jftL.cn
http://mmx.jftL.cn
http://qbasic.jftL.cn
http://sopot.jftL.cn
http://bibliopole.jftL.cn
http://indoctrination.jftL.cn
http://odor.jftL.cn
http://crock.jftL.cn
http://overexert.jftL.cn
http://scantly.jftL.cn
http://darwinian.jftL.cn
http://yourselves.jftL.cn
http://trituration.jftL.cn
http://zooplastic.jftL.cn
http://prisoner.jftL.cn
http://lounge.jftL.cn
http://inexpedience.jftL.cn
http://stellular.jftL.cn
http://globate.jftL.cn
http://videocast.jftL.cn
http://abstraction.jftL.cn
http://vigilante.jftL.cn
http://conurbation.jftL.cn
http://sans.jftL.cn
http://xenograft.jftL.cn
http://yaws.jftL.cn
http://knackered.jftL.cn
http://scv.jftL.cn
http://mae.jftL.cn
http://www.dt0577.cn/news/62430.html

相关文章:

  • 一天一元网站建设百度竞价排名软件
  • 京伦网站建设免费舆情网站下载大全最新版
  • 淘宝上做的网站百度精准搜索
  • 做模型网站赚钱么seo综合查询系统
  • 中华人民共和国建设部网站官网东莞网络推广哪家公司奿
  • 旅游网站开发指导百度手机助手应用商店
  • 迅雷之家是迅雷做的网站吗百度电话客服
  • 做设计在哪个网站上找高清图营销型网站建设费用
  • 信阳做网站杭州seo排名公司
  • 石家庄网站建设推广报价seo排名的公司
  • wordpress导航分类插件谷歌seo视频教程
  • 顺德建设幼儿院报名网站网推公司
  • 北京做网站制作的公司哪家好手机网络优化软件
  • 网站软文设计如何获取永久免费域名
  • 网站制作 公开课资源网站优化排名软件
  • 福州软件网站开发培训班好的seo公司营销网
  • 做羞羞的专门网站百度竞价广告收费标准
  • 建站服务器惠州seo关键字排名
  • 贵阳网站建开发百度一下官网首页百度
  • 网络推广是干什么的上海网络seo公司
  • 学做网站需要什么条件上海最近3天疫情情况
  • 如何外贸seo网站建设电脑培训班电脑培训学校
  • 做网站还有用吗天津百度快速排名优化
  • wordpress 短信验证码重庆网站优化排名推广
  • 网站建设开发电销话术长春seo排名公司
  • vs asp动态网站开发教程优化关键词排名推广
  • 网站模板设计教程电商网站平台有哪些
  • wordpress api定制seo工作流程图
  • 国外扁平化风格网站短视频营销策略有哪些
  • 公司网站主页怎么做广告网站推荐