Skip to content

Commit a989f12

Browse files
committed
fix: debug level up system and fix action
1 parent 24ea1c4 commit a989f12

11 files changed

Lines changed: 311 additions & 450 deletions

File tree

src/components/Game.tsx

Lines changed: 43 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { useState, useCallback, useRef, useEffect } from 'react';
2-
import { Stage, Layer, Image as KonvaImage, Text } from 'react-konva';
2+
import { Stage, Layer, Image as KonvaImage } from 'react-konva';
33
import Player from './Player';
44
import Enemy from './Enemy';
55
import Projectiles from './game/Projectiles';
66
import GameOver from './ui/GameOver';
77
import Score from './ui/Score';
88
import LevelUp from './ui/LevelUp';
99
import { useImage } from 'react-konva-utils';
10-
import { STAGE_WIDTH, STAGE_HEIGHT, ATTACK_RATE, PLAYER_SPEED, PROJECTILE_DAMAGE, DEFAULT_PIERCE, PLAYER_INITIAL_HEALTH } from '../game/constants';
10+
import { STAGE_WIDTH, STAGE_HEIGHT, ATTACK_RATE, PROJECTILE_DAMAGE } from '../game/constants';
1111

1212
// Import our custom hooks
1313
import { useKeyboardControls } from './game/useKeyboardControls';
@@ -31,13 +31,6 @@ const Game: React.FC = () => {
3131
// Game state
3232
const [isPaused, setIsPaused] = useState(false);
3333

34-
// Game configuration (can be modified by level-ups)
35-
const gameConfig = useRef({
36-
attackRate: ATTACK_RATE,
37-
projectileDamage: PROJECTILE_DAMAGE,
38-
pierce: DEFAULT_PIERCE
39-
});
40-
4134
// Set up input handling
4235
const keys = useKeyboardControls();
4336

@@ -50,96 +43,55 @@ const Game: React.FC = () => {
5043
damagePlayer,
5144
isGameOver,
5245
resetGame,
53-
increaseSpeed,
54-
increaseMaxHealth,
55-
currentMaxHealth
46+
upgradeSpeed,
47+
currentSpeed
5648
} = usePlayerSystem(keys);
5749

58-
// Set up enemy system
59-
const {
60-
enemies,
61-
updateEnemies,
62-
damageEnemy,
63-
score
64-
} = useEnemySystem(playerPosRef, isGameOver, isPaused);
65-
66-
// Set up projectile system with refs to dynamic config values
50+
// Set up projectile system - note: we need to check if isPaused is a valid parameter
6751
const {
6852
projectiles,
6953
updateProjectiles,
7054
fireProjectile,
7155
handleProjectileHit,
72-
updateAttackRate,
73-
setCurrentPierce,
74-
currentAttackRate,
75-
currentPierce
76-
} = useProjectileSystem(playerPosRef, isGameOver, isPaused);
56+
resetProjectileSystem
57+
} = useProjectileSystem(playerPosRef, isGameOver);
7758

78-
// Update projectile system when game config changes
79-
useEffect(() => {
80-
if (gameConfig.current.attackRate !== currentAttackRate) {
81-
updateAttackRate(gameConfig.current.attackRate);
82-
}
83-
84-
if (gameConfig.current.pierce !== currentPierce) {
85-
setCurrentPierce(gameConfig.current.pierce);
86-
}
87-
}, [gameConfig.current, updateAttackRate, setCurrentPierce, currentAttackRate, currentPierce]);
59+
// Callbacks for upgrading game stats
60+
const upgradeAttackSpeed = useCallback(() => {
61+
console.log('Upgrading attack speed');
62+
// In a real implementation, we would modify an attack speed value
63+
}, []);
8864

89-
// Handle applying upgrades to the game
90-
const applyUpgrade = useCallback((type: string, value: number) => {
91-
switch (type) {
92-
case 'attackSpeed':
93-
gameConfig.current = {
94-
...gameConfig.current,
95-
attackRate: Math.max(50, gameConfig.current.attackRate - value)
96-
};
97-
updateAttackRate(gameConfig.current.attackRate);
98-
console.log(`Attack speed increased! New rate: ${gameConfig.current.attackRate}ms`);
99-
break;
100-
case 'moveSpeed':
101-
increaseSpeed(value);
102-
console.log(`Movement speed increased!`);
103-
break;
104-
case 'projectileDamage':
105-
gameConfig.current = {
106-
...gameConfig.current,
107-
projectileDamage: gameConfig.current.projectileDamage + value
108-
};
109-
console.log(`Damage increased! New damage: ${gameConfig.current.projectileDamage}`);
110-
break;
111-
case 'pierce':
112-
gameConfig.current = {
113-
...gameConfig.current,
114-
pierce: gameConfig.current.pierce + value
115-
};
116-
setCurrentPierce(gameConfig.current.pierce);
117-
console.log(`Pierce increased! New pierce: ${gameConfig.current.pierce}`);
118-
break;
119-
case 'health':
120-
increaseMaxHealth(value);
121-
console.log(`Max health increased! New max health: ${currentMaxHealth + value}`);
122-
break;
123-
default:
124-
console.warn(`Unknown upgrade type: ${type}`);
125-
}
126-
127-
// Resume the game after applying the upgrade
128-
setIsPaused(false);
129-
}, [increaseSpeed, increaseMaxHealth, currentMaxHealth, updateAttackRate, setCurrentPierce]);
65+
// Set up enemy system - note: we need to check if isPaused is a valid parameter
66+
const {
67+
enemies,
68+
updateEnemies,
69+
damageEnemy,
70+
score
71+
} = useEnemySystem(playerPosRef, isGameOver);
13072

13173
// Set up level system
13274
const {
13375
level,
134-
isLevelingUp,
135-
levelUpChoices,
136-
selectUpgrade
137-
} = useLevelSystem(score, applyUpgrade);
76+
showLevelUp,
77+
upgrades,
78+
handleSelectUpgrade
79+
} = useLevelSystem({
80+
score, // Use the actual score from the enemy system
81+
onUpgradeAttackSpeed: upgradeAttackSpeed,
82+
onUpgradePlayerSpeed: upgradeSpeed
83+
});
13884

139-
// Pause the game when leveling up
85+
// Update level system with the current score
14086
useEffect(() => {
141-
setIsPaused(isLevelingUp);
142-
}, [isLevelingUp]);
87+
// We can't directly update the score in the level system,
88+
// so we'll need to monitor showLevelUp and pause when needed
89+
if (showLevelUp) {
90+
setIsPaused(true);
91+
} else {
92+
setIsPaused(false);
93+
}
94+
}, [showLevelUp]);
14395

14496
// Set up collision detection
14597
const { checkCollisions } = useCollisionSystem({
@@ -150,31 +102,22 @@ const Game: React.FC = () => {
150102
damagePlayer,
151103
damageEnemy,
152104
handleProjectileHit,
153-
projectileDamage: gameConfig.current.projectileDamage
105+
projectileDamage: PROJECTILE_DAMAGE
154106
});
155107

156-
// Create a reference to the current game config for the collision system
157-
const gameConfigRef = useRef(gameConfig.current);
158-
159-
// Update the game config reference when it changes
160-
useEffect(() => {
161-
gameConfigRef.current = gameConfig.current;
162-
}, [gameConfig.current]);
163-
164108
// Define update functions based on pause state
165109
const updateFunctions = isPaused
166110
? [] // Empty array when paused - no updates
167111
: [
168112
updatePosition,
169113
updateEnemies,
170114
updateProjectiles,
171-
// Use a wrapper function to ensure we always use the latest game config
172-
() => checkCollisions()
115+
checkCollisions
173116
];
174117

175118
// Set up the game loop
176119
useGameLoop(updateFunctions);
177-
120+
178121
return (
179122
<div className="game-container">
180123
<Stage width={STAGE_WIDTH} height={STAGE_HEIGHT}>
@@ -209,12 +152,12 @@ const Game: React.FC = () => {
209152
<Projectiles projectiles={projectiles} />
210153

211154
{/* UI Elements */}
212-
<Score score={score} level={level} />
155+
<Score score={score} />
213156
<GameOver visible={isGameOver} />
214157
<LevelUp
215-
visible={isLevelingUp}
216-
choices={levelUpChoices}
217-
onSelect={selectUpgrade}
158+
visible={showLevelUp}
159+
upgrades={upgrades}
160+
onSelect={handleSelectUpgrade}
218161
/>
219162
</Layer>
220163
</Stage>

src/components/game/gameUtils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { Position, Direction, Enemy, Projectile } from '../../types/types';
1+
import { Position, Direction, Projectile } from '../../types/types';
22
import {
33
STAGE_WIDTH,
44
STAGE_HEIGHT,
55
ENEMY_SIZE,
6-
PLAYER_SIZE,
76
PROJECTILE_SIZE
87
} from '../../game/constants';
98
import { randomRange, clamp } from '../../utils/mathUtils';

src/components/game/useEnemySystem.ts

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState, useEffect, useRef, useCallback } from 'react';
22
import { Enemy, Position } from '../../types/types';
3-
import { ENEMY_SPEED, ENEMY_SIZE, SPAWN_INTERVAL, ENEMY_INITIAL_HEALTH } from '../../game/constants';
3+
import { ENEMY_SPEED, SPAWN_INTERVAL, ENEMY_INITIAL_HEALTH } from '../../game/constants';
44
import { generateSpawnPosition, calculateApproachVector } from './gameUtils';
55
import { clamp } from '../../utils/mathUtils';
66

@@ -11,11 +11,7 @@ const getUniqueEnemyId = () => globalEnemyId++;
1111
/**
1212
* Custom hook for managing enemy spawning and movement
1313
*/
14-
export const useEnemySystem = (
15-
playerPosRef: React.RefObject<Position>,
16-
isGameOver: boolean,
17-
isPaused: boolean = false
18-
) => {
14+
export const useEnemySystem = (playerPosRef: React.RefObject<Position>, isGameOver: boolean) => {
1915
const [enemies, setEnemies] = useState<Enemy[]>([]);
2016
const [score, setScore] = useState(0);
2117
const enemiesRef = useRef(enemies);
@@ -28,7 +24,7 @@ export const useEnemySystem = (
2824

2925
// Update enemy positions based on player position
3026
const updateEnemies = useCallback(() => {
31-
if (!playerPosRef.current || isGameOver || isPaused) return;
27+
if (!playerPosRef.current || isGameOver) return;
3228

3329
const currentPlayerPos = playerPosRef.current;
3430
const currentEnemies = enemiesRef.current;
@@ -51,11 +47,11 @@ export const useEnemySystem = (
5147
});
5248

5349
setEnemies(updatedEnemies);
54-
}, [playerPosRef, isGameOver, isPaused]);
50+
}, [playerPosRef, isGameOver]);
5551

5652
// Function to spawn a single enemy
5753
const spawnEnemy = useCallback(() => {
58-
if (isGameOver || isPaused) return;
54+
if (isGameOver) return;
5955

6056
const spawnPos = generateSpawnPosition();
6157

@@ -70,62 +66,44 @@ export const useEnemySystem = (
7066
]);
7167

7268
console.log('Enemy spawned, ID:', globalEnemyId - 1);
73-
}, [isGameOver, isPaused]);
69+
}, [isGameOver]);
7470

75-
// Function to manage the spawn interval
76-
const resetSpawnInterval = useCallback(() => {
77-
// Clear any existing interval
78-
if (spawnIntervalRef.current) {
79-
console.log('Cleaning up spawn interval');
80-
window.clearInterval(spawnIntervalRef.current);
81-
spawnIntervalRef.current = null;
82-
}
71+
// Set up the spawn interval
72+
useEffect(() => {
73+
console.log('Setting up enemy spawn interval');
8374

84-
// Only set up new interval if game is not over or paused
85-
if (!isGameOver && !isPaused) {
86-
console.log('Setting up enemy spawn interval');
75+
// Spawn first enemy immediately
76+
if (!isGameOver) {
77+
spawnEnemy();
78+
79+
// Set up the interval
8780
spawnIntervalRef.current = window.setInterval(() => {
8881
console.log('Spawn interval triggered');
8982
spawnEnemy();
9083
}, SPAWN_INTERVAL);
9184
}
92-
}, [isGameOver, isPaused, spawnEnemy]);
93-
94-
// Handle pause state changes
95-
useEffect(() => {
96-
if ((isPaused || isGameOver) && spawnIntervalRef.current) {
97-
// Clear the interval when game is paused or over
98-
window.clearInterval(spawnIntervalRef.current);
99-
spawnIntervalRef.current = null;
100-
} else if (!isPaused && !isGameOver && !spawnIntervalRef.current) {
101-
// Restart the interval when game is unpaused and not over
102-
resetSpawnInterval();
103-
}
104-
}, [isPaused, isGameOver, resetSpawnInterval]);
105-
106-
// Set up the spawn interval initially
107-
useEffect(() => {
108-
// Spawn first enemy immediately if not paused
109-
if (!isGameOver && !isPaused) {
110-
spawnEnemy();
111-
}
112-
113-
// Set up the interval if not paused
114-
resetSpawnInterval();
11585

11686
// Return cleanup function
11787
return () => {
11888
if (spawnIntervalRef.current) {
119-
console.log('Cleaning up spawn interval on unmount');
89+
console.log('Cleaning up spawn interval');
12090
window.clearInterval(spawnIntervalRef.current);
12191
spawnIntervalRef.current = null;
12292
}
12393
};
124-
}, [spawnEnemy, isGameOver, isPaused, resetSpawnInterval]);
94+
}, [spawnEnemy, isGameOver]);
95+
96+
// Stop spawning when game is over
97+
useEffect(() => {
98+
if (isGameOver && spawnIntervalRef.current) {
99+
window.clearInterval(spawnIntervalRef.current);
100+
spawnIntervalRef.current = null;
101+
}
102+
}, [isGameOver]);
125103

126104
// Function to handle enemy damage or destruction
127105
const damageEnemy = useCallback((enemyId: number, damage: number) => {
128-
if (isGameOver || isPaused) return;
106+
if (isGameOver) return;
129107

130108
setEnemies(prev => {
131109
// Check if this enemy will be killed by the damage
@@ -142,7 +120,7 @@ export const useEnemySystem = (
142120
: enemy
143121
).filter(enemy => enemy.health > 0);
144122
});
145-
}, [isGameOver, isPaused]);
123+
}, [isGameOver]);
146124

147125
// Reset function for future use
148126
const resetEnemySystem = useCallback(() => {

0 commit comments

Comments
 (0)