diff --git a/src/system.rs b/src/system.rs index fdae5fb..1a473a9 100644 --- a/src/system.rs +++ b/src/system.rs @@ -52,7 +52,7 @@ impl StarField { q.x as i16, q.y as i16, (5.0 - (1.0 * wp.par)) as i16, - Color::RGBA(255, 255, 255, 100), + Color::RGB(100, 100, 100), )?; } return Ok(()); @@ -64,35 +64,38 @@ impl StarField { let ww = w / 2.0; let hh = h / 2.0; + // Camera position relative to the center of this field. let pos_in_field = Cartesian::new( dc.camera.pos.x.signum() * (((dc.camera.pos.x.abs() + ww) % w) - ww), dc.camera.pos.y.signum() * (((dc.camera.pos.y.abs() + hh) % h) - hh), ); - // Field center in world coordinates + // Center of this field, in world coordinates let field_center = dc.camera.pos - pos_in_field; - // screen coordinates of top left position of starfield - let field_tl = - WorldPosition::new(field_center + Cartesian::new(-ww, hh), 3.0).screen_position(dc); + // Compute tile bounds. + // We use neighboring tiles' corners instead of this tile's corner to properly account for parallax. + // If we use the current tiles corners, we'll see stars appear when a tile is drawn--parallax moves them + // into view. The bounds below guarantee that no *other* tiles' stars will be drawn inside. + // + // bound_nw is the screen position of the bottom-right corner of north-west tile + // bound_se is the screen position of the top-right corner of south-east tile + let bound_nw = + WorldPosition::new(field_center + Cartesian::new(-ww, hh), 4.0).screen_position(dc); + let bound_se = + WorldPosition::new(field_center + Cartesian::new(ww, -hh), 4.0).screen_position(dc); - let field_br = - WorldPosition::new(field_center + Cartesian::new(ww, -hh), 3.0).screen_position(dc); - - dc.canvas.aa_circle( - field_tl.x as i16, - field_tl.y as i16, - 5, - Color::RGB(255, 0, 0), - )?; - dc.canvas.set_draw_color(Color::RGB(0, 0, 0)); - - let north = field_tl.y > 0.0; - let south = field_br.y < dc.window_size.y; - let east = field_br.x < dc.window_size.x; - let west = field_tl.x > 0.0; + // Naturally, we show tiles only if we can see their edges. + let north = bound_nw.y > 0.0; + let south = bound_se.y < dc.window_size.y; + let east = bound_se.x < dc.window_size.x; + let west = bound_nw.x > 0.0; + // Draw center tile self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, 0.0))?; + + // Draw surrounding tiles + // (which are just offset clones of the main one) if north { self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, h))?; } @@ -118,6 +121,7 @@ impl StarField { self.draw_with_offset(dc, pos_in_field, Cartesian::new(-w, -h))?; } + // draw_circle doesn't clean up the color it uses, so we do that here. dc.canvas.set_draw_color(Color::RGB(0, 0, 0)); return Ok(()); }