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

做网站 域名如何要回cpv广告联盟

做网站 域名如何要回,cpv广告联盟,建设银行网站支付流程,360网址大全电脑版笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 CONTENTS 1. 编写移动同步函数move_to2. 编写攻击同步函数shoot_fireball 1. 编写移动同步函数move_to 与上一章中的 create_player 同步函数相似,移动函数的同…

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

CONTENTS

    • 1. 编写移动同步函数move_to
    • 2. 编写攻击同步函数shoot_fireball

1. 编写移动同步函数move_to

与上一章中的 create_player 同步函数相似,移动函数的同步也需要在前端实现 send_move_toreceive_move_to 函数。我们修改 MultiPlayerSocket 类(在目录 ~/djangoapp/game/static/js/src/playground/socket/multiplayer 中):

class MultiPlayerSocket {constructor(playground) {this.playground = playground;// 直接将网站链接复制过来,将https改成wss,如果没有配置https那就改成ws,然后最后加上wss的路由this.ws = new WebSocket('wss://app4007.acapp.acwing.com.cn/wss/multiplayer/');this.start();}start() {this.receive();}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);}};}send_create_player(username, avatar) {...}receive_create_player(uuid, username, avatar) {...}// 根据uuid找到对应的Playerget_player(uuid) {let players = this.playground.players;for (let i = 0; i < players.length; i++) {let player = players[i];if (player.uuid === uuid)return player;}return null;}send_move_to(tx, ty) {let outer = this;this.ws.send(JSON.stringify({'event': 'move_to','uuid': outer.uuid,'tx': tx,'ty': ty,}));}receive_move_to(uuid, tx, ty) {let player = this.get_player(uuid);if (player) {  // 确保玩家存在再调用move_to函数player.move_to(tx, ty);}}
}

然后修改一下后端通信代码(~/djangoapp/game/consumers/multiplayer 目录中的 index.py 文件):

from channels.generic.websocket import AsyncWebsocketConsumer
import json
from django.conf import settings
from django.core.cache import cacheclass MultiPlayer(AsyncWebsocketConsumer):async def connect(self):...async def disconnect(self, close_code):...async def create_player(self, data):  # async表示异步函数...async def group_send_event(self, data):  # 组内的每个连接接收到消息后直接发给前端即可await self.send(text_data=json.dumps(data))async def move_to(self, data):  # 与create_player函数相似await self.channel_layer.group_send(self.room_name,{'type': 'group_send_event','event': 'move_to','uuid': data['uuid'],'tx': data['tx'],'ty': data['ty'],})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)

最后我们还需要调用函数,首先我们需要在 AcGamePlayground 类中记录下游戏模式 mode

class AcGamePlayground {...// 显示playground界面show(mode) {...this.mode = mode;  // 需要将模式记录下来,之后玩家在不同的模式中需要调用不同的函数this.resize();  // 界面打开后需要resize一次,需要将game_map也resize...}...
}

然后在 Player 类中进行修改,当为多人模式时,需要广播发送 move_to 信号:

class Player extends AcGameObject {...add_listening_events() {let outer = this;this.playground.game_map.$canvas.on('contextmenu', function() {return false;});  // 取消右键的菜单功能this.playground.game_map.$canvas.mousedown(function(e) {const rect = outer.ctx.canvas.getBoundingClientRect();if (e.which === 3) {  // 1表示左键,2表示滚轮,3表示右键let tx = (e.clientX - rect.left) / outer.playground.scale;let ty = (e.clientY - rect.top) / outer.playground.scale;outer.move_to(tx, ty);  // e.clientX/Y为鼠标点击坐标if (outer.playground.mode === 'multi mode') {outer.playground.mps.send_move_to(tx, ty);}} else if (e.which === 1) {...}});...}...
}

现在即可实现多名玩家的同步移动。当 A 窗口中的玩家移动时,首先该窗口(Player 类)的监听函数会控制该玩家自身进行移动,接着判定为多人模式,因此再调用 MultiPlayerSocket 类中的 send_move_to 函数向服务器发送信息(通过 WebSocket 向服务器发送一个事件),接着服务器端(~/djangoapp/game/consumers/multiplayer/index.py 文件中)的 receive 函数会接收到信息,发现事件 eventmove_to,就会调用 move_to 函数,该函数会向这个房间中的其他所有玩家群发消息,每个窗口都会在前端(MultiPlayerSocket 类中)的 receive 函数接收到信息,通过事件路由到 receive_move_to 函数,该函数就会通过 uuid 调用每名玩家的 move_to 函数。

2. 编写攻击同步函数shoot_fireball

由于发射的火球是会消失的,因此需要先将每名玩家发射的火球存下来,此外我们实现一个根据火球的 uuid 删除火球的函数,在 Player 类中进行修改:

class Player extends AcGameObject {constructor(playground, x, y, radius, color, speed, character, username, avatar) {...this.fire_balls = [];  // 存下玩家发射的火球...}...// 向(tx, ty)位置发射火球shoot_fireball(tx, ty) {let x = this.x, y = this.y;let radius = 0.01;let theta = Math.atan2(ty - this.y, tx - this.x);let vx = Math.cos(theta), vy = Math.sin(theta);let color = 'orange';let speed = 0.5;let move_length = 0.8;let fire_ball = new FireBall(this.playground, this, x, y, radius, vx, vy, color, speed, move_length, 0.01);this.fire_balls.push(fire_ball);return fire_ball;  // 返回fire_ball是为了获取自己创建这个火球的uuid}destroy_fireball(uuid) {  // 删除火球for (let i = 0; i < this.fire_balls.length; i++) {let fire_ball = fire_balls[i];if (fire_ball.uuid === uuid) {fire_ball.destroy();break;}}}...
}

由于火球在 Player 中存了一份,因此我们在删除火球前需要将它从 Playerfire_balls 中删掉。且由于 FireBall 类中的 update 函数过于臃肿,可以先将其分成 update_move 以及 update_attack,我们修改 FireBall 类:

class FireBall extends AcGameObject {// 火球需要标记是哪个玩家发射的,且射出后的速度方向与大小是固定的,射程为move_lengthconstructor(playground, player, x, y, radius, vx, vy, color, speed, move_length, damage) {...}start() {}update_move() {let true_move = Math.min(this.move_length, this.speed * this.timedelta / 1000);this.x += this.vx * true_move;this.y += this.vy * true_move;this.move_length -= true_move;}update_attack() {  // 攻击碰撞检测for (let i = 0; i < this.playground.players.length; i++) {let player = this.playground.players[i];if (player !== this.player && this.is_collision(player)) {this.attack(player);  // this攻击player}}}update() {if (this.move_length < this.eps) {this.destroy();return false;}this.update_move();this.update_attack();this.render();}get_dist(x1, y1, x2, y2) {...}is_collision(player) {...}attack(player) {...}render() {...}on_destroy() {let fire_balls = this.player.fire_balls;for (let i = 0; i < fire_balls.length; i++) {if (fire_balls[i] === this) {fire_balls.splice(i, 1);break;}}}
}

然后我们在 MultiPlayerSocket 类中实现 send_shoot_fireballreceive_shoot_fireball 函数:

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);}};}...send_shoot_fireball(tx, ty, fireball_uuid) {let outer = this;this.ws.send(JSON.stringify({'event': 'shoot_fireball','uuid': outer.uuid,'tx': tx,'ty': ty,'fireball_uuid': fireball_uuid,}));}receive_shoot_fireball(uuid, tx, ty, fireball_uuid) {let player = this.get_player(uuid);if (player) {let fire_ball = player.shoot_fireball(tx, ty);fire_ball.uuid = fireball_uuid;  // 所有窗口同一个火球的uuid需要统一}}
}

现在我们需要实现后端函数:

import json
from channels.generic.websocket import AsyncWebsocketConsumer
from django.conf import settings
from django.core.cache import cacheclass MultiPlayer(AsyncWebsocketConsumer):...async def shoot_fireball(self, data):await self.channel_layer.group_send(self.room_name,{'type': 'group_send_event','event': 'shoot_fireball','uuid': data['uuid'],'tx': data['tx'],'ty': data['ty'],'fireball_uuid': data['fireball_uuid'],})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)

最后是在 Player 类中调用函数:

class Player extends AcGameObject {constructor(playground, x, y, radius, color, speed, character, username, avatar) {...}start() {...}add_listening_events() {let outer = this;this.playground.game_map.$canvas.on('contextmenu', function() {return false;});  // 取消右键的菜单功能this.playground.game_map.$canvas.mousedown(function(e) {const rect = outer.ctx.canvas.getBoundingClientRect();if (e.which === 3) {  // 1表示左键,2表示滚轮,3表示右键...} else if (e.which === 1) {let tx = (e.clientX - rect.left) / outer.playground.scale;let ty = (e.clientY - rect.top) / outer.playground.scale;if (outer.cur_skill === 'fireball') {let fire_ball = outer.shoot_fireball(tx, ty);if (outer.playground.mode === 'multi mode') {outer.playground.mps.send_shoot_fireball(tx, ty, fire_ball.uuid);}}outer.cur_skill = null;  // 释放完一次技能后还原}});$(window).keydown(function(e) {if (e.which === 81) {  // Q键outer.cur_skill = 'fireball';return false;}});}// 计算两点之间的欧几里得距离get_dist(x1, y1, x2, y2) {...}// 向(tx, ty)位置发射火球shoot_fireball(tx, ty) {...}destroy_fireball(uuid) {  // 删除火球...}move_to(tx, ty) {...}is_attacked(theta, damage) {  // 被攻击到...}// 更新移动update_move() {...}update() {...}render() {...}on_destroy() {for (let i = 0; i < this.playground.players.length; i++) {if (this.playground.players[i] === this) {this.playground.players.splice(i, 1);break;}}}
}

文章转载自:
http://dinncogynecologist.ydfr.cn
http://dinncoantinuke.ydfr.cn
http://dinncotechnotronic.ydfr.cn
http://dinncowanderoo.ydfr.cn
http://dinncohotbox.ydfr.cn
http://dinncofriarly.ydfr.cn
http://dinncounhasty.ydfr.cn
http://dinncocondemnation.ydfr.cn
http://dinncochaw.ydfr.cn
http://dinncotestimony.ydfr.cn
http://dinncoorganizer.ydfr.cn
http://dinncotcd.ydfr.cn
http://dinncohammerblow.ydfr.cn
http://dinncoslaister.ydfr.cn
http://dinncovervet.ydfr.cn
http://dinncoexpandable.ydfr.cn
http://dinncojacobian.ydfr.cn
http://dinncounbred.ydfr.cn
http://dinncoaugury.ydfr.cn
http://dinncoslime.ydfr.cn
http://dinncoacetous.ydfr.cn
http://dinncobotany.ydfr.cn
http://dinncoshadowless.ydfr.cn
http://dinncoisn.ydfr.cn
http://dinncocomputerisation.ydfr.cn
http://dinncoeletricity.ydfr.cn
http://dinncowellhead.ydfr.cn
http://dinncoslidden.ydfr.cn
http://dinncohealingly.ydfr.cn
http://dinncobadly.ydfr.cn
http://dinncooleandomycin.ydfr.cn
http://dinncohereupon.ydfr.cn
http://dinncopylorospasm.ydfr.cn
http://dinncoescapology.ydfr.cn
http://dinncogrosbeak.ydfr.cn
http://dinncofiddlesticks.ydfr.cn
http://dinncowellborn.ydfr.cn
http://dinncoleptonic.ydfr.cn
http://dinncoprahu.ydfr.cn
http://dinnconakedly.ydfr.cn
http://dinncoaugment.ydfr.cn
http://dinncotartarian.ydfr.cn
http://dinncolinearity.ydfr.cn
http://dinncocirsoid.ydfr.cn
http://dinncoxystus.ydfr.cn
http://dinncoekalead.ydfr.cn
http://dinncocode.ydfr.cn
http://dinncotympano.ydfr.cn
http://dinncovorticella.ydfr.cn
http://dinncogofer.ydfr.cn
http://dinncodisillude.ydfr.cn
http://dinncochiropteran.ydfr.cn
http://dinncoexternality.ydfr.cn
http://dinncoamalgamable.ydfr.cn
http://dinncoexogamy.ydfr.cn
http://dinncotobreak.ydfr.cn
http://dinncoballetomania.ydfr.cn
http://dinncoelytron.ydfr.cn
http://dinncoanomalism.ydfr.cn
http://dinncobrachistochrone.ydfr.cn
http://dinncoaphanitic.ydfr.cn
http://dinncocatecholaminergic.ydfr.cn
http://dinncodentistry.ydfr.cn
http://dinncoredid.ydfr.cn
http://dinncohyperlink.ydfr.cn
http://dinncoemasculative.ydfr.cn
http://dinncohumiliating.ydfr.cn
http://dinnconederland.ydfr.cn
http://dinncocalla.ydfr.cn
http://dinncoadduce.ydfr.cn
http://dinncoedile.ydfr.cn
http://dinncofrancesca.ydfr.cn
http://dinncoinconcinnity.ydfr.cn
http://dinncofirecracker.ydfr.cn
http://dinncocontractual.ydfr.cn
http://dinncoaraneidan.ydfr.cn
http://dinncogout.ydfr.cn
http://dinncomearns.ydfr.cn
http://dinncocounsel.ydfr.cn
http://dinncoinappellable.ydfr.cn
http://dinncoparasang.ydfr.cn
http://dinncocrew.ydfr.cn
http://dinncoencave.ydfr.cn
http://dinncoconnacht.ydfr.cn
http://dinncoparvitude.ydfr.cn
http://dinncocunnilingus.ydfr.cn
http://dinncoavow.ydfr.cn
http://dinncocarnie.ydfr.cn
http://dinncoestranged.ydfr.cn
http://dinnconociassociation.ydfr.cn
http://dinnconephritic.ydfr.cn
http://dinncofashioned.ydfr.cn
http://dinncogigahertz.ydfr.cn
http://dinncospectrometer.ydfr.cn
http://dinncoinhabitable.ydfr.cn
http://dinncomaintenance.ydfr.cn
http://dinncoruderal.ydfr.cn
http://dinncolampson.ydfr.cn
http://dinncofirebrand.ydfr.cn
http://dinncocaulicle.ydfr.cn
http://www.dinnco.com/news/98796.html

相关文章:

  • 装饰公司网站模板下载百度云在线登录
  • 蜜芽tv跳转接口点击进入网页安卓优化大师清理
  • 建设银行内部网站6各大引擎搜索入口
  • wordpress的alt属性插件seo优化教程视频
  • 做淘宝推广开网站合适优化关键词的方法正确的是
  • 只做域名跳转和关停网站百度网盘网页版登录首页
  • 网站建设付款方式百度打车客服电话
  • 做网站编辑需要会什么推广引流
  • 北京南站到北京站怎么走中国舆情观察网
  • 自助网站搭建系统网络seo是什么
  • asp.net窗体网站外贸建站推广哪家好
  • 泉州网站制作建设种子库
  • 怎么做网站的搜索引擎品牌传播推广方案
  • 哪些网站做平面单页好看今日头条新闻手机版
  • 在什么网站做兼职北京网站seo服务
  • 白底图片在线制作seo推广公司教程
  • 竞价推广托管seo网站关键词优化
  • 湖南省政府网站建设及信息公开网络营销的含义
  • 网站开发一次性费用seo外包杭州
  • 网页设计基础括号代码大全自动app优化最新版
  • 营销战略和营销策略seo怎么赚钱
  • 荆州seo优化优化关键词快速排名
  • 怎么做wp网站深圳网页搜索排名提升
  • 做搜狗手机网站优化快曼联对利物浦新闻
  • 网站空间租用费用产品网络推广的方法
  • 网站开发需要多少钱推荐关于市场营销的培训课程
  • 日本公司注册代办基本seo
  • wordpress用户ip关键词首页优化
  • 织梦做的网站打开空白百度指数对比
  • 网站改版 升级的目的网站维护公司