Skip to content

Commit e1b9f54

Browse files
authored
Introduce testbed examples starting with 2d (#15954)
# Objective - Make progress for #15918 - Start with 2d ## Solution - Remove screenshots for existing examples as they're not deterministic - Create new "testbed" example category, with a 2d one to start ## Testing - Run `CI_TESTING_CONFIG=.github/example-run/testbed_2d.ron cargo run --example testbed_2d --features "bevy_ci_testing"` - ??? - Check the screenshots
1 parent fc659a6 commit e1b9f54

File tree

6 files changed

+194
-3
lines changed

6 files changed

+194
-3
lines changed

.github/example-run/breakout.ron

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
fixed_frame_time: Some(0.03),
44
),
55
events: [
6-
(200, Screenshot),
76
(900, AppExit),
87
]
98
)

.github/example-run/load_gltf.ron

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
frame_time: Some(0.03),
44
),
55
events: [
6-
(100, Screenshot),
76
(300, AppExit),
87
]
98
)

.github/example-run/testbed_2d.ron

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(
2+
events: [
3+
(100, Screenshot),
4+
(200, Custom("switch_scene")),
5+
(300, Screenshot),
6+
(400, Custom("switch_scene")),
7+
(500, Screenshot),
8+
(600, Custom("switch_scene")),
9+
(700, Screenshot),
10+
(800, AppExit),
11+
]
12+
)

.github/workflows/send-screenshots-to-pixeleagle.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ on:
1919
jobs:
2020
send-to-pixel-eagle:
2121
name: Send screenshots to Pixel Eagle
22-
runs-on: ubuntu-latest
22+
runs-on: ubuntu-24.04
2323
steps:
2424

2525
- name: Download artifact

Cargo.toml

+9
Original file line numberDiff line numberDiff line change
@@ -3834,3 +3834,12 @@ name = "Monitor info"
38343834
description = "Displays information about available monitors (displays)."
38353835
category = "Window"
38363836
wasm = false
3837+
3838+
# Testbed
3839+
[[example]]
3840+
name = "testbed_2d"
3841+
path = "examples/testbed/2d.rs"
3842+
doc-scrape-examples = true
3843+
3844+
[package.metadata.example.testbed_2d]
3845+
hidden = true

examples/testbed/2d.rs

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//! 2d testbed
2+
//!
3+
//! You can switch scene by pressing the spacebar
4+
5+
#[cfg(feature = "bevy_ci_testing")]
6+
use bevy::dev_tools::ci_testing::CiTestingCustomEvent;
7+
use bevy::prelude::*;
8+
9+
fn main() {
10+
let mut app = App::new();
11+
app.add_plugins((DefaultPlugins,))
12+
.init_state::<Scene>()
13+
.enable_state_scoped_entities::<Scene>()
14+
.add_systems(OnEnter(Scene::Shapes), shapes::setup)
15+
.add_systems(OnEnter(Scene::Bloom), bloom::setup)
16+
.add_systems(OnEnter(Scene::Text), text::setup)
17+
.add_systems(OnEnter(Scene::Sprite), sprite::setup)
18+
.add_systems(Update, switch_scene);
19+
app.run();
20+
}
21+
22+
#[derive(Debug, Clone, Eq, PartialEq, Hash, States, Default)]
23+
enum Scene {
24+
#[default]
25+
Shapes,
26+
Bloom,
27+
Text,
28+
Sprite,
29+
}
30+
31+
fn switch_scene(
32+
keyboard: Res<ButtonInput<KeyCode>>,
33+
#[cfg(feature = "bevy_ci_testing")] mut ci_events: EventReader<CiTestingCustomEvent>,
34+
scene: Res<State<Scene>>,
35+
mut next_scene: ResMut<NextState<Scene>>,
36+
) {
37+
let mut should_switch = false;
38+
should_switch |= keyboard.just_pressed(KeyCode::Space);
39+
#[cfg(feature = "bevy_ci_testing")]
40+
{
41+
should_switch |= ci_events.read().any(|event| match event {
42+
CiTestingCustomEvent(event) => event == "switch_scene",
43+
});
44+
}
45+
if should_switch {
46+
info!("Switching scene");
47+
next_scene.set(match scene.get() {
48+
Scene::Shapes => Scene::Bloom,
49+
Scene::Bloom => Scene::Text,
50+
Scene::Text => Scene::Sprite,
51+
Scene::Sprite => Scene::Shapes,
52+
});
53+
}
54+
}
55+
56+
mod shapes {
57+
use bevy::prelude::*;
58+
59+
const X_EXTENT: f32 = 900.;
60+
61+
pub fn setup(
62+
mut commands: Commands,
63+
mut meshes: ResMut<Assets<Mesh>>,
64+
mut materials: ResMut<Assets<ColorMaterial>>,
65+
) {
66+
commands.spawn((Camera2d, StateScoped(super::Scene::Shapes)));
67+
68+
let shapes = [
69+
meshes.add(Circle::new(50.0)),
70+
meshes.add(CircularSector::new(50.0, 1.0)),
71+
meshes.add(CircularSegment::new(50.0, 1.25)),
72+
meshes.add(Ellipse::new(25.0, 50.0)),
73+
meshes.add(Annulus::new(25.0, 50.0)),
74+
meshes.add(Capsule2d::new(25.0, 50.0)),
75+
meshes.add(Rhombus::new(75.0, 100.0)),
76+
meshes.add(Rectangle::new(50.0, 100.0)),
77+
meshes.add(RegularPolygon::new(50.0, 6)),
78+
meshes.add(Triangle2d::new(
79+
Vec2::Y * 50.0,
80+
Vec2::new(-50.0, -50.0),
81+
Vec2::new(50.0, -50.0),
82+
)),
83+
];
84+
let num_shapes = shapes.len();
85+
86+
for (i, shape) in shapes.into_iter().enumerate() {
87+
// Distribute colors evenly across the rainbow.
88+
let color = Color::hsl(360. * i as f32 / num_shapes as f32, 0.95, 0.7);
89+
90+
commands.spawn((
91+
Mesh2d(shape),
92+
MeshMaterial2d(materials.add(color)),
93+
Transform::from_xyz(
94+
// Distribute shapes from -X_EXTENT/2 to +X_EXTENT/2.
95+
-X_EXTENT / 2. + i as f32 / (num_shapes - 1) as f32 * X_EXTENT,
96+
0.0,
97+
0.0,
98+
),
99+
StateScoped(super::Scene::Shapes),
100+
));
101+
}
102+
}
103+
}
104+
105+
mod bloom {
106+
use bevy::{
107+
core_pipeline::{bloom::Bloom, tonemapping::Tonemapping},
108+
prelude::*,
109+
};
110+
111+
pub fn setup(
112+
mut commands: Commands,
113+
mut meshes: ResMut<Assets<Mesh>>,
114+
mut materials: ResMut<Assets<ColorMaterial>>,
115+
) {
116+
commands.spawn((
117+
Camera2d,
118+
Camera {
119+
hdr: true,
120+
..default()
121+
},
122+
Tonemapping::TonyMcMapface,
123+
Bloom::default(),
124+
StateScoped(super::Scene::Bloom),
125+
));
126+
127+
commands.spawn((
128+
Mesh2d(meshes.add(Circle::new(100.))),
129+
MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))),
130+
Transform::from_translation(Vec3::new(-200., 0., 0.)),
131+
StateScoped(super::Scene::Bloom),
132+
));
133+
134+
commands.spawn((
135+
Mesh2d(meshes.add(RegularPolygon::new(100., 6))),
136+
MeshMaterial2d(materials.add(Color::srgb(6.25, 9.4, 9.1))),
137+
Transform::from_translation(Vec3::new(200., 0., 0.)),
138+
StateScoped(super::Scene::Bloom),
139+
));
140+
}
141+
}
142+
143+
mod text {
144+
use bevy::prelude::*;
145+
146+
pub fn setup(mut commands: Commands) {
147+
let text_font = TextFont {
148+
font_size: 50.0,
149+
..default()
150+
};
151+
let text_justification = JustifyText::Center;
152+
commands.spawn((Camera2d, StateScoped(super::Scene::Text)));
153+
commands.spawn((
154+
Text2d::new("Hello World"),
155+
text_font,
156+
TextLayout::new_with_justify(text_justification),
157+
StateScoped(super::Scene::Text),
158+
));
159+
}
160+
}
161+
162+
mod sprite {
163+
use bevy::prelude::*;
164+
165+
pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
166+
commands.spawn((Camera2d, StateScoped(super::Scene::Sprite)));
167+
commands.spawn((
168+
Sprite::from_image(asset_server.load("branding/bevy_bird_dark.png")),
169+
StateScoped(super::Scene::Sprite),
170+
));
171+
}
172+
}

0 commit comments

Comments
 (0)