1
1
use bevy:: {
2
- app:: AppExit ,
3
2
diagnostic:: { FrameTimeDiagnosticsPlugin , LogDiagnosticsPlugin } ,
4
3
prelude:: * ,
5
- window:: WindowResizeConstraints ,
4
+ window:: { WindowResizeConstraints , WindowResolution } ,
6
5
} ;
7
6
use bevy_pixels:: prelude:: * ;
8
7
use rand:: prelude:: * ;
9
8
10
- const WIDTH : u32 = 320 ;
11
- const HEIGHT : u32 = 240 ;
9
+ const INITIAL_WIDTH : u32 = 320 ;
10
+ const INITIAL_HEIGHT : u32 = 240 ;
11
+ const SCALE_FACTOR : f32 = 2.0 ;
12
12
13
13
#[ derive( Bundle , Debug ) ]
14
14
struct ObjectBundle {
@@ -42,36 +42,44 @@ struct Color(u8, u8, u8, u8);
42
42
fn main ( ) {
43
43
App :: new ( )
44
44
. add_plugins ( DefaultPlugins . set ( WindowPlugin {
45
- window : WindowDescriptor {
45
+ primary_window : Some ( Window {
46
46
title : "Hello Bevy Pixels" . to_string ( ) ,
47
- width : WIDTH as f32 ,
48
- height : HEIGHT as f32 ,
47
+ resolution : WindowResolution :: new (
48
+ INITIAL_WIDTH as f32 * SCALE_FACTOR ,
49
+ INITIAL_HEIGHT as f32 * SCALE_FACTOR ,
50
+ ) ,
49
51
resize_constraints : WindowResizeConstraints {
50
- min_width : WIDTH as f32 ,
51
- min_height : HEIGHT as f32 ,
52
+ min_width : INITIAL_WIDTH as f32 * SCALE_FACTOR ,
53
+ min_height : INITIAL_HEIGHT as f32 * SCALE_FACTOR ,
52
54
..default ( )
53
55
} ,
54
56
fit_canvas_to_parent : true ,
55
57
..default ( )
56
- } ,
58
+ } ) ,
57
59
..default ( )
58
60
} ) )
59
61
. add_plugin ( PixelsPlugin {
60
- width : WIDTH ,
61
- height : HEIGHT ,
62
- ..default ( )
62
+ primary_window : Some ( PixelsOptions {
63
+ width : INITIAL_WIDTH ,
64
+ height : INITIAL_HEIGHT ,
65
+ scale_factor : SCALE_FACTOR ,
66
+ ..default ( )
67
+ } ) ,
63
68
} )
64
69
. add_plugin ( FrameTimeDiagnosticsPlugin :: default ( ) )
65
70
. add_plugin ( LogDiagnosticsPlugin :: default ( ) )
66
71
. add_startup_system ( setup)
67
- . add_system ( bounce)
68
- . add_system ( movement. after ( bounce) )
69
- . add_system ( exit_on_escape)
70
- . add_system_to_stage ( PixelsStage :: Draw , draw_background)
71
- . add_system_to_stage ( PixelsStage :: Draw , draw_objects. after ( draw_background) )
72
+ . add_system ( bevy:: window:: close_on_esc)
73
+ . add_systems ( ( bounce, movement) . chain ( ) . in_set ( PixelsSet :: Update ) )
74
+ . add_systems (
75
+ ( draw_background, draw_objects)
76
+ . chain ( )
77
+ . in_set ( PixelsSet :: Draw ) ,
78
+ )
72
79
. run ( ) ;
73
80
}
74
81
82
+ /// Spawn object.
75
83
fn setup ( mut commands : Commands ) {
76
84
let box_object = ObjectBundle {
77
85
position : Position { x : 24 , y : 16 } ,
@@ -85,14 +93,28 @@ fn setup(mut commands: Commands) {
85
93
commands. spawn ( box_object) ;
86
94
}
87
95
88
- fn bounce ( mut query : Query < ( & Position , & mut Velocity , & Size , & mut Color ) > ) {
89
- for ( position, mut velocity, size, mut color) in query. iter_mut ( ) {
96
+ /// Bounce object off edges of buffer.
97
+ fn bounce (
98
+ options_query : Query < & PixelsOptions > ,
99
+ mut query : Query < ( & Position , & mut Velocity , & Size , & mut Color ) > ,
100
+ ) {
101
+ let Ok ( options) = options_query. get_single ( ) else { return } ;
102
+
103
+ for ( position, mut velocity, size, mut color) in & mut query {
90
104
let mut bounce = false ;
91
- if position. x == 0 || position. x + size. width > WIDTH {
105
+ if position. x == 0 && velocity. x < 0 {
106
+ velocity. x *= -1 ;
107
+ bounce = true ;
108
+ }
109
+ if position. x + size. width == options. width && velocity. x > 0 {
92
110
velocity. x *= -1 ;
93
111
bounce = true ;
94
112
}
95
- if position. y == 0 || position. y + size. height > HEIGHT {
113
+ if position. y == 0 && velocity. y < 0 {
114
+ velocity. y *= -1 ;
115
+ bounce = true ;
116
+ }
117
+ if position. y + size. height == options. height && velocity. y > 0 {
96
118
velocity. y *= -1 ;
97
119
bounce = true ;
98
120
}
@@ -104,37 +126,43 @@ fn bounce(mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>) {
104
126
}
105
127
}
106
128
107
- fn movement ( mut query : Query < ( & mut Position , & Velocity ) > ) {
108
- for ( mut position , velocity ) in query . iter_mut ( ) {
109
- position . x = ( position . x as i16 + velocity . x ) as u32 ;
110
- position . y = ( position . y as i16 + velocity . y ) as u32 ;
111
- }
112
- }
129
+ /// Move object based on current velocity.
130
+ fn movement (
131
+ options_query : Query < & PixelsOptions > ,
132
+ mut query : Query < ( & mut Position , & Velocity , & Size ) > ,
133
+ ) {
134
+ let Ok ( options ) = options_query . get_single ( ) else { return } ;
113
135
114
- fn exit_on_escape ( keyboard_input : Res < Input < KeyCode > > , mut app_exit_events : EventWriter < AppExit > ) {
115
- if keyboard_input. just_pressed ( KeyCode :: Escape ) {
116
- app_exit_events. send ( AppExit ) ;
136
+ for ( mut position, velocity, size) in & mut query {
137
+ position. x = ( ( position. x as i16 + velocity. x ) as u32 ) . clamp ( 0 , options. width - size. width ) ;
138
+ position. y =
139
+ ( ( position. y as i16 + velocity. y ) as u32 ) . clamp ( 0 , options. height - size. height ) ;
117
140
}
118
141
}
119
142
120
- fn draw_background ( mut pixels_resource : ResMut < PixelsResource > ) {
121
- let frame = pixels_resource. pixels . frame_mut ( ) ;
143
+ /// Draw solid background to buffer.
144
+ fn draw_background ( mut wrapper_query : Query < & mut PixelsWrapper > ) {
145
+ let Ok ( mut wrapper) = wrapper_query. get_single_mut ( ) else { return } ;
146
+ let frame = wrapper. pixels . frame_mut ( ) ;
147
+
122
148
frame. copy_from_slice ( & [ 0x48 , 0xb2 , 0xe8 , 0xff ] . repeat ( frame. len ( ) / 4 ) ) ;
123
149
}
124
150
151
+ /// Draw objects to buffer.
125
152
fn draw_objects (
126
- mut pixels_resource : ResMut < PixelsResource > ,
153
+ mut wrapper_query : Query < ( & mut PixelsWrapper , & PixelsOptions ) > ,
127
154
query : Query < ( & Position , & Size , & Color ) > ,
128
155
) {
129
- let frame = pixels_resource. pixels . frame_mut ( ) ;
130
- let frame_width_bytes = ( WIDTH * 4 ) as usize ;
156
+ let Ok ( ( mut wrapper, options) ) = wrapper_query. get_single_mut ( ) else { return } ;
157
+ let frame = wrapper. pixels . frame_mut ( ) ;
158
+ let frame_width_bytes = ( options. width * 4 ) as usize ;
131
159
132
- for ( position, size, color) in query. iter ( ) {
160
+ for ( position, size, color) in & query {
133
161
let x_offset = ( position. x * 4 ) as usize ;
134
162
let width_bytes = ( size. width * 4 ) as usize ;
135
163
let object_row = & [ color. 0 , color. 1 , color. 2 , color. 3 ] . repeat ( size. width as usize ) ;
136
164
137
- for y in position. y ..( position. y + size. height - 1 ) {
165
+ for y in position. y ..( position. y + size. height ) {
138
166
let y_offset = y as usize * frame_width_bytes;
139
167
let i = y_offset + x_offset;
140
168
let j = i + width_bytes;
0 commit comments