Skip to content

Commit 97513a7

Browse files
committed
Improve hand view responsiveness and fix object spawning
- Add smooth animations and hover effects to hand items - Fix jittering when dragging items from the hand view - Ensure spawning objects in a cell appends to existing ones instead of overwriting
1 parent 197ddb3 commit 97513a7

4 files changed

Lines changed: 74 additions & 19 deletions

File tree

api/lib/src/event/process/server.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ ServerProcessed processServerEvent(
183183
case ObjectsSpawned():
184184
return ServerProcessed(
185185
state.mapTableOrDefault(event.table, (table) {
186-
var newTable = table;
186+
final cells = Map<VectorDefinition, TableCell>.from(table.cells);
187187
for (final entry in event.objects.entries) {
188-
final cell = newTable.cells[entry.key] ?? TableCell();
189-
newTable = newTable.copyWith.cellsBox(
190-
content: Map<VectorDefinition, TableCell>.from(newTable.cells)
191-
..[entry.key] = cell.copyWith(objects: entry.value),
192-
);
188+
cells[entry.key] = table
189+
.getCell(entry.key)
190+
.copyWith
191+
.objects
192+
.addAll(entry.value);
193193
}
194-
return newTable;
194+
return table.copyWith.cellsBox(content: cells);
195195
}),
196196
);
197197
case ObjectsMoved():

app/lib/board/hand/item.dart

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ abstract class HandItem<T> extends PositionComponent
100100
HandItemDropZone,
101101
DragCallbacks,
102102
TapCallbacks,
103+
HoverCallbacks,
103104
LongDragCallbacks,
104105
DoubleTapCallbacks,
105106
SecondaryTapCallbacks,
@@ -109,6 +110,11 @@ abstract class HandItem<T> extends PositionComponent
109110
final SpriteComponent _sprite = SpriteComponent();
110111
late final TextComponent<TextPaint> _label;
111112

113+
Vector2? targetPosition;
114+
double? targetAngle;
115+
double? targetWidth;
116+
bool _isHovered = false;
117+
112118
HandItem({required this.item})
113119
: super(size: Vector2(100, 0), anchor: Anchor.bottomCenter);
114120

@@ -173,10 +179,53 @@ abstract class HandItem<T> extends PositionComponent
173179
_updateSpriteSize();
174180
}
175181

182+
@override
183+
void update(double dt) {
184+
super.update(dt);
185+
if (targetPosition != null) {
186+
if (position.distanceToSquared(targetPosition!) > 0.5) {
187+
position.lerp(targetPosition!, dt * 15);
188+
} else {
189+
position.setFrom(targetPosition!);
190+
}
191+
}
192+
if (targetAngle != null) {
193+
if ((angle - targetAngle!).abs() > 0.005) {
194+
angle = angle + (targetAngle! - angle) * dt * 15;
195+
} else {
196+
angle = targetAngle!;
197+
}
198+
}
199+
if (targetWidth != null) {
200+
if ((width - targetWidth!).abs() > 0.5) {
201+
width = width + (targetWidth! - width) * dt * 15;
202+
_label.x = width / 2;
203+
_updateSpriteSize();
204+
} else {
205+
width = targetWidth!;
206+
}
207+
}
208+
209+
final targetScale = _isHovered ? 1.1 : 1.0;
210+
if ((scale.x - targetScale).abs() > 0.005) {
211+
scale.lerp(Vector2.all(targetScale), dt * 15);
212+
} else {
213+
scale.setValues(targetScale, targetScale);
214+
}
215+
}
216+
217+
@override
218+
void onHoverEnter() {
219+
_isHovered = true;
220+
}
221+
222+
@override
223+
void onHoverExit() {
224+
_isHovered = false;
225+
}
226+
176227
void updateWidth(double width) {
177-
this.width = width;
178-
_label.x = width / 2;
179-
_updateSpriteSize();
228+
targetWidth = width;
180229
}
181230

182231
void _updateSpriteSize() {
@@ -190,10 +239,10 @@ abstract class HandItem<T> extends PositionComponent
190239

191240
final scaleX = availableWidth / spriteSize.x;
192241
final scaleY = availableHeight / spriteSize.y;
193-
final scale = scaleX < scaleY ? scaleX : scaleY;
242+
final spriteScale = scaleX < scaleY ? scaleX : scaleY;
194243

195-
final newWidth = spriteSize.x * scale;
196-
final newHeight = spriteSize.y * scale;
244+
final newWidth = spriteSize.x * spriteScale;
245+
final newHeight = spriteSize.y * spriteScale;
197246

198247
_sprite.size = Vector2(newWidth, newHeight);
199248
_sprite.position = Vector2(
@@ -212,7 +261,7 @@ abstract class HandItem<T> extends PositionComponent
212261
game.world.add(
213262
_cursorHitbox = HandItemDragCursorHitbox(
214263
item: this,
215-
position: event.localPosition,
264+
position: game.camera.globalToLocal(event.canvasPosition),
216265
),
217266
);
218267
_last = event.canvasPosition;
@@ -247,7 +296,9 @@ abstract class HandItem<T> extends PositionComponent
247296
opacityTo: 0.5,
248297
),
249298
);
250-
add(sprite);
299+
if (sprite.parent == null) {
300+
add(sprite);
301+
}
251302
sprite.position = event.localEndPosition;
252303
_last = event.canvasEndPosition;
253304
_cursorHitbox?.position = game.camera.globalToLocal(

app/lib/board/hand/view.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,15 @@ class GameHand extends CustomPainterComponent
123123
final offset = activeRelative <= -1 ? -activeItemWidth / 2 : 0;
124124
y = center.y + itemYOffset * activeRelative.abs();
125125
x = center.x + offset + activeRelative * itemWidth;
126-
element.angle = activeRelative * itemAngle;
126+
element.targetAngle = activeRelative * itemAngle;
127+
} else {
128+
element.targetAngle = 0;
127129
}
128130
element.updateWidth(width);
129131

130132
element.changeLabelVisibility(activeRelative.abs() >= 1);
131133

132-
element.position = Vector2(x, y);
134+
element.targetPosition = Vector2(x, y);
133135
});
134136
}
135137

@@ -282,8 +284,7 @@ class GameHand extends CustomPainterComponent
282284
if (delta == 0) {
283285
delta = info.scrollDelta.global.y;
284286
}
285-
delta /= 4;
286-
scroll(delta > 0 ? -1 : 1);
287+
scroll(-delta * 0.01);
287288
return true;
288289
}
289290

metadata/en-US/changelogs/11.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* Add support for game modes and scripts in single-player
55
* Add game mode and scripts to editor
66
* Add localized names and descriptions for game modes
7+
* Improve hand view UI animations and responsiveness
8+
* Fix jittering when dragging items from hand
9+
* Fix spawning objects overwriting existing ones in a cell
710
* Fix server state dropping hidden card variations before script evaluation
811
* Fix server builds not created for released versions
912
* Improve server docs by ignoring generated files

0 commit comments

Comments
 (0)