Bevy 0.11小球生成偏移屏幕及边界限制问题求助
问题原因分析
Bevy 0.11 对2D相机的默认坐标系做了重大调整,你参考的旧教程使用的是旧版本Bevy的坐标系逻辑,两者不匹配导致了小球位置异常:
- 旧版本Bevy:2D相机默认以屏幕左上角为原点(0,0),X轴向右、Y轴向下延伸,屏幕右下角对应坐标为
(window.width, window.height) - Bevy 0.11+:2D相机默认以屏幕中心为原点(0,0),X轴向右、Y轴向上延伸,屏幕左上角对应
(-window.width/2, window.height/2),右下角对应(window.width/2, -window.height/2)
你的代码里把相机和玩家都设置到(window.width/2, window.height/2),在新坐标系下这个点位于屏幕右下角外侧,自然看不到小球;而使用默认Transform时,相机和玩家都在(0,0)(屏幕中心),你看到的(32,32)应该是精灵左上角相对于屏幕的坐标(精灵大小64x64,中心在(0,0)时左上角为(-32,32),可能是坐标显示混淆),此时边界限制代码只适配了向左/向下的移动,是因为旧教程的逻辑基于左上角原点,和新坐标系不兼容。
解决方案
有两种方式可以解决这个问题,根据你的需求选择:
方案1:切换回旧教程的左上角坐标系
修改相机的配置,让它使用旧版本的原点规则,这样你可以完全沿用教程的后续代码:
pub fn spawn_camera(mut commands: Commands, window_query: Query<&Window, With<PrimaryWindow>>) { commands.spawn(Camera2dBundle { camera_2d: Camera2d { // 设置相机原点为屏幕左上角 default_position: Camera2dDefaultPosition::TopLeft, ..default() }, // 相机位置保持在(0,0)即可 transform: Transform::from_xyz(0.0, 0.0, 0.0), ..default() }); }
此时你的spawn_player函数无需修改,小球会正确生成在屏幕中心,后续教程的边界限制代码也能直接使用。
方案2:适配Bevy 0.11的中心坐标系
如果你想使用新版本的默认坐标系,需要调整玩家生成位置和边界限制逻辑:
- 修改玩家生成位置为屏幕中心
(0,0):
pub fn spawn_player( mut commands: Commands, asset_server: Res<AssetServer>, ) { commands.spawn(( SpriteBundle { transform: Transform::from_xyz(0.0, 0.0, 0.0), texture: asset_server.load("sprites/ball_blue_large.png"), ..default() }, Player {}, )); }
- 重写边界限制系统,适配中心坐标系:
pub fn constrain_player_movement( mut player_query: Query<&mut Transform, With<Player>>, window_query: Query<&Window, With<PrimaryWindow>>, ) { let window = window_query.get_single().unwrap(); let mut player_transform = player_query.single_mut(); let half_player_size = PLAYER_SIZE / 2.0; let half_window_width = window.width() / 2.0; let half_window_height = window.height() / 2.0; // 限制X轴范围:从屏幕左边缘+玩家半径 到 屏幕右边缘-玩家半径 player_transform.translation.x = player_transform.translation.x.clamp( -half_window_width + half_player_size, half_window_width - half_player_size, ); // 限制Y轴范围:从屏幕下边缘+玩家半径 到 屏幕上边缘-玩家半径 player_transform.translation.y = player_transform.translation.y.clamp( -half_window_height + half_player_size, half_window_height - half_player_size, ); }
记得在main函数里添加这个系统:
.add_systems(Update, constrain_player_movement)
内容的提问来源于stack exchange,提问作者robi503
相关产品推荐
相关产品推荐

