- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用 socket.io 发出和表达时遇到问题。我想发出一些数据(我正在创建一个网页游戏),所以我需要将玩家数据发送到特定的大厅。例如,我通过此链接创建一个大厅:本地主机:8000/test/lobbyName我只需要向该大厅发送信息,而不向其他大厅发送信息。我怎样才能做到这一点?
这是我的代码:
www
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('progetto:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.Server(app);
var io = require('socket.io').listen(server);
//Game
let players = {};
let xCoin = Math.floor((Math.random() * 1200));
io.on('connection', function(socket){
console.log('A user connected');
players[socket.id] = {
rotation: 0,
x: 0,
y: 0,
layer: Math.floor((Math.random() * -1200)),
playerId: socket.id,
frame: 0,
haveGun: true,
};
socket.emit('currentPlayers', players);
socket.broadcast.emit('newPlayer', players[socket.id]);
socket.emit('newCoin', xCoin);
socket.on('disconnect', function () {
console.log('User disconnected');
delete players[socket.id];
io.emit('disconnect', socket.id);
});
socket.on('playerMovement', function (movementData) {
players[socket.id].x = movementData.x;
players[socket.id].y = movementData.y;
players[socket.id].layer = movementData.layer;
players[socket.id].frame = movementData.frame;
socket.broadcast.emit('playerMoved', players[socket.id]);
});
socket.on('playerAngle', function (movementData) {
socket.broadcast.emit('gunAngle', socket.id, movementData);
});
socket.on('playerShotting', function (movementData) {
socket.broadcast.emit('shotting', socket.id, movementData);
});
socket.on('coinTaken', function (x, y) {
socket.broadcast.emit('taken', x, y);
});
socket.on('createGun', function (n1, n2) {
socket.broadcast.emit('enemyGun', players[socket.id].playerId, n1, n2);
});
})
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
main.js
let game = new Phaser.Game(
{
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
physics: {
default: 'arcade',
arcade: {
debug: false,
gravity: { y: 0 }
}
},
scene: {
preload: preload,
create: create,
update: update
}
});
let playerInfo = ['Daniel', 100, 100, 3, 12, 1000]; //nickname , gold, life , jump , spead , gravity
let player = new Player(game, playerInfo);
let background = new Background();
let settings = new Settings();
function preload () {
load(this);
loading(this);
settings.preload();
}
function create () {
let playerArray = [0, 0];
this.socket = io();
player.debug(this);
var self = this;
this.otherPlayers = this.physics.add.group();
this.socket.on('currentPlayers', function (players) {
Object.keys(players).forEach(function (id) {
if (players[id].playerId === self.socket.id) {
player.createPlayer(self, players[id]);
}else if(playerArray[0] == 0) {
playerArray[0] = players[id].playerId;
player.createEnemyOne(self, players[id]);
}else if(playerArray[1] == 0) {
playerArray[1] = players[id].playerId;
player.createEnemyTwo(self, players[id]);
}else {
playerArray[2] = players[id].playerId;
player.createEnemyTre(self, players[id]);
}
});
});
this.socket.on('newPlayer', function (playerInfo) {
if(playerArray[0] == 0) {
playerArray[0] = playerInfo.playerId;
player.createEnemyOne(self, playerInfo);
}else if(playerArray[1] == 0) {
playerArray[1] = playerInfo.playerId;
player.createEnemyTwo(self, playerInfo);
}else {
playerArray[2] = playerInfo.playerId;
player.createEnemyTre(self, playerInfo);
}
});
this.socket.on('disconnect', function (playerId) {
self.otherPlayers.getChildren().forEach(function (otherPlayer) {
if(playerId === otherPlayer.playerId) {
otherPlayer.destroy();
}
for(var i = 0; i < 2; i++) {
if(playerId == playerArray[i]) {
playerArray[i] = 0;
}
}
});
});
this.socket.on('playerMoved', function (playerInfo) {
if(playerArray[0] == playerInfo.playerId) {
move = playerInfo.layer - background.midle.x;
player.setPosition(player.enemy, player.gun1,player.textEn1, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun1);
}else if(playerArray[1] == playerInfo.playerId) {
move = playerInfo.layer - background.midle.x;
player.setPosition(player.enemy2, player.gun2, player.textEn2, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun2);
}else {
move = playerInfo.layer - background.midle.x;
player.setPosition(player.enemy3, player.gun3, player.textEn3, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun3);
}
});
this.input.on('pointermove', function (pointer) {
if(player.haveGun) {
let angle = (Phaser.Math.Angle.Between(player.player.x , player.player.y, pointer.x , pointer.y)) * (180/Math.PI);
player.gun_angle(angle + 90);
}
});
this.socket.on('gunAngle', function (id, playerInfo) {
if(playerArray[0] == id) {
if(player.haveGun1) player.gunAngle(player.gun1, playerInfo.angle);
}else if(playerArray[1] == id) {
if(player.haveGun2) player.gunAngle(player.gun2, playerInfo.angle);
}else {
if(player.haveGun3) player.gunAngle(player.gun3, playerInfo.angle);
}
});
this.socket.on('shotting', function (id, playerInfo) {
if(playerArray[0] == id) {
player.shot(self.bulletsEnemy, player.enemy, playerInfo);
}else if(playerArray[1] == id) {
player.shot(self.bulletsEnemy2,player.enemy2, playerInfo);
}else {
player.shot(self.bulletsEnemy3,player.enemy3, playerInfo);
}
});
this.socket.on('newCoin', function (x) {
background.worldObject.createCoin(self, x, true);
});
this.socket.on('taken', function (x, y) {
background.worldObject.coin.destroy();
background.worldObject.createCoin(self, x, y);
});
this.socket.on('enemyGun', function (id, info, info2) {
if(playerArray[0] == id) {
player.enemyGun1(self, info, info2);
}else if(playerArray[1] == id) {
player.enemyGun2(self, info, info2);
}else {
player.enemyGun3(self, info, info2);
}
});
background.createBackground(this);
settings.create(this);
}
function loading(game) {
let progressBar = game.add.graphics();
let progressBox = game.add.graphics();
let width = 320, heigth = 50;
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(window.innerWidth / 2 - (width / 2), window.innerHeight / 2 - (heigth / 2), width, heigth);
let loadingText = game.make.text({
x: window.innerWidth / 2,
y: window.innerHeight / 2 - 50,
text: 'Loading...',
style: {
font: '20px monospace',
fill: '#ffffff'
}
});
let percentText = game.make.text({
x: window.innerWidth / 2,
y: window.innerHeight / 2 - 5,
text: '0%',
style: {
font: '18px monospace',
fill: '#ffffff'
}
});
let assetText = game.make.text({
x: window.innerWidth / 2 - 100,
y: window.innerHeight / 2 + 50,
text: '',
style: {
font: '18px monospace',
fill: '#ffffff'
}
});
percentText.setOrigin(0.5, 0.5);
loadingText.setOrigin(0.5, 0.5);
game.load.on('progress', function (value) {
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(window.innerWidth / 2 - ((width - 20) / 2), window.innerHeight / 2 - ((heigth - 20) / 2), 300 * value, heigth - 20);
percentText.setText(parseInt(value * 100) + '%');
});
game.load.on('fileprogress', function (file) {
console.log(file.key);
assetText.setText('Loading asset: ' + file.key);
});
game.load.on('complete', function () {
progressBar.destroy();
progressBox.destroy();
loadingText.destroy();
percentText.destroy();
assetText.destroy();
});
}
function load(game) {
let playerImg = ['/images/snowman.png', '/images/snowman.png', '/images/snowman.png', '/images/snowman.png'];
let sound = ['/sounds/Jump.mp3', '/sounds/Explosion.mp3', '/sounds/Pickup_Coin.mp3']
let groundImg = ['/images/ground.png','/images/nuvola.png', '/images/map.json', '/images/coin.png', '/images/heart.png', '/images/pozioni.png'];
game.load.spritesheet('player', playerImg[0], { frameWidth: 128, frameHeight: 128 });
game.load.spritesheet('enemy', playerImg[1], { frameWidth: 128, frameHeight: 128 });
game.load.spritesheet('enemy2', playerImg[2], { frameWidth: 128, frameHeight: 128 });
game.load.spritesheet('enemy3', playerImg[3], { frameWidth: 128, frameHeight: 128 });
game.load.audio('jumpAudio', sound[0]);
game.load.audio('shotAudio', sound[1]);
game.load.audio('coinAudio', sound[2]);
game.load.image("tiles1", groundImg[0]);
game.load.image("tiles2", groundImg[1]);
game.load.tilemapTiledJSON("map", groundImg[2]);
game.load.spritesheet("coin", groundImg[3], { frameWidth: 128, frameHeight: 128 });
game.load.spritesheet("heart", groundImg[4], { frameWidth: 128, frameHeight: 128 });
game.load.spritesheet("pozions", groundImg[5], { frameWidth: 32, frameHeight: 32 });
}
function update () {
if(player.life != false) player.update(this);
background.update(this);
background.midle.setCollisionByProperty({colision:true});
this.physics.add.collider(player.player, background.midle);
}
window.addEventListener('resize', function() {
game.scale.setGameSize( window.innerWidth, window.innerHeight);
background.midle.displayHeight = window.innerHeight;
player.resize();
settings.resize();
});
然后我想让用户创建他们的房间,所以我按照我找到的教程进行操作,这就是我的 index.js 文件中的代码:
router.get('/test/:id', function(req, res, next){
res.render('test', {output: req.params.id} );
})
router.post('/test/submit', function(req, res, next){
var id = req.body.id;
res.redirect('/test/' + id);
})
这是形式:
<form action="/test/submit" method="post">
<input type="text" name="id">
<button type="submit">Submit</button>
</form>
现在,我如何使用 socket.io 将玩家数据仅发送到玩家连接的重定向页面?
抱歉我的英语不好,谢谢
最佳答案
您应该使用socket.io
rooms or namespaces .
房间
在套接字连接上,将套接字连接到特定房间,在您的情况下:lobbyName
例如,然后仅向该房间发出
io.to('lobbyName').emit(...)
命名空间
在后端,为每个大厅创建一个命名空间。
const lobbies = ['/lobbyName'];
for(const lobby of lobbies) {
const nsp = io.of(lobby);
// Your socket logic in here
nsp.on('connection', socket => {
console.log('someone connected');
});
}
并连接到前端的特定命名空间:
const socket = io('/lobbyName');
关于javascript - 如何一起使用socket.io和express?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58961151/
我想要的是能够在输入获得焦点或失去焦点时执行某些操作(两个事件)。 我尝试了以下方法,但这按事件单独工作(单独编码时):仅在焦点上,或仅在失去焦点时。 另外,我希望它尽可能跨平台(包括触摸设备),这是
我分别研究了TableView的Filtering和Pagination。 过滤: this帖子帮助我满足了我的需要 分页: this , this帖子也帮助了我 我想像这样将它们组合在一起: 详情-
我是 TDD 方法的新手,所以我想知道是否有人经历过这种机智可以启发我一点。我想获得一些关于如何一起使用 UML 和 TDD 方法的线索。 我已经习惯了:用 UML 设计 --> 生成骨架类(然后保持
我尝试使用入口点和 cmd 设置 Docker。 FROM debian:stretch RUN apt-get update && \ apt install gnupg ca-certificat
我想要一个 Class 对象,但我想强制它所代表的任何类扩展类 A 并实现接口(interface) B。 我能做到: Class 或者: Class 但我不能两者兼得。有办法做到这一点吗? 最佳答案
我是 Rubymine 的长期用户。 Rubymine 非常适合基于 html 的 Rails 应用程序,但我现在正在做更多的 SPA 客户端工作(例如 javascript/react)。我发现我真
我注意到我使用的某个脚本依赖于原型(prototype)。 (Lightbox 2) 它会与 jQuery 在同一页面上一起工作吗?有没有办法确保它们不冲突? 最佳答案 可以,但你需要采取 speci
我需要对表中显示的数据进行分页并通过 ajax 调用获取它 - 这是我通过使用具有以下配置的 dataTables 插件来完成的 - bServerSide : true; sAjaxSource :
我是 gtk 新手,所以想知道在 C 语言中归档和 gtk 是否可以一起使用?例如,我可以从 .txt 文件中读取,然后在相同的代码中使用 gtk 在标签或其他内容中显示它吗?如果是,怎么办? 谢谢!
有没有人设法得到Bck2Brwsr最近与 Java 8/JavaFX 8 一起工作?有没有兼容的机会?我找不到太多关于它的信息,也没有一个好的起点。使用给定的 Maven archetype我遇到了几
在我的应用程序中,用户通过 openid(与 stackoverflow 相同)登录/注销。 我想通过 oauth 向第三方应用程序开放我的应用程序。 如何创建我的 openid-consumer 应
我在启动和运行 Hibernate 和 Spring 时遇到一些问题。我有一个网络服务器项目,它使用了其他几个具有持久实体的项目。我遇到的问题是,对于存储在 WEB-INF/libs 内的另一个 ja
我有 @ControllerAdvice 类,它处理一组异常。我们还有一些其他异常,这些异常用 @ResponseStatus 注释进行注释。为了结合这两种方法,我们使用博客文章中描述的技术:http
我想在屏幕上使用进度条而不是 progressDialog。 我在我的 XML View 文件中插入了一个进度条,我想让它在加载时显示并在不加载时禁用它。 所以我使用的是可见的,但它发生了,所以其余的
CREATE TABLE `users` ( `id` int(11) AUTO_INCREMENT, `academicdegree` varchar(255),
IN() 中使用的查询返回:1, 2。然而,整个查询返回 0 行,这是不可能的,因为它们存在。我在这里做错了什么? SELECT DISTINCT li.auto_id FROM links
亲们, 我如何在使用 Jade 生成的表单上实现 jQuery 样式?我想做的是美化 表单并使它们可点击。我在 UI 方面很糟糕。期间。 我如何在表单上实现这个可选择的方法? http://jquer
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我可以: auto o1 = new Content; 但不能: std::shared_ptr o1(new Content); std::unique_ptr o1(new Content); 我
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
我是一名优秀的程序员,十分优秀!