App 2.38.0: Overview styles Visor and Empire
Visor, after Halo's helmet display: the battery as the shield bar, the range as the ammunition counter, P R N D as grenade slots, the speed in the reticle with power round it, and the power trail as blips on a motion tracker that sweeps while moving. Original blue or the accent. Empire, after Age of Empires: a wooden resource bar, an isometric world that moves with the speed, the car as the selected unit, P R N D as commands, a diamond minimap, and ages by odometer (EmpireAge, tested). The app takes the player's blue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
@@ -0,0 +1,454 @@
|
||||
package com.evsuite.abrp;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The Empire Overview style, after the interface of a real-time strategy game like Age of
|
||||
* Empires: a wooden resource bar on top, an isometric world in the middle and a carved panel
|
||||
* at the bottom with the commands, the selected unit and a diamond-shaped minimap.
|
||||
*
|
||||
* The resource bar holds the battery, the range, the power and the usage over 5 minutes, the
|
||||
* age (by odometer, {@link EmpireAge}) and the clock. In the world the car is the selected unit
|
||||
* on a road, with the battery as its health bar; the ground moves past with the speed, which
|
||||
* stands large over the world. Below 20 % a warning blinks there. At the bottom: P R N D as
|
||||
* command buttons, the unit's portrait and stats (trip, usage since start, climate), and the
|
||||
* minimap with the odometer and the way to the next age. Unread values show "—" and fill
|
||||
* nothing; the world stands still when the speed is unread.
|
||||
*
|
||||
* The world animates (about 30 frames a second) only while the car moves and the view is on
|
||||
* screen.
|
||||
*/
|
||||
final class EmpireView extends ClusterCanvasView {
|
||||
|
||||
private static final int WOOD = 0xFF3B2414, WOOD_LIGHT = 0xFF5A3A1E, WOOD_DARK = 0xFF24150B,
|
||||
TRIM = 0xFFC8A05A, PARCHMENT = 0xFFF2E2B8, TEAM = 0xFF3D6BFF, HEALTH = 0xFF3CC23C,
|
||||
RED = 0xFFE03A2A, GRASS = 0xFF4E7A2E, GRASS_ALT = 0xFF557F33, ROAD = 0xFF8A6A3C, REGEN = 0xFF6FE07A;
|
||||
/** Metres per tile, as the ground moves past. */
|
||||
private static final float TILE_M = 6f;
|
||||
|
||||
private final Paint line = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint fill = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint text = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Path path = new Path();
|
||||
private final RectF r = new RectF();
|
||||
private final Typeface serif = Typeface.create(Typeface.SERIF, Typeface.BOLD);
|
||||
private final Typeface sans = Typeface.create("sans-serif-condensed", Typeface.BOLD);
|
||||
|
||||
/** Tiles travelled: the whole part picks the trees, the fraction moves the ground. */
|
||||
private double travelled;
|
||||
private long lastFrame;
|
||||
|
||||
EmpireView(Context context) {
|
||||
super(context);
|
||||
line.setStyle(Paint.Style.STROKE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas c) {
|
||||
super.onDraw(c);
|
||||
float w = getWidth(), h = getHeight();
|
||||
if (w <= 0 || h <= 0) return;
|
||||
float u = Math.min(h / 640f, w / 1100f);
|
||||
boolean moving = v.speedKmh != null && v.speedKmh > 0.5f;
|
||||
advance(moving);
|
||||
float top = 46f * u, bottom = h - 186f * u;
|
||||
drawWorld(c, w, top, bottom, u);
|
||||
drawSpeed(c, w, top, u);
|
||||
drawResources(c, w, top, u);
|
||||
drawPanel(c, w, h, bottom, u);
|
||||
keepAnimating(moving, 33);
|
||||
}
|
||||
|
||||
private void advance(boolean moving) {
|
||||
long now = SystemClock.uptimeMillis();
|
||||
float dt = lastFrame == 0 ? 0f : Math.min(0.2f, (now - lastFrame) / 1000f);
|
||||
lastFrame = now;
|
||||
if (moving) travelled = (travelled + v.speedKmh / 3.6f * dt / TILE_M) % 1_000_000d;
|
||||
}
|
||||
|
||||
// ---------- Shared ----------
|
||||
|
||||
private void say(Canvas c, String s, float x, float y, float size, int colour, Typeface face, Paint.Align a, float u) {
|
||||
text.setTypeface(face);
|
||||
text.setTextSize(size);
|
||||
text.setTextAlign(a);
|
||||
text.setColor(0xCC000000);
|
||||
c.drawText(s, x + Math.max(1f, size * 0.05f), y + Math.max(1f, size * 0.05f), text);
|
||||
text.setColor(colour);
|
||||
c.drawText(s, x, y, text);
|
||||
}
|
||||
|
||||
/** Wood with planks and a gold trim. */
|
||||
private void wood(Canvas c, float l, float t, float rr, float b, float u) {
|
||||
fill.setColor(WOOD);
|
||||
c.drawRect(l, t, rr, b, fill);
|
||||
line.setColor(WOOD_DARK);
|
||||
line.setStrokeWidth(2f * u);
|
||||
for (float y = t + 22f * u; y < b; y += 22f * u) c.drawLine(l, y, rr, y, line);
|
||||
line.setColor(WOOD_LIGHT);
|
||||
line.setStrokeWidth(1f * u);
|
||||
for (float y = t + 23.5f * u; y < b; y += 22f * u) c.drawLine(l, y, rr, y, line);
|
||||
}
|
||||
|
||||
/** A recessed frame with a gold edge. */
|
||||
private void inset(Canvas c, float l, float t, float rr, float b, int bg, float u) {
|
||||
r.set(l, t, rr, b);
|
||||
fill.setColor(bg);
|
||||
c.drawRect(r, fill);
|
||||
line.setColor(WOOD_DARK);
|
||||
line.setStrokeWidth(4f * u);
|
||||
c.drawRect(r, line);
|
||||
line.setColor(TRIM);
|
||||
line.setStrokeWidth(1.5f * u);
|
||||
c.drawRect(r, line);
|
||||
}
|
||||
|
||||
private void bar(Canvas c, float l, float t, float rr, float b, float frac, int colour, float u) {
|
||||
fill.setColor(0xFF140C06);
|
||||
c.drawRect(l, t, rr, b, fill);
|
||||
if (frac > 0f) {
|
||||
fill.setColor(colour);
|
||||
c.drawRect(l, t, l + (rr - l) * Math.min(1f, frac), b, fill);
|
||||
}
|
||||
line.setColor(0xFF000000);
|
||||
line.setStrokeWidth(1.5f * u);
|
||||
c.drawRect(l, t, rr, b, line);
|
||||
}
|
||||
|
||||
// ---------- World ----------
|
||||
|
||||
/** Isometric grass with a road through the middle; the car sits on it, the ground moves. */
|
||||
private void drawWorld(Canvas c, float w, float top, float bottom, float u) {
|
||||
c.save();
|
||||
c.clipRect(0, top, w, bottom);
|
||||
float tw = 112f * u, th = 56f * u;
|
||||
float ox = w * 0.36f, oy = top + (bottom - top) * 0.62f;
|
||||
long whole = (long) Math.floor(travelled);
|
||||
float phase = (float) (travelled - whole);
|
||||
// Moving forward along the road (up and to the right) moves the ground down and left.
|
||||
float sx = -phase * tw / 2f, sy = phase * th / 2f;
|
||||
int n = (int) Math.ceil((w / tw + (bottom - top) / th)) + 2;
|
||||
for (int i = -n; i <= n; i++) {
|
||||
for (int j = -n; j <= n; j++) {
|
||||
float cx = ox + (i + j) * tw / 2f + sx, cy = oy + (i - j) * th / 2f + sy;
|
||||
if (cx < -tw || cx > w + tw || cy < top - th || cy > bottom + th) continue;
|
||||
long cell = j + whole;
|
||||
boolean road = i == 0;
|
||||
int colour = road ? ROAD : (hash(i, cell) % 3 == 0 ? GRASS_ALT : GRASS);
|
||||
diamond(c, cx, cy, tw / 2f, th / 2f, colour);
|
||||
if (road && (cell & 1) == 0) {
|
||||
// Wheel ruts.
|
||||
line.setColor(0x40000000);
|
||||
line.setStrokeWidth(2f * u);
|
||||
c.drawLine(cx - tw * 0.18f, cy + th * 0.02f, cx + tw * 0.08f, cy - th * 0.11f, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trees, drawn back to front so the nearer ones overlap.
|
||||
for (int i = n; i >= -n; i--) {
|
||||
for (int j = -n; j <= n; j++) {
|
||||
if (Math.abs(i) < 2) continue;
|
||||
long cell = j + whole;
|
||||
if (hash(i, cell) % 7 != 0) continue;
|
||||
float cx = ox + (i + j) * tw / 2f + sx, cy = oy + (i - j) * th / 2f + sy;
|
||||
if (cx < -tw || cx > w + tw || cy < top - th || cy > bottom + 2 * th) continue;
|
||||
tree(c, cx, cy, u);
|
||||
}
|
||||
}
|
||||
drawUnit(c, ox, oy, u);
|
||||
c.restore();
|
||||
}
|
||||
|
||||
private static int hash(long i, long j) {
|
||||
long x = i * 73_856_093L ^ j * 19_349_663L;
|
||||
x ^= x >>> 13;
|
||||
x *= 0x5bd1e995L;
|
||||
x ^= x >>> 15;
|
||||
return (int) ((x & 0x7fffffffL) % 1_000_003L);
|
||||
}
|
||||
|
||||
private void diamond(Canvas c, float cx, float cy, float hw, float hh, int colour) {
|
||||
path.reset();
|
||||
path.moveTo(cx, cy - hh);
|
||||
path.lineTo(cx + hw, cy);
|
||||
path.lineTo(cx, cy + hh);
|
||||
path.lineTo(cx - hw, cy);
|
||||
path.close();
|
||||
fill.setColor(colour);
|
||||
c.drawPath(path, fill);
|
||||
line.setColor(0x18000000);
|
||||
line.setStrokeWidth(1f);
|
||||
c.drawPath(path, line);
|
||||
}
|
||||
|
||||
private void tree(Canvas c, float x, float y, float u) {
|
||||
fill.setColor(0x40000000);
|
||||
c.drawOval(x - 20f * u, y - 6f * u, x + 20f * u, y + 6f * u, fill);
|
||||
fill.setColor(0xFF5A3A1E);
|
||||
c.drawRect(x - 3f * u, y - 14f * u, x + 3f * u, y, fill);
|
||||
for (int k = 0; k < 3; k++) {
|
||||
float base = y - 10f * u - k * 16f * u, half = (22f - k * 5f) * u;
|
||||
path.reset();
|
||||
path.moveTo(x - half, base);
|
||||
path.lineTo(x, base - 28f * u);
|
||||
path.lineTo(x + half, base);
|
||||
path.close();
|
||||
fill.setColor(k == 1 ? 0xFF2F5A23 : 0xFF274D1D);
|
||||
c.drawPath(path, fill);
|
||||
}
|
||||
}
|
||||
|
||||
/** The car as the selected unit: a selection ring, the car along the road, its health bar. */
|
||||
private void drawUnit(Canvas c, float x, float y, float u) {
|
||||
line.setColor(0xFFFFFFFF);
|
||||
line.setStrokeWidth(2f * u);
|
||||
c.drawOval(x - 62f * u, y - 24f * u, x + 62f * u, y + 24f * u, line);
|
||||
c.save();
|
||||
c.translate(x, y - 6f * u);
|
||||
c.rotate(-26.565f);
|
||||
carProfile(c, 0f, 0f, 54f * u, TEAM);
|
||||
c.restore();
|
||||
float frac = v.socPercent == null ? 0f : v.socPercent / 100f;
|
||||
boolean low = v.socPercent != null && v.socPercent < 20f;
|
||||
bar(c, x - 40f * u, y - 92f * u, x + 40f * u, y - 84f * u, frac, low ? RED : HEALTH, u);
|
||||
}
|
||||
|
||||
/** A car in profile, facing right, in the player's colour. */
|
||||
private void carProfile(Canvas c, float cx, float cy, float s, int colour) {
|
||||
path.reset();
|
||||
path.moveTo(cx - s, cy + s * 0.15f);
|
||||
path.lineTo(cx - s * 0.92f, cy - s * 0.15f);
|
||||
path.quadTo(cx - s * 0.55f, cy - s * 0.22f, cx - s * 0.32f, cy - s * 0.5f);
|
||||
path.lineTo(cx + s * 0.28f, cy - s * 0.52f);
|
||||
path.quadTo(cx + s * 0.6f, cy - s * 0.24f, cx + s * 0.95f, cy - s * 0.12f);
|
||||
path.lineTo(cx + s, cy + s * 0.15f);
|
||||
path.close();
|
||||
fill.setColor(colour);
|
||||
c.drawPath(path, fill);
|
||||
line.setColor(0xFF0A1440);
|
||||
line.setStrokeWidth(s * 0.04f);
|
||||
c.drawPath(path, line);
|
||||
// Windows.
|
||||
path.reset();
|
||||
path.moveTo(cx - s * 0.26f, cy - s * 0.42f);
|
||||
path.lineTo(cx + s * 0.24f, cy - s * 0.43f);
|
||||
path.lineTo(cx + s * 0.44f, cy - s * 0.2f);
|
||||
path.lineTo(cx - s * 0.45f, cy - s * 0.2f);
|
||||
path.close();
|
||||
fill.setColor(0xFFBFD8FF);
|
||||
c.drawPath(path, fill);
|
||||
fill.setColor(0xFF15100A);
|
||||
c.drawCircle(cx - s * 0.55f, cy + s * 0.17f, s * 0.21f, fill);
|
||||
c.drawCircle(cx + s * 0.55f, cy + s * 0.17f, s * 0.21f, fill);
|
||||
fill.setColor(0xFFB0B0B0);
|
||||
c.drawCircle(cx - s * 0.55f, cy + s * 0.17f, s * 0.1f, fill);
|
||||
c.drawCircle(cx + s * 0.55f, cy + s * 0.17f, s * 0.1f, fill);
|
||||
}
|
||||
|
||||
// ---------- Speed ----------
|
||||
|
||||
private void drawSpeed(Canvas c, float w, float top, float u) {
|
||||
float x = w * 0.66f;
|
||||
say(c, fmt(v.speedKmh, "%.0f", "—"), x, top + 150f * u, 130f * u, PARCHMENT, serif, Paint.Align.CENTER, u);
|
||||
say(c, "km/h", x, top + 184f * u, 26f * u, PARCHMENT, serif, Paint.Align.CENTER, u);
|
||||
boolean low = v.socPercent != null && v.socPercent < 20f;
|
||||
if (low && (SystemClock.uptimeMillis() / 600) % 2 == 0) {
|
||||
say(c, "Your battery is running low!", x, top + 236f * u, 28f * u, 0xFFFFD040, serif,
|
||||
Paint.Align.CENTER, u);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Resource bar ----------
|
||||
|
||||
private void drawResources(Canvas c, float w, float top, float u) {
|
||||
wood(c, 0, 0, w, top, u);
|
||||
line.setColor(TRIM);
|
||||
line.setStrokeWidth(2f * u);
|
||||
c.drawLine(0, top - 1f * u, w, top - 1f * u, line);
|
||||
float y = top / 2f, x = 22f * u, slot = 170f * u;
|
||||
boolean low = v.socPercent != null && v.socPercent < 20f;
|
||||
icon(c, 0, x, y, u);
|
||||
say(c, fmt(v.socPercent, "%.0f %%", "—"), x + 30f * u, y + 9f * u, 26f * u, low ? RED : PARCHMENT, sans,
|
||||
Paint.Align.LEFT, u);
|
||||
x += slot;
|
||||
icon(c, 1, x, y, u);
|
||||
say(c, fmt(v.rangeKm, "%.0f km", "—"), x + 30f * u, y + 9f * u, 26f * u, PARCHMENT, sans, Paint.Align.LEFT, u);
|
||||
x += slot;
|
||||
icon(c, 2, x, y, u);
|
||||
boolean regen = v.powerKw != null && v.powerKw < -0.05f;
|
||||
String power = v.powerKw == null ? "—" : String.format(Locale.US, regen ? "+%.1f kW" : "%.1f kW",
|
||||
Math.abs(v.powerKw));
|
||||
say(c, power, x + 30f * u, y + 9f * u, 26f * u, regen ? REGEN : PARCHMENT, sans, Paint.Align.LEFT, u);
|
||||
x += slot;
|
||||
icon(c, 3, x, y, u);
|
||||
say(c, fmt(v.usage5Min, "%.1f kWh/100", "—"), x + 30f * u, y + 9f * u, 26f * u, PARCHMENT, sans,
|
||||
Paint.Align.LEFT, u);
|
||||
say(c, v.clock.isEmpty() ? "—" : v.clock, w - 22f * u, y + 9f * u, 26f * u, PARCHMENT, sans,
|
||||
Paint.Align.RIGHT, u);
|
||||
say(c, EmpireAge.name(v.odometerKm), w - 130f * u, y + 9f * u, 26f * u, 0xFFFFD873, serif,
|
||||
Paint.Align.RIGHT, u);
|
||||
}
|
||||
|
||||
/** Small resource pictures: 0 battery, 1 flag, 2 bolt, 3 leaf. */
|
||||
private void icon(Canvas c, int kind, float x, float y, float u) {
|
||||
float s = 11f * u;
|
||||
fill.setColor(0xFF000000);
|
||||
r.set(x - s - 2f * u, y - s - 2f * u, x + s + 2f * u, y + s + 2f * u);
|
||||
c.drawRect(r, fill);
|
||||
line.setColor(TRIM);
|
||||
line.setStrokeWidth(1.2f * u);
|
||||
c.drawRect(r, line);
|
||||
path.reset();
|
||||
switch (kind) {
|
||||
case 0:
|
||||
fill.setColor(HEALTH);
|
||||
c.drawRect(x - s * 0.5f, y - s * 0.6f, x + s * 0.5f, y + s * 0.85f, fill);
|
||||
c.drawRect(x - s * 0.22f, y - s * 0.85f, x + s * 0.22f, y - s * 0.6f, fill);
|
||||
break;
|
||||
case 1:
|
||||
fill.setColor(TEAM);
|
||||
path.moveTo(x - s * 0.5f, y - s * 0.8f);
|
||||
path.lineTo(x + s * 0.7f, y - s * 0.45f);
|
||||
path.lineTo(x - s * 0.5f, y - s * 0.1f);
|
||||
path.close();
|
||||
c.drawPath(path, fill);
|
||||
line.setColor(PARCHMENT);
|
||||
line.setStrokeWidth(1.5f * u);
|
||||
c.drawLine(x - s * 0.5f, y - s * 0.85f, x - s * 0.5f, y + s * 0.85f, line);
|
||||
break;
|
||||
case 2:
|
||||
fill.setColor(0xFFFFD040);
|
||||
path.moveTo(x + s * 0.2f, y - s * 0.9f);
|
||||
path.lineTo(x - s * 0.55f, y + s * 0.1f);
|
||||
path.lineTo(x, y + s * 0.1f);
|
||||
path.lineTo(x - s * 0.2f, y + s * 0.9f);
|
||||
path.lineTo(x + s * 0.55f, y - s * 0.15f);
|
||||
path.lineTo(x, y - s * 0.15f);
|
||||
path.close();
|
||||
c.drawPath(path, fill);
|
||||
break;
|
||||
default:
|
||||
fill.setColor(REGEN);
|
||||
path.moveTo(x - s * 0.7f, y + s * 0.7f);
|
||||
path.quadTo(x - s * 0.9f, y - s * 0.9f, x + s * 0.7f, y - s * 0.7f);
|
||||
path.quadTo(x + s * 0.9f, y + s * 0.8f, x - s * 0.7f, y + s * 0.7f);
|
||||
c.drawPath(path, fill);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Bottom panel ----------
|
||||
|
||||
private void drawPanel(Canvas c, float w, float h, float bottom, float u) {
|
||||
wood(c, 0, bottom, w, h, u);
|
||||
line.setColor(TRIM);
|
||||
line.setStrokeWidth(3f * u);
|
||||
c.drawLine(0, bottom + 1.5f * u, w, bottom + 1.5f * u, line);
|
||||
drawCommands(c, bottom, u);
|
||||
float mapW = 250f * u;
|
||||
drawUnitInfo(c, 224f * u, bottom, w - mapW - 40f * u, h, u);
|
||||
drawMinimap(c, w - mapW - 20f * u, bottom, w - 20f * u, h, u);
|
||||
}
|
||||
|
||||
/** P R N D as command buttons, two by two. */
|
||||
private void drawCommands(Canvas c, float bottom, float u) {
|
||||
String[] gears = { "P", "R", "N", "D" };
|
||||
String now = Gear.label(v.gear);
|
||||
float s = 74f * u, gap = 8f * u, l = 30f * u, t = bottom + 16f * u;
|
||||
for (int i = 0; i < gears.length; i++) {
|
||||
float x = l + (i % 2) * (s + gap), y = t + (i / 2) * (s + gap);
|
||||
boolean on = gears[i].equals(now);
|
||||
inset(c, x, y, x + s, y + s, on ? 0xFF22346E : 0xFF1A120A, u);
|
||||
if (on) {
|
||||
line.setColor(0xFFFFD873);
|
||||
line.setStrokeWidth(3f * u);
|
||||
c.drawRect(x + 3f * u, y + 3f * u, x + s - 3f * u, y + s - 3f * u, line);
|
||||
}
|
||||
say(c, gears[i], x + s / 2f, y + s * 0.68f, 40f * u, on ? 0xFFFFFFFF : 0xFF9A8A6A, serif,
|
||||
Paint.Align.CENTER, u);
|
||||
}
|
||||
}
|
||||
|
||||
/** The selected unit: portrait, health, name and stats. */
|
||||
private void drawUnitInfo(Canvas c, float l, float t, float rr, float b, float u) {
|
||||
inset(c, l, t + 16f * u, rr, b - 14f * u, 0xFF1A120A, u);
|
||||
float ps = 96f * u, px = l + 16f * u, py = t + 28f * u;
|
||||
inset(c, px, py, px + ps, py + ps, 0xFF2C3E1E, u);
|
||||
carProfile(c, px + ps / 2f, py + ps * 0.6f, ps * 0.38f, TEAM);
|
||||
float frac = v.socPercent == null ? 0f : v.socPercent / 100f;
|
||||
boolean low = v.socPercent != null && v.socPercent < 20f;
|
||||
bar(c, px, py + ps + 8f * u, px + ps, py + ps + 22f * u, frac, low ? RED : HEALTH, u);
|
||||
say(c, fmt(v.socPercent, "%.0f / 100", "—"), px + ps / 2f, py + ps + 40f * u, 16f * u, PARCHMENT, sans,
|
||||
Paint.Align.CENTER, u);
|
||||
|
||||
float x = px + ps + 24f * u;
|
||||
say(c, "MG4", x, py + 26f * u, 28f * u, 0xFFFFD873, serif, Paint.Align.LEFT, u);
|
||||
say(c, "Electric Cart", x + 80f * u, py + 26f * u, 20f * u, PARCHMENT, serif, Paint.Align.LEFT, u);
|
||||
String[][] stats = {
|
||||
{ "Range", fmt(v.rangeKm, "%.0f km", "—") },
|
||||
{ "Trip", fmt(v.tripKm, "%.1f km", "—") },
|
||||
{ "Since start", fmt(v.usageTrip, "%.1f kWh/100 km", "—") },
|
||||
{ "Climate", fmt(v.climateCelsius, "%.0f °C", "—") },
|
||||
};
|
||||
float colW = (rr - x - 16f * u) / 2f;
|
||||
for (int i = 0; i < stats.length; i++) {
|
||||
float sx = x + (i % 2) * colW, sy = py + (66f + (i / 2) * 50f) * u;
|
||||
fill.setColor(TRIM);
|
||||
path.reset();
|
||||
path.moveTo(sx + 6f * u, sy - 20f * u);
|
||||
path.lineTo(sx + 12f * u, sy - 14f * u);
|
||||
path.lineTo(sx + 6f * u, sy - 8f * u);
|
||||
path.lineTo(sx, sy - 14f * u);
|
||||
path.close();
|
||||
c.drawPath(path, fill);
|
||||
say(c, stats[i][0], sx + 20f * u, sy - 7f * u, 17f * u, 0xFFBFAE88, sans, Paint.Align.LEFT, u);
|
||||
say(c, stats[i][1], sx + 20f * u, sy + 18f * u, 23f * u, PARCHMENT, sans, Paint.Align.LEFT, u);
|
||||
}
|
||||
}
|
||||
|
||||
/** The diamond minimap: the player's land round the car, the road, the odometer under it. */
|
||||
private void drawMinimap(Canvas c, float l, float t, float rr, float b, float u) {
|
||||
float cx = (l + rr) / 2f, cy = t + 60f * u, hw = (rr - l) / 2f, hh = 44f * u;
|
||||
path.reset();
|
||||
path.moveTo(cx, cy - hh);
|
||||
path.lineTo(cx + hw, cy);
|
||||
path.lineTo(cx, cy + hh);
|
||||
path.lineTo(cx - hw, cy);
|
||||
path.close();
|
||||
fill.setColor(0xFF000000);
|
||||
c.drawPath(path, fill);
|
||||
c.save();
|
||||
c.clipPath(path);
|
||||
fill.setColor(0xFF35561F);
|
||||
c.drawOval(cx - hw * 0.7f, cy - hh * 0.65f, cx + hw * 0.5f, cy + hh * 0.75f, fill);
|
||||
fill.setColor(AccentColor.withAlpha(TEAM, 0x70));
|
||||
c.drawOval(cx - hw * 0.32f, cy - hh * 0.3f, cx + hw * 0.2f, cy + hh * 0.34f, fill);
|
||||
line.setColor(ROAD);
|
||||
line.setStrokeWidth(3f * u);
|
||||
c.drawLine(cx - hw, cy + hh, cx + hw, cy - hh, line);
|
||||
c.restore();
|
||||
line.setColor(TRIM);
|
||||
line.setStrokeWidth(2f * u);
|
||||
c.drawPath(path, line);
|
||||
fill.setColor(0xFFFFFFFF);
|
||||
c.drawCircle(cx, cy, 5f * u, fill);
|
||||
fill.setColor(TEAM);
|
||||
c.drawCircle(cx, cy, 3.5f * u, fill);
|
||||
|
||||
say(c, fmt(v.odometerKm, "%,.0f km", "—"), cx, cy + hh + 24f * u, 20f * u, PARCHMENT, sans,
|
||||
Paint.Align.CENTER, u);
|
||||
String next = EmpireAge.next(v.odometerKm);
|
||||
Float toNext = EmpireAge.toNext(v.odometerKm);
|
||||
String towards = next == null || toNext == null ? EmpireAge.name(v.odometerKm)
|
||||
: String.format(Locale.US, "%s in %,.0f km", next, toNext);
|
||||
bar(c, l + 12f * u, b - 28f * u, rr - 12f * u, b - 14f * u, EmpireAge.progress(v.odometerKm), 0xFFFFD873, u);
|
||||
say(c, towards, cx, b - 34f * u, 15f * u, 0xFFBFAE88, sans, Paint.Align.CENTER, u);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user