diff --git a/packages/client/src/assets/images/sprites/wall.svg b/packages/client/src/assets/images/sprites/wall.svg index 0413d77..380f0dd 100644 --- a/packages/client/src/assets/images/sprites/wall.svg +++ b/packages/client/src/assets/images/sprites/wall.svg @@ -1,9 +1,9 @@ - - + + - + diff --git a/packages/client/src/components/Game/Game.tsx b/packages/client/src/components/Game/Game.tsx index 46cc8c7..dfb0664 100644 --- a/packages/client/src/components/Game/Game.tsx +++ b/packages/client/src/components/Game/Game.tsx @@ -17,7 +17,7 @@ const livesUse = 3 export const Game: React.FC = () => { const canvasRef = useRef(null) const playerRef = useRef(PLAYER_DEFAULT_PARAMS) - const enemiesRef = useRef(initializeEnemies(5)) + const enemiesRef = useRef(initializeEnemies()) const obstaclesRef = useRef(initializeObstacle()) const livesRef = useRef(livesUse) const [gameStarted, setGameStarted] = useState(false) @@ -86,9 +86,9 @@ export const Game: React.FC = () => { setIsPaused(false) isPausedRef.current = false setIsGameOver(false) - livesRef.current = livesUse - playerRef.current = PLAYER_DEFAULT_PARAMS - enemiesRef.current = initializeEnemies(5) + livesRef.current = 3 + playerRef.current = { ...PLAYER_DEFAULT_PARAMS } + enemiesRef.current = initializeEnemies() } return ( diff --git a/packages/client/src/components/Game/enemy.tsx b/packages/client/src/components/Game/enemy.tsx index 692b85f..e358723 100644 --- a/packages/client/src/components/Game/enemy.tsx +++ b/packages/client/src/components/Game/enemy.tsx @@ -1,22 +1,19 @@ -import { getRandomEdgePosition } from './utils' +import React from 'react' import { Enemy, Player } from '@/components/Game/gameTypes' -export const initializeEnemies = (numberOfEnemies: number) => { - const initialEnemies: Enemy[] = [] - for (let i = 0; i < numberOfEnemies; i++) { - // количество врагов - const { x, y } = getRandomEdgePosition(800, 600) - const enemy: Enemy = { - x, - y, - width: 30, - height: 30, - speed: 1, - direction: { x: 0, y: 0 }, - } - initialEnemies.push(enemy) - } - return initialEnemies as Enemy[] +const enemyParams = { + width: 70, + height: 70, + speed: 0, + direction: { x: 0, y: 0 }, +} + +export const initializeEnemies = (): Enemy[] => { + return [ + { ...enemyParams, x: 50, y: 55 }, + { ...enemyParams, x: 320, y: 250 }, + { ...enemyParams, x: 715, y: 60 }, + ] } export const updateEnemyPositions = ( @@ -39,5 +36,5 @@ export const updateEnemyPositions = ( } export const respawnEnemies = (enemiesRef: React.MutableRefObject) => { - enemiesRef.current = initializeEnemies(5) + enemiesRef.current = initializeEnemies() } diff --git a/packages/client/src/components/Game/gameLoop.tsx b/packages/client/src/components/Game/gameLoop.tsx index d777848..4fd92f6 100644 --- a/packages/client/src/components/Game/gameLoop.tsx +++ b/packages/client/src/components/Game/gameLoop.tsx @@ -1,5 +1,5 @@ -import { HandlePlayerHit, resetPlayerPosition } from './player' -import { updateEnemyPositions, respawnEnemies } from './enemy' +import { HandlePlayerHit } from './player' +import { updateEnemyPositions } from './enemy' import { clearCanvas, drawPlayer, drawEnemies, drawObstacles } from './utils' import { Enemy, Obstacle, Player } from '@/components/Game/gameTypes' import { detectEnemyCollision } from '@/components/Game/collision' @@ -31,16 +31,20 @@ export const gameLoop = ( drawPlayer(context, playerRef.current) drawEnemies(context, enemiesRef.current) - // Проверка на столкновения между игроком и врагами - enemiesRef.current.forEach(enemy => { - if (detectEnemyCollision(playerRef.current, enemy)) { - // Обработка столкновения: уменьшаем жизни - HandlePlayerHit( - livesRef, - handleGameOver, - () => resetPlayerPosition(playerRef), - () => respawnEnemies(enemiesRef) - ) - } - }) + const collidedEnemy = enemiesRef.current.find(enemy => + detectEnemyCollision(playerRef.current, enemy) + ) + + if (collidedEnemy) { + HandlePlayerHit( + livesRef, + handleGameOver, + () => { + playerRef.current = { ...playerRef.current, x: 400, y: 560 } + }, + () => { + enemiesRef.current = enemiesRef.current.map(e => ({ ...e })) + } + ) + } } diff --git a/packages/client/src/components/Game/obstacle.tsx b/packages/client/src/components/Game/obstacle.tsx index 3743838..9cfbf50 100644 --- a/packages/client/src/components/Game/obstacle.tsx +++ b/packages/client/src/components/Game/obstacle.tsx @@ -1,12 +1,31 @@ import { Obstacle } from '@/components/Game/gameTypes' -import { getRandomEdgePosition } from '@/components/Game/utils' export const initializeObstacle = (): Obstacle[] => { - const obstacles: Obstacle[] = [] - for (let i = 0; i < 10; i++) { - const { x, y } = getRandomEdgePosition(800, 600) - const obstacle: Obstacle = { x, y, width: 50, height: 50 } - obstacles.push(obstacle) - } - return obstacles + return [ + { x: 0, y: 0, width: 120, height: 50 }, + { x: 200, y: 0, width: 70, height: 50 }, + { x: 350, y: 0, width: 70, height: 50 }, + { x: 500, y: 0, width: 120, height: 50 }, + { x: 700, y: 0, width: 100, height: 50 }, + + { x: 0, y: 130, width: 50, height: 120 }, + { x: 130, y: 130, width: 50, height: 70 }, + { x: 260, y: 130, width: 50, height: 200 }, + { x: 390, y: 130, width: 50, height: 70 }, + { x: 520, y: 130, width: 50, height: 120 }, + { x: 650, y: 130, width: 50, height: 125 }, + + { x: 0, y: 330, width: 120, height: 50 }, + { x: 200, y: 330, width: 150, height: 50 }, + { x: 350, y: 330, width: 70, height: 50 }, + { x: 500, y: 330, width: 120, height: 50 }, + { x: 700, y: 330, width: 100, height: 100 }, + + { x: 0, y: 460, width: 50, height: 140 }, + { x: 130, y: 530, width: 50, height: 70 }, + { x: 260, y: 480, width: 50, height: 120 }, + { x: 390, y: 460, width: 50, height: 70 }, + { x: 520, y: 490, width: 50, height: 120 }, + { x: 650, y: 480, width: 50, height: 120 }, + ] } diff --git a/packages/client/src/components/Game/player.tsx b/packages/client/src/components/Game/player.tsx index c8d8683..0383a26 100644 --- a/packages/client/src/components/Game/player.tsx +++ b/packages/client/src/components/Game/player.tsx @@ -2,7 +2,7 @@ import { Player } from '@/components/Game/gameTypes' export const PLAYER_DEFAULT_PARAMS = { x: 400, - y: 300, + y: 560, width: 70, height: 70, speed: 2, @@ -31,13 +31,12 @@ export const HandlePlayerHit = ( resetPlayerPosition: () => void, respawnEnemies: () => void ) => { - const newLives = livesRef.current - 1 + livesRef.current -= 1 - if (newLives <= 0) { + if (livesRef.current <= 0) { handleGameOver() } else { - livesRef.current = newLives - resetPlayerPosition() // Сбрасываем позицию игрока - respawnEnemies() // Респавн врагов + resetPlayerPosition() + respawnEnemies() } } diff --git a/packages/client/src/components/Game/utils.tsx b/packages/client/src/components/Game/utils.tsx index 7775cc2..0939a04 100644 --- a/packages/client/src/components/Game/utils.tsx +++ b/packages/client/src/components/Game/utils.tsx @@ -70,7 +70,22 @@ export const drawObstacles = ( context: CanvasRenderingContext2D, obstacles: Obstacle[] ) => { + const SPRITE_SIZE = 50 + obstacles.forEach(obstacle => { - context.drawImage(wallSprite, obstacle.x, obstacle.y) + const horizontalCount = Math.ceil(obstacle.width / SPRITE_SIZE) + const verticalCount = Math.ceil(obstacle.height / SPRITE_SIZE) + + Array.from({ length: horizontalCount }).forEach((_, i) => { + Array.from({ length: verticalCount }).forEach((_, j) => { + const x = obstacle.x + i * SPRITE_SIZE + const y = obstacle.y + j * SPRITE_SIZE + + const width = Math.min(SPRITE_SIZE, obstacle.width - i * SPRITE_SIZE) + const height = Math.min(SPRITE_SIZE, obstacle.height - j * SPRITE_SIZE) + + context.drawImage(wallSprite, 0, 0, width, height, x, y, width, height) + }) + }) }) }