Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3d game example #1252

Merged
merged 7 commits into from
Jan 21, 2021
Merged

3d game example #1252

merged 7 commits into from
Jan 21, 2021

Conversation

mockersf
Copy link
Member

Eat the cakes. Eat them all, I dare you.

...

And experience the powerful sugar rush of the alien.

Small 3d game example that I had fun doing this afternoon.

@mockersf
Copy link
Member Author

mockersf commented Jan 16, 2021

Controls are arrow key to move, spacebar to restart after losing.

Game shows spawning and controlling gltf scenes in various ways, changing the camera, systems with state.

Some of the systems/controls could be nicer with more complexity, but goal was too keep it short

alien.cake.addict.mp4

@tigregalis
Copy link
Contributor

tigregalis commented Jan 17, 2021

Nice work.

The camera movement makes me uncomfortable though haha.

Here's a camera movement system I've come up with - in general it points to the mid-point between the alien and the cake:

#[derive(Default)]
struct Game {
    board: Vec<Vec<Cell>>,
    player: Player,
    bonus: Bonus,
    score: i32,
    cake_eaten: u32,
    camera_should_focus: Vec3,
    camera_is_focus: Vec3,
}

const RESET_FOCUS: [f32; 3] = [
    BOARD_SIZE_I as f32 / 2.0,
    0.0,
    BOARD_SIZE_J as f32 / 2.0 - 0.5,
];

fn setup_cameras(commands: &mut Commands, mut game: ResMut<Game>) {
    game.camera_should_focus = Vec3::from(RESET_FOCUS);
    game.camera_is_focus = game.camera_should_focus;
    commands
        .spawn(Camera3dBundle {
            transform: Transform::from_xyz(
                -(BOARD_SIZE_I as f32 / 2.0),
                2.0 * BOARD_SIZE_J as f32 / 3.0,
                BOARD_SIZE_J as f32 / 2.0 - 0.5,
            )
            .looking_at(game.camera_is_focus, Vec3::unit_y()),
            ..Default::default()
        })
        .spawn(CameraUiBundle::default());
}

fn move_camera(
    time: Res<Time>,
    mut game: ResMut<Game>,
    mut transforms: QuerySet<(Query<(&mut Transform, &Camera)>, Query<&Transform>)>,
) {
    const SPEED: f32 = 2.0;
    // if there is both a player and a bonus, target the mid-point of them
    if let (Some(player_entity), Some(bonus_entity)) = (game.player.entity, game.bonus.entity) {
        if let (Ok(player_transform), Ok(bonus_transform)) = (
            transforms.q1().get(player_entity),
            transforms.q1().get(bonus_entity),
        ) {
            game.camera_should_focus = player_transform
                .translation
                .lerp(bonus_transform.translation, 0.5);
        }
    // otherwise, if there is only a player, target the player
    } else if let Some(player_entity) = game.player.entity {
        if let Ok(player_transform) = transforms.q1().get(player_entity) {
            game.camera_should_focus = player_transform.translation;
        }
    // otherwise, target the middle
    } else {
        game.camera_should_focus = Vec3::from(RESET_FOCUS);
    }
    // calculate the camera motion based on the difference between where the camera is looking
    // and where it should be looking; the greater the distance, the faster the motion;
    // smooth out the camera movement using the frame time
    let mut camera_motion = game.camera_should_focus - game.camera_is_focus;
    if camera_motion.length() > 0.2 {
        camera_motion *= SPEED * time.delta_seconds();
        // set the new camera's actual focus
        game.camera_is_focus += camera_motion;
    }
    // look at that new camera's actual focus
    for (mut transform, camera) in transforms.q0_mut().iter_mut() {
        if camera.name == Some(CAMERA_3D.to_string()) {
            transform.look_at(game.camera_is_focus, Vec3::unit_y());
        }
    }
}

@cart
Copy link
Member

cart commented Jan 17, 2021

Yeah I like everything about this except the "motion sickness as a game mechanic" aspect. Some people are very sensitive to that and I don't want to make them sick 😄

@mockersf
Copy link
Member Author

Here's a camera movement system I've come up with

Oh I like that your camera actually does something useful and interesting to show in an example

@mockersf
Copy link
Member Author

"motion sickness as a game mechanic"

It actually came from me trying to do something useful with the camera and just failing to have controls that I liked so... heh

@cart
Copy link
Member

cart commented Jan 21, 2021

Awesome. This looks good to me!

@cart cart merged commit 8c33da0 into bevyengine:master Jan 21, 2021
rparrett pushed a commit to rparrett/bevy that referenced this pull request Jan 27, 2021
@mockersf mockersf deleted the 3d-example branch April 27, 2021 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants