#[repr(C)]pub struct Color {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}Expand description
A color represented as linear RGBA floats (0.0–1.0).
All game-gem drawing functions accept this type. Internal rendering may convert to premultiplied alpha.
Fields§
§r: f32Red channel (0.0–1.0).
g: f32Green channel (0.0–1.0).
b: f32Blue channel (0.0–1.0).
a: f32Alpha channel (0.0–1.0). 0.0 = fully transparent, 1.0 = fully opaque.
Implementations§
Source§impl Color
impl Color
Sourcepub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self
Create a new color from RGBA components (0.0–1.0).
Sourcepub fn from_rgb8(r: u8, g: u8, b: u8) -> Self
pub fn from_rgb8(r: u8, g: u8, b: u8) -> Self
Create from 8-bit RGB values (0–255), fully opaque.
Sourcepub fn from_hex(hex: &str) -> Result<Self, ColorParseError>
pub fn from_hex(hex: &str) -> Result<Self, ColorParseError>
Create from a hex string like "#FF0080" or "FF008080".
- 6 digits → RGB (fully opaque)
- 8 digits → RGBA
- Optional leading
#
Examples found in repository?
examples/basics.rs (line 157)
147fn main() {
148 let example = BasicsExample {
149 ball: BouncingBall::new(),
150 hue: 0.0,
151 click_count: 0,
152 };
153
154 Game::new()
155 .window_title("game-gem: Basics Example")
156 .window_size(800, 600)
157 .clear_color(Color::from_hex("#0F0F23").unwrap())
158 .run(example);
159}More examples
examples/scene_demo.rs (line 60)
59 fn render(&mut self, ctx: &mut Context) {
60 ctx.graphics.clear(Color::from_hex("#16213E").unwrap());
61
62 // Title
63 ctx.graphics.draw_text("game-gem Scene Demo", 250.0, 150.0, 36.0, Color::GOLD);
64
65 // Menu options
66 for (i, option) in self.options.iter().enumerate() {
67 let color = if i == self.selected {
68 Color::GOLD
69 } else {
70 Color::LIGHT_GRAY
71 };
72 let prefix = if i == self.selected { "> " } else { " " };
73 ctx.graphics.draw_text(
74 &format!("{}{}", prefix, option),
75 320.0, 250.0 + i as f32 * 50.0,
76 24.0, color,
77 );
78 }
79
80 ctx.graphics.draw_text("Arrow Keys / WASD to navigate, Enter to select", 200.0, 500.0, 14.0, Color::GRAY);
81 }examples/particles.rs (line 24)
12 fn on_enter(&mut self, _ctx: &mut Context) {
13 // Fire emitter at bottom center
14 let mut fire = ParticleEmitter::new(vec2(400.0, 500.0));
15 fire.configure(|cfg| {
16 cfg
17 .rate(80.0)
18 .shape(EmitterShape::Line { x1: 370.0, y1: 500.0, x2: 430.0, y2: 500.0 })
19 .speed(80.0, 200.0)
20 .angle(std::f32::consts::PI * 1.1, std::f32::consts::PI * 1.9)
21 .size(3.0, 10.0)
22 .lifetime(0.3, 1.0)
23 .gravity(0.0, -80.0)
24 .color_start(Color::from_hex("#FF6600").unwrap())
25 .color_end(Color::from_hex("#FFFF00").unwrap())
26 .size_end(0.0)
27 .drag(1.5);
28 });
29 self.emitters.push(fire);
30
31 // Sparkle emitter
32 let mut sparkles = ParticleEmitter::new(vec2(400.0, 300.0));
33 sparkles.configure(|cfg| {
34 cfg
35 .rate(30.0)
36 .shape(EmitterShape::Circle { cx: 400.0, cy: 300.0, radius: 150.0 })
37 .speed(10.0, 50.0)
38 .angle(0.0, std::f32::consts::TAU)
39 .size(2.0, 6.0)
40 .lifetime(0.5, 1.5)
41 .gravity(0.0, 20.0)
42 .color_start(Color::from_hex("#FFFFFF").unwrap())
43 .color_end(Color::TRANSPARENT)
44 .size_end(0.0);
45 });
46 self.emitters.push(sparkles);
47 }
48
49 fn update(&mut self, ctx: &mut Context) {
50 let dt = ctx.time.delta() as f32;
51
52 // Move fire emitter to mouse X
53 self.emitters[0].position.x = ctx.input.mouse.position.x;
54 self.emitters[0].position.y = ctx.screen_height() - 50.0;
55
56 // Burst on click
57 if ctx.input.mouse.is_pressed(MouseButton::Left) {
58 self.emitters[1].position = ctx.input.mouse.position;
59 self.emitters[1].burst_now(50);
60 }
61
62 // Update all emitters
63 for emitter in &mut self.emitters {
64 emitter.update(dt);
65 }
66
67 if ctx.input.keyboard.is_pressed(KeyCode::Escape) {
68 ctx.quit();
69 }
70 }
71
72 fn render(&mut self, ctx: &mut Context) {
73 ctx.graphics.clear(Color::from_hex("#0A0A1A").unwrap());
74
75 // Draw particles
76 for emitter in &self.emitters {
77 for particle in emitter.particles() {
78 if !particle.alive {
79 continue;
80 }
81 ctx.graphics.draw_circle(
82 particle.position.x,
83 particle.position.y,
84 particle.size,
85 particle.color,
86 );
87 }
88 }
89
90 // HUD
91 ctx.graphics.draw_text(
92 &format!("Particles: {}", self.emitters.iter().map(|e| e.alive_count()).sum::<usize>()),
93 10.0, 10.0, 18.0, Color::WHITE,
94 );
95 ctx.graphics.draw_text(
96 "Move mouse = fire | Click = sparkles | Esc = quit",
97 10.0, 35.0, 14.0, Color::LIGHT_GRAY,
98 );
99 }
100}
101
102fn main() {
103 let example = ParticlesExample {
104 emitters: Vec::new(),
105 };
106
107 Game::new()
108 .window_title("game-gem: Particles Example")
109 .window_size(800, 600)
110 .clear_color(Color::from_hex("#0A0A1A").unwrap())
111 .run(example);
112}Sourcepub fn premultiplied(self) -> Self
pub fn premultiplied(self) -> Self
Convert to premultiplied alpha form.
Sourcepub fn with_alpha(self, a: f32) -> Self
pub fn with_alpha(self, a: f32) -> Self
Return the color with a new alpha.
Examples found in repository?
examples/basics.rs (line 118)
110 fn render(&mut self, ctx: &mut Context) {
111 ctx.graphics.clear(ctx.window.clear_color);
112
113 // Draw trail
114 for &(pos, alpha) in &self.ball.trail {
115 ctx.graphics.draw_circle(
116 pos.x, pos.y,
117 self.ball.radius * 0.5 * alpha,
118 self.ball.color.with_alpha(alpha * 0.5),
119 );
120 }
121
122 // Draw ball
123 ctx.graphics.draw_circle(
124 self.ball.position.x,
125 self.ball.position.y,
126 self.ball.radius,
127 self.ball.color,
128 );
129
130 // Draw HUD
131 ctx.graphics.reset_camera();
132 ctx.graphics.draw_text(
133 &format!("FPS: {:.0}", ctx.time.fps()),
134 10.0, 10.0, 18.0, Color::WHITE,
135 );
136 ctx.graphics.draw_text(
137 &format!("Clicks: {}", self.click_count),
138 10.0, 35.0, 18.0, Color::WHITE,
139 );
140 ctx.graphics.draw_text(
141 "Space = shake | Click = change color | Scroll = zoom | Esc = quit",
142 10.0, 60.0, 14.0, Color::LIGHT_GRAY,
143 );
144 }Sourcepub fn to_hsla(self) -> (f32, f32, f32, f32)
pub fn to_hsla(self) -> (f32, f32, f32, f32)
Convert to HSLA (hue: 0–360, sat/light/alpha: 0–1).
Sourcepub fn from_hsla(h: f32, s: f32, l: f32, a: f32) -> Self
pub fn from_hsla(h: f32, s: f32, l: f32, a: f32) -> Self
Create from HSLA values (hue: 0–360, sat/light/alpha: 0–1).
Examples found in repository?
examples/basics.rs (line 91)
44 fn update(&mut self, ctx: &mut Context) {
45 let dt = ctx.time.delta() as f32;
46
47 // --- Ball physics ---
48 self.ball.velocity.y += 600.0 * dt; // Gravity
49 self.ball.position += self.ball.velocity * dt;
50
51 // Bounce off walls
52 let w = ctx.screen_width();
53 let h = ctx.screen_height();
54
55 if self.ball.position.x - self.ball.radius < 0.0 {
56 self.ball.position.x = self.ball.radius;
57 self.ball.velocity.x = self.ball.velocity.x.abs();
58 }
59 if self.ball.position.x + self.ball.radius > w {
60 self.ball.position.x = w - self.ball.radius;
61 self.ball.velocity.x = -self.ball.velocity.x.abs();
62 }
63 if self.ball.position.y - self.ball.radius < 0.0 {
64 self.ball.position.y = self.ball.radius;
65 self.ball.velocity.y = self.ball.velocity.y.abs();
66 }
67 if self.ball.position.y + self.ball.radius > h {
68 self.ball.position.y = h - self.ball.radius;
69 self.ball.velocity.y = -self.ball.velocity.y.abs() * 0.95; // Damping
70 }
71
72 // Update trail
73 self.ball.trail.push((self.ball.position, 1.0));
74 if self.ball.trail.len() > 60 {
75 self.ball.trail.remove(0);
76 }
77 for (_, alpha) in &mut self.ball.trail {
78 *alpha -= dt * 2.0;
79 }
80 self.ball.trail.retain(|(_, a)| *a > 0.0);
81
82 // --- Input ---
83 if ctx.input.is_action_pressed("shake") {
84 ctx.graphics.camera.shake(10.0, 0.3);
85 }
86
87 if ctx.input.mouse.is_pressed(MouseButton::Left) {
88 self.click_count += 1;
89 // Change ball color
90 self.hue = (self.hue + 30.0) % 360.0;
91 self.ball.color = Color::from_hsla(self.hue, 0.8, 0.6, 1.0);
92 // Boost ball toward click
93 let dir = ctx.input.mouse.position - self.ball.position;
94 self.ball.velocity += dir.normalize_or_zero() * 200.0;
95 }
96
97 // Zoom with scroll
98 let zoom = ctx.graphics.camera.zoom + ctx.input.mouse.scroll.y * 0.1;
99 ctx.graphics.camera.set_zoom(zoom);
100
101 // Escape to quit
102 if ctx.input.keyboard.is_pressed(KeyCode::Escape) {
103 ctx.quit();
104 }
105
106 // Update camera follow target
107 ctx.graphics.camera.follow(self.ball.position, 0.05);
108 }Source§impl Color
impl Color
pub const WHITE: Color
pub const BLACK: Color
pub const RED: Color
pub const GREEN: Color
pub const BLUE: Color
pub const YELLOW: Color
pub const CYAN: Color
pub const MAGENTA: Color
pub const ORANGE: Color
pub const GRAY: Color
pub const LIGHT_GRAY: Color
pub const DARK_GRAY: Color
pub const TRANSPARENT: Color
pub const SKY_BLUE: Color
pub const GOLD: Color
pub const CORAL: Color
pub const SALMON: Color
pub const LIME: Color
pub const PURPLE: Color
pub const PINK: Color
pub const TEAL: Color
pub const NAVY: Color
pub const MAROON: Color
pub const OLIVE: Color
pub const AQUA: Color
pub const INDIGO: Color
pub const VIOLET: Color
pub const CRIMSON: Color
pub const TURQUOISE: Color
Trait Implementations§
impl Copy for Color
impl Pod for Color
impl StructuralPartialEq for Color
Auto Trait Implementations§
impl Freeze for Color
impl RefUnwindSafe for Color
impl Send for Color
impl Sync for Color
impl Unpin for Color
impl UnsafeUnpin for Color
impl UnwindSafe for Color
Blanket Implementations§
impl<T> AnyBitPattern for Twhere
T: Pod,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
Source§type Bits = T
type Bits = T
Self must have the same layout as the specified Bits except for
the possible invalid bit patterns being checked during
is_valid_bit_pattern.Source§fn is_valid_bit_pattern(_bits: &T) -> bool
fn is_valid_bit_pattern(_bits: &T) -> bool
If this function returns true, then it must be valid to reinterpret
bits
as &Self.