Skip to content

Commit fd5522f

Browse files
Add weapon sprites and arena obstacles
1 parent 3f07477 commit fd5522f

17 files changed

Lines changed: 224 additions & 28 deletions

app/game.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,10 @@ export default function GameScreen() {
510510
materials={state?.materials ?? 0}
511511
playerEmoji={state?.player?.emoji ?? '🦀'}
512512
victory={state?.victory ?? false}
513-
weapons={(state?.player?.weapons ?? []).map(w => ({
514-
emoji: (w?.evolved ? EVOLVED_WEAPONS[w?.id] : WEAPONS[w?.id])?.emoji ?? '?'
513+
weapons={(state?.player?.weapons ?? []).map(w => ({
514+
id: w?.id,
515+
evolved: w?.evolved,
516+
emoji: (w?.evolved ? EVOLVED_WEAPONS[w?.id] : WEAPONS[w?.id])?.emoji ?? '?'
515517
}))}
516518
items={(state?.player?.items ?? []).map(it => ({
517519
emoji: ITEM_DEFS.find(d => d.id === it?.id)?.emoji ?? '?',

assets/weapons/icons/claw.png

74.9 KB
Loading

assets/weapons/icons/crossbow.png

75.6 KB
Loading

assets/weapons/icons/lightning.png

76.4 KB
Loading

assets/weapons/icons/pistol.png

77.8 KB
Loading

assets/weapons/icons/shotgun.png

51.9 KB
Loading

assets/weapons/icons/smg.png

59 KB
Loading

assets/weapons/icons/stick.png

60.5 KB
Loading

assets/weapons/icons/sword.png

53.8 KB
Loading

components/game/GameCanvas.tsx

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { View, Text, StyleSheet } from 'react-native';
33
import type { GameState } from '../../engine/types';
44
import { ELITE_EMOJIS, ELITE_COLORS } from '../../engine/data';
55
import ArenaBackground from './arena/ArenaBackground';
6+
import WeaponIcon, { hasWeaponIcon } from './WeaponIcon';
67

78
interface Props {
89
gameState: React.RefObject<GameState | null>;
@@ -50,6 +51,7 @@ export default function GameCanvas({ gameState, frame }: Props) {
5051
const showProjectileTrails = !crowded && visibleProjectiles.length < 34;
5152
const showCritFlash = !crowded && state.hitStop > 0.06;
5253
const bgFrame = Math.floor(frame / (crowded ? 4 : 3));
54+
const visibleWeaponSprites = (p.weapons ?? []).filter(w => hasWeaponIcon(w.id, w.evolved)).slice(0, crowded ? 2 : 4);
5355

5456
return (
5557
<View style={s.viewport} pointerEvents="none">
@@ -454,13 +456,29 @@ export default function GameCanvas({ gameState, frame }: Props) {
454456
})}
455457
{/* Player */}
456458
<View style={[s.playerWrap, { left: p.x - 24, top: p.y - 32 }]}>
457-
{state.inWater && !crowded && <View style={s.playerWaterRing} />}
458-
<View style={s.playerAura} />
459-
{/* Player ground glow ring */}
460-
<View style={[s.playerGroundGlow, {
461-
opacity: 0.12 + Math.sin(frame * 0.06) * 0.04,
462-
}]} />
463-
<View style={s.playerFocusShadow} />
459+
{visibleWeaponSprites.map((weapon, i) => {
460+
const count = visibleWeaponSprites.length;
461+
const angle = frame * 0.025 + i * ((Math.PI * 2) / Math.max(1, count));
462+
const radius = 28 + Math.min(8, count * 2);
463+
const x = 24 + Math.cos(angle) * radius;
464+
const y = 23 + Math.sin(angle) * radius * 0.46;
465+
return (
466+
<View
467+
key={`${weapon.id}-${i}`}
468+
style={[
469+
s.playerWeaponSprite,
470+
{
471+
left: x - 14,
472+
top: y - 14,
473+
opacity: 0.78 + Math.sin(frame * 0.08 + i) * 0.08,
474+
transform: [{ rotate: `${angle * 0.4}rad` }, { scale: weapon.evolved ? 1.12 : 1 }],
475+
},
476+
]}
477+
>
478+
<WeaponIcon id={weapon.id} evolved={weapon.evolved} size={28} />
479+
</View>
480+
);
481+
})}
464482
<Text style={[s.playerEmoji, p.invulnTimer > 0 && { opacity: 0.5 }]}>{p.emoji}</Text>
465483
<View style={s.pHpBg}>
466484
<View style={[s.pHp, { width: `${Math.max(0, (p.hp / p.maxHp) * 100)}%` }]} />
@@ -674,10 +692,7 @@ const s = StyleSheet.create({
674692
hpBarBg: { width: 30, height: 3, backgroundColor: 'rgba(255,255,255,0.15)', borderRadius: 2, marginTop: 2 },
675693
hpBar: { height: 3, backgroundColor: '#EF4444', borderRadius: 2 },
676694
playerWrap: { position: 'absolute', alignItems: 'center', width: 48 },
677-
playerWaterRing: { position: 'absolute', top: 22, width: 58, height: 18, borderRadius: 29, borderWidth: 1, borderColor: 'rgba(125,211,252,0.45)', backgroundColor: 'rgba(14,116,144,0.1)' },
678-
playerAura: { position: 'absolute', top: 31, width: 42, height: 10, borderRadius: 21, backgroundColor: 'rgba(45,212,191,0.08)' },
679-
playerGroundGlow: { position: 'absolute', top: 24, width: 58, height: 18, borderRadius: 29, backgroundColor: 'rgba(45,212,191,0.055)', borderWidth: 1, borderColor: 'rgba(45,212,191,0.08)' },
680-
playerFocusShadow: { position: 'absolute', top: 29, width: 44, height: 12, borderRadius: 22, backgroundColor: 'rgba(2,6,23,0.55)' },
695+
playerWeaponSprite: { position: 'absolute', width: 28, height: 28, alignItems: 'center', justifyContent: 'center', zIndex: 1 },
681696
playerEmoji: { fontSize: 42, textAlign: 'center', textShadowColor: 'rgba(0,0,0,0.95)', textShadowOffset: { width: 0, height: 3 }, textShadowRadius: 7 },
682697
shieldIcon: { position: 'absolute', top: -5, fontSize: 20 },
683698
petWrap: { position: 'absolute', alignItems: 'center', justifyContent: 'center' },

0 commit comments

Comments
 (0)