- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在游戏客户端和服务器之间发送事件,我已经让它工作了,但我不知道如何用 bevy 来做。
我依赖于使用 tokios async TcpStream
,因为我必须能够使用 OwnedWriteHalf
和 OwnedReadhalf
将流拆分为 stream.into_split()
.
我的第一个想法是生成一个处理连接的线程,然后使用 mpsc::channel
然后我使用 app.insert_resource(Queue)
将这个队列包含到 bevy 资源中,并在游戏循环中从中提取事件。
队列:
use tokio::sync::mpsc;
pub enum Instruction {
Push(GameEvent),
Pull(mpsc::Sender<Option<GameEvent>>),
}
#[derive(Clone, Debug)]
pub struct Queue {
sender: mpsc::Sender<Instruction>,
}
impl Queue {
pub fn init() -> Self {
let (tx, rx) = mpsc::channel(1024);
init(rx);
Self{sender: tx}
}
pub async fn send(&self, event: GameEvent) {
self.sender.send(Instruction::Push(event)).await.unwrap();
}
pub async fn pull(&self) -> Option<GameEvent> {
println!("new pull");
let (tx, mut rx) = mpsc::channel(1);
self.sender.send(Instruction::Pull(tx)).await.unwrap();
rx.recv().await.unwrap()
}
}
fn init(mut rx: mpsc::Receiver<Instruction>) {
tokio::spawn(async move {
let mut queue: Vec<GameEvent> = Vec::new();
loop {
match rx.recv().await.unwrap() {
Instruction::Push(ev) => {
queue.push(ev);
}
Instruction::Pull(sender) => {
sender.send(queue.pop()).await.unwrap();
}
}
}
});
}
但是因为所有这些都必须是异步的,所以我在同步游戏循环中阻止了 pull()
函数。我使用 futures-lite
crate 执行此操作:
fn event_pull(
communication: Res<Communication>
) {
let ev = future::block_on(communication.event_queue.pull());
println!("got event: {:?}", ev);
}
这工作正常,但在大约 5 秒后整个程序停止并且不再接收任何事件。
future::block_on()
似乎会无限期阻塞。
拥有 main 函数,其中 bevy::prelude::App
被构建并运行,成为异步 tokio::main
函数也可能是一个问题在这里。
可能最好包装异步 TcpStream
初始化和 tokio::sync::mpsc::Sender
以及 Queue.pull
到同步函数中,但我不知道该怎么做。
有人能帮忙吗?
可以找到 repo here
只需编译server
和client
,然后按相同的顺序运行它们。
最佳答案
我通过将每个 tokio::sync::mpsc
替换为 crossbeam::channel
来让它工作,这可能是个问题,因为它会阻塞
并手动初始化 tokio 运行时。
所以初始化代码是这样的:
pub struct Communicator {
pub event_bridge: bridge::Bridge,
pub event_queue: event_queue::Queue,
_runtime: Runtime,
}
impl Communicator {
pub fn init(ip: &str) -> Self {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_io()
.build()
.unwrap();
let (bridge, queue, game_rx) = rt.block_on(async move {
let socket = TcpStream::connect(ip).await.unwrap();
let (read, write) = socket.into_split();
let reader = TcpReader::new(read);
let writer = TcpWriter::new(write);
let (bridge, tcp_rx, game_rx) = bridge::Bridge::init();
reader::init(bridge.clone(), reader);
writer::init(tcp_rx, writer);
let event_queue = event_queue::Queue::init();
return (bridge, event_queue, game_rx);
});
// game of game_rx events to queue for game loop
let eq_clone = queue.clone();
rt.spawn(async move {
loop {
let event = game_rx.recv().unwrap();
eq_clone.send(event);
}
});
Self {
event_bridge: bridge,
event_queue: queue,
_runtime: rt,
}
}
}
main.rs
看起来像这样:
fn main() {
let communicator = communication::Communicator::init("0.0.0.0:8000");
communicator.event_bridge.push_tcp(TcpEvent::Register{name: String::from("luca")});
App::new()
.insert_resource(communicator)
.add_system(event_pull)
.add_plugins(DefaultPlugins)
.run();
}
fn event_pull(
communication: Res<communication::Communicator>
) {
let ev = communication.event_queue.pull();
if let Some(ev) = ev {
println!("ev");
}
}
也许有更好的解决方案。
关于rust - 如何使用 tokio async TcpStream 将 bevy 游戏连接到外部 TCP 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71636383/
我对 Bevy 和 Rust 还很陌生。我想加载一个 png 图像并获取它的宽度和高度。下面的代码不会打印“found resource ...”。 fn setup( mut commands: C
我正在和 Bevy 一起制作一个小 boids 玩具,每个 boid 的速度/加速度取决于它周围 boid 的位置和速度值。这意味着对于每个 boid,我想运行一些依赖于其他 boid 的某个子集的逻
这是一个非常简单的问题。 我已经重写了我的代码以处理新版本 bevy 附带的语法和其他更改。 编译时似乎一切正常,除了实体的消失。 我在上述实体中生成,例如: commands.spawn_bundl
我正在尝试取消绘制我使用Commands.spawn()函数生成的一些实体,但它需要为Commands.Entity().despawn函数提供不同类型的参数。以下是我的代码:。此代码给出错误:Exp
我正在尝试取消绘制我使用Commands.spawn()函数生成的一些实体,但它需要为Commands.Entity().despawn函数提供不同类型的参数。以下是我的代码:。此代码给出错误:Exp
是否可以通过在 bevy rust 中包含实体来获取组件列表?例如用于调试目的。 use bevy::prelude::*; fn main() { App::build()
我想创建一个第一人称相机。 我已经研究了其他几个实现的源代码,比如 https://github.com/mcpar-land/bevy_fly_camera https://github.com/s
我想将我的对象旋转给定的量并将其向前平移以创建一个可操纵的坦克。 我找不到解决方法,所有的矩阵、向量和四元数让我很难找到解决方案。 这是我想要做的 Unity 等价物: transform.Rotat
Bevy ,一个新的 Rust 游戏引擎和 ECS,有一个特性,它根据参数的类型“范围”它的系统。来自 its docs : The parameters we pass in to a "syste
我目前正在尝试使用事件在我的 Bevy 游戏中角色跳跃时发出信号。我希望处理玩家输入的系统发送一个 JumpedEvent然后可以被其他系统接收以执行适当的操作(设置正确的玩家动画、速度、声音等),但
我试图查看按下鼠标的位置,以便我可以选择我的角色。 我已经尝试了以下 #[derive(Default)] struct State { // Set up from example mous
在 bevy 示例 breakout 中只使用矩形,有加载 Sprite 的示例,有加载 3d 网格的示例。在 2d 中,我想绘制一个三角形(或其他多边形),但我无法通过文档弄明白。 最佳答案 目前不
以下程序是大量 SpriteComponents 的一个非常简约的示例。在此示例中,使用 FPS 计数器,您可以看到 SpriteComponents 的成本似乎是多么高。 我确实注意到,如果我重用
我在 empty 借了一笔钱变量,我想延长它的生命周期。在注释的代码块中,我尝试解决它,但引用不再可用。我必须再次遍历循环才能找到匹配项才能对其采取行动。 如何遍历查询以寻找最佳匹配,然后在我知道它是
我试图根据玩家是在屏幕上向左还是向右移动来翻转 Sprite 。我目前修改 SpriteSheetComponents 变换的方法如下,似乎根本没有改变 Sprite : fn player_di
我想创建一个 portal-like effect使用 Bevy . Unity 似乎有一个 render texture实现这一目标。 有没有办法在 Bevy 中做同样的事情?如果没有, futur
我不太确定我是否完全理解实体组件系统方法,这可能是出现此问题的原因之一。仍在与 OOP 思维方式作斗争! 我正在尝试创建一个类似于网络的数据结构,例如,类似于电路的东西: 因此,例如,实体 4 连接到
使用 Res>我可以在屏幕空间坐标(左下角为零)中获得鼠标位置的变化,例如 #[derive(Default)] struct State { cursor_moved_reader: Eve
当我尝试在character.ars文件中定义此常量时,出现错误:。错误是:
在 Amethyst 或许多其他游戏引擎中,update 之间存在区别。对于逻辑和fixed_update用于渲染。 Bevy 0.4 引入了状态,但只有 enter , update和 exit生命
我是一名优秀的程序员,十分优秀!