ads-game:: resources are used

This commit is contained in:
Zeno Rogue 2022-09-12 12:57:52 +02:00
parent 3578ae0631
commit cd84dfca4f
6 changed files with 101 additions and 32 deletions

View File

@ -3,9 +3,9 @@
#include "math.cpp"
#include "globals.cpp"
#include "shapes.cpp"
#include "resources.cpp"
#include "map.cpp"
#include "control.cpp"
#include "resources.cpp"
#include "display.cpp"
#include "menu.cpp"

View File

@ -5,6 +5,8 @@ namespace ads_game {
vector<string> move_names = { "acc down", "acc left", "acc up", "acc right", "fire", "pause", "display times", "switch spin", "menu" };
void fire() {
if(!pdata.ammo) return;
pdata.ammo--;
auto g = hybrid::get_where(vctr);
auto c = g.first;
if(g.second != 0) println(hlog, "WARNING: vctr not zeroed");
@ -132,15 +134,27 @@ bool ads_turn(int idelta) {
bool up = a[16+2];
bool down = a[16];
if(left) apply_lorentz(lorentz(0, 2, delta*accel)), ang = 180;
if(right) apply_lorentz(lorentz(0, 2, -delta*accel)), ang = 0;
if(up) apply_lorentz(lorentz(1, 2, delta*accel)), ang = 90;
if(down) apply_lorentz(lorentz(1, 2, -delta*accel)), ang = 270;
int clicks = (left?1:0) + (right?1:0) + (up?1:0) + (down?1:0);
if(left && right) left = right = false;
if(up && down) up = down = false;
if(left) ang = 180;
if(right) ang = 0;
if(up) ang = 90;
if(down) ang = 270;
if(left && up) ang = 135;
if(left && down) ang = 225;
if(right && up) ang = 45;
if(right && down) ang = 315;
ld mul = clicks ? 1 : 0;
if(clicks > 2) mul *= .3;
if(pdata.fuel < 0) mul = 0;
apply_lorentz(spin(ang*degree) * lorentz(0, 2, -delta*accel*mul) * spin(-ang*degree));
pdata.fuel -= delta*accel*mul;
current.T = cspin(3, 2, pt) * current.T;
optimize_shift(current);
@ -152,6 +166,11 @@ bool ads_turn(int idelta) {
ang += pt / degree;
ship_pt += pt;
pdata.oxygen -= pt;
if(pdata.oxygen < 0) {
pdata.oxygen = 0;
game_over = true;
}
}
fixmatrix_ads(current.T);

View File

@ -209,7 +209,13 @@ bool view_ads_game() {
if(true) {
poly_outline = 0xFF;
queuepolyat(shiftless(spin(ang*degree) * Id), shShip, 0x2020FFFF, PPR::LINE);
color_t shipcolor = 0x2020FFFF;
if(ship_pt < invincibility_pt) {
ld u = (invincibility_pt-ship_pt) / how_much_invincibility;
poly_outline = gradient(shipcolor, rsrc_color[rtHull], 0, 0.5 + cos(5*u*TAU), 1);
}
queuepolyat(shiftless(spin(ang*degree) * Id), shShip, shipcolor, PPR::LINE);
poly_outline = 0xFF;
if(view_proper_times) {
string str = format(tformat, ship_pt / TAU);

View File

@ -26,6 +26,9 @@ ld ang = 0;
/** ship's current proper time */
ld ship_pt;
/** until when is the ship invincible */
ld invincibility_pt;
/** is the game paused */
bool paused;
@ -45,6 +48,8 @@ vector<struct ads_object*> displayed;
color_t missile_color = 0xFF0000FF;
bool game_over;
struct player_data {
int hitpoints;
int score;
@ -53,6 +58,8 @@ struct player_data {
ld oxygen;
};
ld how_much_invincibility = TAU / 4;
player_data pdata, max_pdata, tank_pdata;
}}

View File

@ -4,13 +4,6 @@ namespace ads_game {
enum eObjType { oRock, oMissile, oParticle, oResource };
enum eResourceType { rtNone, rtHull, rtGold, rtAmmo, rtFuel, rtOxygen };
color_t rock_color[6] = { 0x703800FF, 0xC0A080FF, 0xC08010FF, 0xC04000FF, 0x408000FF, 0x8040A0FF, };
color_t rsrc_color[6] = {0, 0xC0C0C0FF, 0xFFD500FF, 0xFF0000FF, 0x00FF00FF, 0x0000FFFF };
vector<ld>* rsrc_shape[6] = { nullptr, &shape_heart, &shape_gold, &shape_weapon, &shape_fuel, &shape_airtank };
struct ads_object {
eObjType type;
eResourceType resource;
@ -172,34 +165,47 @@ void gen_resource(cell *c, shiftmatrix from, eResourceType rsrc) {
r->shape = rsrc_shape[rsrc];
r->life_end = HUGE_VAL;
r->life_start = 0;
r->resource = rsrc;
ci_at[c].rocks.emplace_back(std::move(r));
}
bool pointcrash(hyperpoint h, const vector<cross_result>& vf) {
int winding = 0;
vector<hyperpoint> kleins;
for(auto& p: vf) kleins.push_back(kleinize(p.h) - h);
auto take = [&] (hyperpoint& a, hyperpoint& b) {
if(asign(a[1], b[1]) && xcross(b[0], b[1], a[0], a[1]) < 1e-6)
winding++;
};
for(int i=1; i<isize(kleins); i++) take(kleins[i-1], kleins[i]);
take(kleins.back(), kleins[0]);
return winding & 1;
}
void crash_ship() {
if(ship_pt < invincibility_pt) return;
invincibility_pt = ship_pt + how_much_invincibility;
pdata.hitpoints--;
if(pdata.hitpoints <= 0) game_over = true;
}
void handle_crashes() {
vector<ads_object*> missiles;
vector<ads_object*> rocks;
vector<ads_object*> resources;
for(auto m: displayed) {
if(m->type == oMissile)
missiles.push_back(m);
if(m->type == oRock)
rocks.push_back(m);
if(m->type == oResource)
resources.push_back(m);
}
hybrid::in_underlying_geometry([&] {
for(auto m: missiles) {
hyperpoint h = kleinize(m->pt_main.h);
for(auto r: rocks) {
int winding = 0;
vector<hyperpoint> kleins;
for(auto& p: r->pts) kleins.push_back(kleinize(p.h) - h);
auto take = [&] (hyperpoint& a, hyperpoint& b) {
if(asign(a[1], b[1]) && xcross(b[0], b[1], a[0], a[1]) < 1e-6)
winding++;
};
for(int i=1; i<isize(kleins); i++) take(kleins[i-1], kleins[i]);
take(kleins.back(), kleins[0]);
if(winding & 1) {
println(hlog, "winding = ", winding);
println(hlog, "kleins = ", kleins);
if(pointcrash(h, r->pts)) {
m->life_end = m->pt_main.shift;
r->life_end = r->pt_main.shift;
hybrid::in_actual([&] {
@ -210,6 +216,18 @@ void handle_crashes() {
}
}
}
for(int i=0; i<isize(shape_ship); i+=2) {
hyperpoint h = kleinize(hpxyz(shape_ship[i], shape_ship[i+1], 1));
for(auto r: rocks) {
if(pointcrash(h, r->pts)) crash_ship();
}
for(auto r: resources) {
if(pointcrash(h, r->pts)) {
r->life_end = r->pt_main.shift;
gain_resource(r->resource);
}
}
}
});
}

View File

@ -2,6 +2,13 @@ namespace hr {
namespace ads_game {
enum eResourceType { rtNone, rtHull, rtGold, rtAmmo, rtFuel, rtOxygen };
color_t rock_color[6] = { 0x703800FF, 0xC0A080FF, 0xC08010FF, 0xC04000FF, 0x408000FF, 0x8040A0FF, };
color_t rsrc_color[6] = {0, 0xC0C0C0FF, 0xFFD500FF, 0xFF0000FF, 0x00FF00FF, 0x0000FFFF };
vector<ld>* rsrc_shape[6] = { nullptr, &shape_heart, &shape_gold, &shape_weapon, &shape_fuel, &shape_airtank };
void init_rsrc() {
max_pdata.hitpoints = 3;
max_pdata.score = 0;
@ -52,13 +59,15 @@ void display(int id, int y, ld val, ld maxv, ld tank, ld unit) {
curvepoint(atscreenpos(sta, top, 1) * C0);
queuecurve(sId, col, col - 128, PPR::ZERO);
ld end = sta + siz * val / maxv;
curvepoint(atscreenpos(sta, top, 1) * C0);
curvepoint(atscreenpos(end, top, 1) * C0);
curvepoint(atscreenpos(end, bot, 1) * C0);
curvepoint(atscreenpos(sta, bot, 1) * C0);
curvepoint(atscreenpos(sta, top, 1) * C0);
queuecurve(sId, col, col, PPR::ZERO);
if(val > 0) {
ld end = sta + siz * val / maxv;
curvepoint(atscreenpos(sta, top, 1) * C0);
curvepoint(atscreenpos(end, top, 1) * C0);
curvepoint(atscreenpos(end, bot, 1) * C0);
curvepoint(atscreenpos(sta, bot, 1) * C0);
curvepoint(atscreenpos(sta, top, 1) * C0);
queuecurve(sId, col, col, PPR::ZERO);
}
if(unit) for(ld u=unit; u<maxv-1e-3; u+=unit) {
ld at = sta + siz * u / maxv;
@ -95,4 +104,14 @@ void display_rsrc() {
quickqueue();
}
void gain_resource(eResourceType rsrc) {
#define D(id, field) if(rsrc == id) { pdata.field += tank_pdata.field; if(max_pdata.field && pdata.field > max_pdata.field) pdata.field = max_pdata.field; }
println(hlog, "gain resource ", int(rsrc));
D(1, hitpoints)
D(2, score)
D(3, ammo)
D(4, fuel)
D(5, oxygen)
}
}}