0

I'm working on a 2048 game using the Bevy game engine (version 0.10.1), and I've encountered an intermittent issue when rendering the game board. In my code, I have a function display_game_board that iterates through the game board and spawns entities representing each tile. For each tile with a value, I also want to spawn a text entity displaying that value.

To achieve this, I originally used commands.spawn to create the tile entity and then with_children to spawn the text entity as a child of the tile entity. However, I noticed that the text entities were sometimes not rendered properly or were not displayed at all.

Works:

Game board with the entities properly rendered

Doesn't work:

Game board with out the entities properly rendered

In a try too fix this, I attempted to use bevy::ecs::schedule::ShouldRun to insert a delay and spawn the text entities at the end of the frame, however, I learned that bevy::ecs::schedule::ShouldRun is deprecated in Bevy version 0.10.1 and no longer available. This approach doesn't work as expected, and the intermittent issue with rendering of text entities persists.

Given that ShouldRun is deprecated, I'm looking for an alternative method to properly handle the delayed spawning of child entities in Bevy. I suspect that the intermittent rendering issue might be related to the timing of entity construction and how the ECS system processes entities.

fn display_game_board(commands: &mut Commands, game_board: GameBoard, fonts: GameFonts) {
        // Calculate the total width and height of the board based on the size of each tile and the number of tiles in a row/column
        let tile_size = 100.0; // Adjust the size of each tile as needed
        let gap_size = 5.0; // Adjust the size of the gap between tiles as needed
        let board_width = (tile_size + gap_size) * game_board.size as f32 - gap_size;
        let board_height = (tile_size + gap_size) * game_board.size as f32 - gap_size;

        // Calculate the translation vector that centers the board on the screen
        let translation = Vec3::new(
            (-board_width / 2.0) + (tile_size / 2.0),
            (-board_height / 2.0) + (tile_size / 2.0),
            0.0,
        );

        for row in 0..game_board.size {
            for col in 0..game_board.size {
                // Calculate the translation vector to position each tile in the center of the board
                let tile_translation = translation
                    + Vec3::new(
                        col as f32 * (tile_size + gap_size),
                        row as f32 * (tile_size + gap_size),
                        0.0,
                    );

                // For each tile, create a sprite representing the tile
                commands.spawn(SpriteBundle {
                    sprite: Sprite {
                        color: Color::rgba_u8(200, 200, 200, 6).into(), // Default color for empty tiles
                        custom_size: Some(Vec2::new(tile_size, tile_size)),
                        ..default()
                    },
                    transform: Transform::from_translation(tile_translation),
                    ..default()
                });

                if let Some(value) = game_board.board[row][col] {
                    // If the tile has a value, create the text to display the value of the tile
                    let text = value.to_string();

                    // Calculate the brightness based on the value
                    let brightness = (value as f32 / 2048.0).min(1.0); // Divide by the maximum value (2048) to get a value between 0 and 1

                    // For each tile with a value, create a sprite representing the tile with grayscale color
                    commands
                        .spawn(SpriteBundle {
                            sprite: Sprite {
                                color: Color::rgba(brightness, brightness, brightness, 1.0).into(),
                                custom_size: Some(Vec2::new(tile_size, tile_size)),
                                ..default()
                            },
                            transform: Transform::from_translation(tile_translation),
                            ..default()
                        })
                        .with_children(|tile_parent| {
                            tile_parent.spawn(Text2dBundle {
                                text: Text::from_section(
                                    text,
                                    TextStyle {
                                        font: fonts.main_font.clone(),
                                        font_size: 40.0,
                                        color: Color::WHITE,
                                    },
                                ),
                                transform: Transform::from_translation(Vec3 {
                                    x: 0.0,
                                    y: 0.0,
                                    z: 0.0,
                                }),
                                visibility: Visibility::Visible,
                                ..default()
                            });
                        });
                }
            }
        }
    }

Can someone guide me on how to implement a delay for spawning child entities in Bevy version 0.10.1, or suggest another approach to handle this situation?

1 Answers1

1

The problem was caused by the control of the deep using the zaxis.

I was rendering the tile using this values for the translation to set the tile position:

// Calculate the translation vector that centers the board on the screen
        let translation = Vec3::new(
            x: (-board_width / 2.0) + (tile_size / 2.0),
            y: (-board_height / 2.0) + (tile_size / 2.0),
            z: 0.0,
        );

// Calculate the translation vector to position each tile in the center of the board
                let tile_translation = translation
                    + Vec3::new(
                        col as f32 * (tile_size + gap_size),
                        row as f32 * (tile_size + gap_size),
                        0.0,
                    );

And after that I was rendering the tile text value in the same position of the z axis

transform: Transform::from_translation(Vec3 {
                                    x: 0.0,
                                    y: 0.0,
                                    z: 0.0,
                                }),

That was the origin of the problem, by changing the position in the zaxis we allow the value to be rendering hover of the tile

transform: Transform::from_translation(Vec3 {
                                    x: 0.0,
                                    y: 0.0,
                                    z: 1.0,
                                }),

In a 2d scene the deep is controlled by the zaxis and taking in mid this values could avoid this kind of problems.