mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2026-04-15 06:21:23 +00:00
ru:: ellipse platforms
This commit is contained in:
@@ -484,6 +484,16 @@ struct pendulum_platform : public moving_platform {
|
||||
string get_help() override { return "These pendulum platforms go back and forth between two locations, taking the shortest path possible."; }
|
||||
};
|
||||
|
||||
struct ellipse_platform : public moving_platform {
|
||||
xy a, b;
|
||||
ld ratio, period, shift;
|
||||
vector<hyperpoint> points;
|
||||
vector<ld> lengthsum;
|
||||
xy location_at(ld t) override;
|
||||
string get_name() override { return "ellipse platform"; }
|
||||
string get_help() override { return "These platforms go in an ellipse."; }
|
||||
};
|
||||
|
||||
struct rope_platform : public moving_platform {
|
||||
ld period, shift, dist, max_swing;
|
||||
xy location_at(ld t) override;
|
||||
|
||||
@@ -623,6 +623,36 @@ xy pendulum_platform::location_at(ld t) {
|
||||
return from_hyper(rgpushxto0(h1) * rspintox(gpushxto0(h1) * h2) * xpush0(x));
|
||||
}
|
||||
|
||||
xy ellipse_platform::location_at(ld t) {
|
||||
if(points.empty()) {
|
||||
auto h1 = to_hyper(a);
|
||||
auto h2 = to_hyper(b);
|
||||
auto m = mid(h1, h2);
|
||||
ld wanted = hdist(h1, h2) * ratio;
|
||||
for(int it=0; it<360; it++) {
|
||||
auto p = [&] (ld x) { return rgpushxto0(m) * spin(it*1._deg) * xpush0(x); };
|
||||
ld x = binsearch(0, 5, [&] (ld x) { auto px = p(x); return hdist(h1, px) + hdist(h2, px) >= wanted; });
|
||||
points.push_back(p(x));
|
||||
}
|
||||
int N = isize(points);
|
||||
points.push_back(points[0]);
|
||||
ld ls = 0;
|
||||
for(int i=0; i<N; i++) {
|
||||
lengthsum.push_back(ls);
|
||||
ls += hdist(points[i], points[i+1]);
|
||||
}
|
||||
lengthsum.push_back(ls);
|
||||
}
|
||||
ld our_t = t / (period * game_fps);
|
||||
our_t -= floor(our_t);
|
||||
our_t *= lengthsum.back();
|
||||
auto it = lower_bound(lengthsum.begin(), lengthsum.end(), our_t);
|
||||
auto index = it - lengthsum.begin();
|
||||
auto& h1 = points[index-1];
|
||||
auto& h2 = points[index];
|
||||
return from_hyper(rgpushxto0(h1) * rspintox(gpushxto0(h1) * h2) * xpush0(our_t - lengthsum[index-1]));
|
||||
}
|
||||
|
||||
void moving_platform::draw() {
|
||||
double d = get_scale();
|
||||
auto wi = width();
|
||||
|
||||
@@ -321,6 +321,11 @@ void load_room(fhstream& f, cell *c) {
|
||||
b->a = get_xy(); b->b = get_xy(); b->period = get_ld(); b->shift = get_ld();
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else if(cap == "ELLIPSE") {
|
||||
auto b = std::make_unique<ellipse_platform>();
|
||||
b->a = get_xy(); b->b = get_xy(); b->period = get_ld(); b->shift = get_ld(); b->ratio = get_ld();
|
||||
r.entities.emplace_back(std::move(b));
|
||||
}
|
||||
else if(cap == "HINT") {
|
||||
auto b = std::make_unique<hint>();
|
||||
b->respawn = get_xy(); b->size = get_xy();
|
||||
|
||||
Reference in New Issue
Block a user