mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
nilrider:: can now fly off surface
This commit is contained in:
parent
04b8287dbe
commit
448c08e925
@ -389,6 +389,8 @@ void level::init() {
|
||||
start.where = mappt(startx+.5, starty+.5, 1);
|
||||
start.t = 0;
|
||||
start.timer = 0;
|
||||
start.on_surface = this;
|
||||
start.sstime = -100;
|
||||
current = start;
|
||||
println(hlog, "start.where = ", start.where);
|
||||
println(hlog, "current.where = ", current.where, " : ", hr::format("%p", ¤t));
|
||||
|
@ -11,9 +11,16 @@ struct timestamp {
|
||||
ld heading_angle; /**< the current heading angle */
|
||||
ld vel; /**< the current velocity in units per second */
|
||||
ld circpos; /**< controls the wheel graphics */
|
||||
ld slope; /**< the current slope */
|
||||
ld slope; /**< the current slope, as angle */
|
||||
ld chg_slope; /**< slope used at surface state change */
|
||||
ld gfx_slope; /**< current slope used by graphics */
|
||||
ld t; /**< planning spline parameter */
|
||||
ld timer = 0; /**< the timer, in seconds */
|
||||
level *on_surface;/**< pointer to the sub-level if we are currently on the surface, nullptr otherwise */
|
||||
|
||||
ld sstime; /**< when did we leave or enter surface? for smoothing gfx_slope */
|
||||
hyperpoint flyvel;/**< velocity vector if we are not on any surface */
|
||||
ld circvel; /**< how fast the wheel is rotating if we are not on any surface, per second */
|
||||
|
||||
flagtype collected_triangles; /**< a bitset which shows which triangles are collected */
|
||||
flagtype goals; /**< a bitset which shows which goals are complete */
|
||||
@ -25,6 +32,7 @@ struct timestamp {
|
||||
void draw_instruments(level*);
|
||||
ld energy_in_squares();
|
||||
bool collect(level*);
|
||||
bool out_of_surface(level*);
|
||||
void be_consistent();
|
||||
};
|
||||
|
||||
|
@ -82,10 +82,16 @@ void timestamp::draw_unilcycle(const shiftmatrix& V) {
|
||||
|
||||
bool tick_debug = false;
|
||||
|
||||
bool timestamp::out_of_surface(level *lev) {
|
||||
auto xy = lev->get_xy_i(where);
|
||||
char ch = lev->mapchar(xy);
|
||||
return ch == '!';
|
||||
}
|
||||
|
||||
bool timestamp::collect(level *lev) {
|
||||
auto xy = lev->get_xy_i(where);
|
||||
char ch = lev->mapchar(xy);
|
||||
if(ch == 'r' || ch == '!') return false;
|
||||
if(ch == 'r') return false;
|
||||
if(ch == '*') {
|
||||
for(int i=0; i<isize(lev->triangles); i++) {
|
||||
auto& t = lev->triangles[i];
|
||||
@ -143,31 +149,64 @@ void timestamp::be_consistent() {
|
||||
|
||||
bool timestamp::tick(level *lev) {
|
||||
|
||||
if(!collect(lev)) return false;
|
||||
if(on_surface && !collect(lev)) return false;
|
||||
const ld eps = slope_eps;
|
||||
|
||||
hyperpoint wnext = where;
|
||||
wnext[0] += cos(heading_angle) * eps;
|
||||
wnext[1] += sin(heading_angle) * eps;
|
||||
wnext[2] = lev->surface(wnext);
|
||||
|
||||
wnext = gpushxto0(where) * wnext;
|
||||
slope = atan(wnext[2] / eps);
|
||||
|
||||
auto ovel = vel;
|
||||
|
||||
vel -= sin(slope) * gravity / tps;
|
||||
if(vel < 0) {
|
||||
vel = 0;
|
||||
if(ovel == 0) return false;
|
||||
if(on_surface) {
|
||||
hyperpoint wnext = where;
|
||||
wnext[0] += cos(heading_angle) * eps;
|
||||
wnext[1] += sin(heading_angle) * eps;
|
||||
wnext[2] = lev->surface(wnext);
|
||||
|
||||
wnext = gpushxto0(where) * wnext;
|
||||
slope = atan(wnext[2] / eps);
|
||||
|
||||
if(out_of_surface(lev)) {
|
||||
on_surface = nullptr;
|
||||
sstime = timer; chg_slope = gfx_slope;
|
||||
flyvel = wnext * vel / hypot_d(3, wnext);
|
||||
flyvel[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto mvel = (vel + ovel) / 2;
|
||||
where[0] += cos(heading_angle) * mvel * cos(slope) / tps;
|
||||
where[1] += sin(heading_angle) * mvel * cos(slope) / tps;
|
||||
where[2] = lev->surface(where);
|
||||
circpos += mvel / whrad / tps;
|
||||
|
||||
|
||||
if(on_surface) {
|
||||
auto ovel = vel;
|
||||
|
||||
vel -= sin(slope) * gravity / tps;
|
||||
if(vel < 0) {
|
||||
vel = 0;
|
||||
if(ovel == 0) return false;
|
||||
}
|
||||
|
||||
auto mvel = (vel + ovel) / 2;
|
||||
where[0] += cos(heading_angle) * mvel * cos(slope) / tps;
|
||||
where[1] += sin(heading_angle) * mvel * cos(slope) / tps;
|
||||
where[2] = lev->surface(where);
|
||||
circvel = mvel / whrad;
|
||||
}
|
||||
|
||||
else {
|
||||
auto oflyvel = flyvel;
|
||||
flyvel = rgpushxto0(where) * flyvel;
|
||||
flyvel[2] -= gravity / tps / 2;
|
||||
|
||||
// todo rewrite geodesic_step to take gravity into account into RK4 correctly
|
||||
flyvel /= tps;
|
||||
nisot::geodesic_step(where, flyvel);
|
||||
flyvel *= tps;
|
||||
|
||||
flyvel[2] -= gravity / tps / 2;
|
||||
auto mflyvel = (flyvel + oflyvel) / 2;
|
||||
heading_angle = atan2(mflyvel[1], mflyvel[0]);
|
||||
flyvel = gpushxto0(where) * flyvel;
|
||||
mflyvel = gpushxto0(where) * mflyvel;
|
||||
slope = atan(mflyvel[2] / hypot_d(2, mflyvel));
|
||||
|
||||
vel = hypot_d(3, flyvel);
|
||||
}
|
||||
|
||||
circpos += circvel / tps;
|
||||
|
||||
timer += 1. / tps;
|
||||
return true;
|
||||
}
|
||||
@ -195,7 +234,8 @@ void timestamp::centerview(level *lev) {
|
||||
|
||||
transmatrix T = View;
|
||||
|
||||
ld gfx_slope = binsearch(-90*degree, min(slope, min_gfx_slope), [&] (ld slope) {
|
||||
gfx_slope = min_gfx_slope;
|
||||
if(on_surface) gfx_slope = binsearch(-90*degree, min(slope, min_gfx_slope), [&] (ld slope) {
|
||||
View = T;
|
||||
rotate_view(cspin(1, 2, slope));
|
||||
for(int i=0; i<8; i++) {
|
||||
@ -208,7 +248,12 @@ void timestamp::centerview(level *lev) {
|
||||
}
|
||||
return false;
|
||||
}, 10);
|
||||
|
||||
|
||||
if(timer < sstime + 1) {
|
||||
ld t = timer - sstime;
|
||||
gfx_slope = lerp(chg_slope, gfx_slope, t * t * (3 - 2*t));
|
||||
}
|
||||
|
||||
View = T;
|
||||
rotate_view(cspin(1, 2, gfx_slope));
|
||||
shift_view(ztangent(whdist * lev->scale));
|
||||
|
Loading…
Reference in New Issue
Block a user