Fixed starfield tiling
parent
53927a9944
commit
bf60fda4f2
|
@ -52,7 +52,7 @@ impl StarField {
|
||||||
q.x as i16,
|
q.x as i16,
|
||||||
q.y as i16,
|
q.y as i16,
|
||||||
(5.0 - (1.0 * wp.par)) as i16,
|
(5.0 - (1.0 * wp.par)) as i16,
|
||||||
Color::RGBA(255, 255, 255, 100),
|
Color::RGB(100, 100, 100),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -64,35 +64,38 @@ impl StarField {
|
||||||
let ww = w / 2.0;
|
let ww = w / 2.0;
|
||||||
let hh = h / 2.0;
|
let hh = h / 2.0;
|
||||||
|
|
||||||
|
// Camera position relative to the center of this field.
|
||||||
let pos_in_field = Cartesian::new(
|
let pos_in_field = Cartesian::new(
|
||||||
dc.camera.pos.x.signum() * (((dc.camera.pos.x.abs() + ww) % w) - ww),
|
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),
|
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;
|
let field_center = dc.camera.pos - pos_in_field;
|
||||||
|
|
||||||
// screen coordinates of top left position of starfield
|
// Compute tile bounds.
|
||||||
let field_tl =
|
// We use neighboring tiles' corners instead of this tile's corner to properly account for parallax.
|
||||||
WorldPosition::new(field_center + Cartesian::new(-ww, hh), 3.0).screen_position(dc);
|
// 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 =
|
// Naturally, we show tiles only if we can see their edges.
|
||||||
WorldPosition::new(field_center + Cartesian::new(ww, -hh), 3.0).screen_position(dc);
|
let north = bound_nw.y > 0.0;
|
||||||
|
let south = bound_se.y < dc.window_size.y;
|
||||||
dc.canvas.aa_circle(
|
let east = bound_se.x < dc.window_size.x;
|
||||||
field_tl.x as i16,
|
let west = bound_nw.x > 0.0;
|
||||||
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;
|
|
||||||
|
|
||||||
|
// Draw center tile
|
||||||
self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, 0.0))?;
|
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 {
|
if north {
|
||||||
self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, h))?;
|
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))?;
|
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));
|
dc.canvas.set_draw_color(Color::RGB(0, 0, 0));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue