Skip to content

Commit ae3d0e0

Browse files
authored
fix: Fix background color blending by using doubles (#102)
1 parent fef633c commit ae3d0e0

File tree

2 files changed

+59
-51
lines changed

2 files changed

+59
-51
lines changed

lib/game/components/background.dart

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import 'package:lightrunners/game/lightrunners_game.dart';
88
import 'package:lightrunners/ui/palette.dart';
99
import 'package:lightrunners/utils/delaunay.dart';
1010
import 'package:lightrunners/utils/flame_utils.dart';
11+
import 'package:lightrunners/utils/mutable_color.dart';
1112

1213
const _margin = 200.0;
1314

1415
const _numberShades = 5;
1516
const _shadeStep = 0.1;
16-
const _colorMoveSpeed = 30;
17+
const _colorMoveSpeed = 0.8;
1718
final _emptyColor = GamePalette.black.brighten(0.1);
1819
final _borderPaint = Paint()
1920
..color = GamePalette.black
@@ -33,7 +34,7 @@ class Background extends PositionComponent
3334
late Rect clipArea;
3435
late List<ShadedTriangle> mesh;
3536

36-
Color currentColor = _emptyColor;
37+
MutableColor currentColor = MutableColor.fromColor(_emptyColor);
3738

3839
@override
3940
void onGameResize(Vector2 gameSize) {
@@ -72,8 +73,7 @@ class Background extends PositionComponent
7273
super.update(dt);
7374

7475
final targetColor = _computeTargetColor();
75-
currentColor =
76-
_moveTowards(currentColor, targetColor, _colorMoveSpeed * dt);
76+
currentColor.moveTowards(targetColor, _colorMoveSpeed * dt);
7777
}
7878

7979
@override
@@ -82,7 +82,8 @@ class Background extends PositionComponent
8282
canvas.clipRect(clipArea);
8383

8484
for (final t in mesh) {
85-
final shadedColor = currentColor.brighten(t.shadeLevel * _shadeStep);
85+
final shadedColor =
86+
currentColor.toColor().brighten(t.shadeLevel * _shadeStep);
8687
canvas.drawPath(t.path, paint..color = shadedColor);
8788
}
8889

@@ -91,60 +92,19 @@ class Background extends PositionComponent
9192
}
9293
}
9394

94-
(int, int, int) _computeTargetColor() {
95+
MutableColor _computeTargetColor() {
9596
final sortedShips = game.ships.values.sortedBy<num>((ship) => -ship.score);
9697
final maxScore = sortedShips.first.score;
9798
if (maxScore == 0) {
98-
return _fromColor(_emptyColor);
99+
return MutableColor.fromColor(_emptyColor);
99100
}
100101
final colors = sortedShips
101102
.takeWhile((ship) => ship.score == maxScore)
102103
.map((ship) => ship.paint.color.darken(0.75))
103104
.toList();
104-
return colors.map(_fromColor).reduce((value, element) => value + element) /
105+
return colors
106+
.map(MutableColor.fromColor)
107+
.reduce((value, element) => value + element) /
105108
colors.length.toDouble();
106109
}
107-
108-
Color _moveTowards(Color currentColor, (int, int, int) target, double ds) {
109-
final color = _fromColor(currentColor);
110-
if (color == target) {
111-
return currentColor;
112-
}
113-
return color.moveTowards(target, ds).toColor();
114-
}
115110
}
116-
117-
extension on (int, int, int) {
118-
Color toColor() => Color.fromARGB(255, $1, $2, $3);
119-
120-
(int, int, int) operator +((int, int, int) other) =>
121-
(this.$1 + other.$1, this.$2 + other.$2, this.$3 + other.$3);
122-
123-
(int, int, int) operator -((int, int, int) other) => this + (-other);
124-
125-
(int, int, int) operator /(double other) =>
126-
_fromDoubles(this.$1 / other, this.$2 / other, this.$3 / other);
127-
128-
(int, int, int) operator *(double other) =>
129-
_fromDoubles(this.$1 * other, this.$2 * other, this.$3 * other);
130-
131-
(int, int, int) operator -() => (-this.$1, -this.$2, -this.$3);
132-
133-
double get length => sqrt($1 * $1 + $2 * $2 + $3 * $3);
134-
135-
(int, int, int) normalized() => this / length;
136-
137-
(int, int, int) moveTowards((int, int, int) target, double ds) {
138-
final diff = target - this;
139-
if (diff.length < ds) {
140-
return target;
141-
} else {
142-
return this + diff.normalized() * ds;
143-
}
144-
}
145-
}
146-
147-
(int, int, int) _fromDoubles(double r, double g, double b) =>
148-
(r.round(), g.round(), b.round());
149-
150-
(int, int, int) _fromColor(Color color) => (color.red, color.green, color.blue);

lib/utils/mutable_color.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import 'package:flame/extensions.dart';
2+
3+
class MutableColor {
4+
final Vector3 rgb;
5+
6+
double get r => rgb.x;
7+
set r(double value) => rgb.x = value;
8+
9+
double get g => rgb.y;
10+
set g(double value) => rgb.y = value;
11+
12+
double get b => rgb.z;
13+
set b(double value) => rgb.z = value;
14+
15+
MutableColor(double r, double g, double b) : rgb = Vector3(r, g, b);
16+
17+
MutableColor.fromColor(Color color)
18+
: this(
19+
color.red.toDouble(),
20+
color.green.toDouble(),
21+
color.blue.toDouble(),
22+
);
23+
24+
Color toColor() => Color.fromARGB(255, r.round(), g.round(), b.round());
25+
26+
MutableColor operator +(MutableColor other) {
27+
return MutableColor(r + other.r, g + other.g, b + other.b);
28+
}
29+
30+
MutableColor operator /(double scalar) {
31+
return MutableColor(r / scalar, g / scalar, b / scalar);
32+
}
33+
34+
void moveTowards(MutableColor target, double ds) {
35+
r = _moveTowards(r, target.r, ds);
36+
g = _moveTowards(g, target.g, ds);
37+
b = _moveTowards(b, target.b, ds);
38+
}
39+
40+
double _moveTowards(double current, double target, double ds) {
41+
final diff = target - current;
42+
if (diff.abs() < ds) {
43+
return target;
44+
} else {
45+
return current + ds * diff.sign;
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)