Skip to content

Commit

Permalink
feature: finishing the game
Browse files Browse the repository at this point in the history
  • Loading branch information
radzionc committed Jul 5, 2019
1 parent 1b35972 commit 3300120
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 5 deletions.
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@
"name": "breakout-game",
"version": "0.1.0",
"private": true,
"homepage": "https://rodionchachura.github.io/breakout-game",
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
"devDependencies": {
"gh-pages": "^2.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
95 changes: 91 additions & 4 deletions src/components/scene.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import React, { useReducer } from 'react'
import React, { useEffect, useReducer } from 'react'

import { LEVELS } from '../game/levels'
import { getGameStateFromLevel } from '../game/core'
import { MOVEMENT, getNewGameState, getGameStateFromLevel } from '../game/core'
import { registerListener } from '../utils'

import Level from './level'
import Lives from './lives'
import Block from './block'
import Paddle from './paddle'
import Ball from './ball'

const MOVEMENT_KEYS = {
LEFT: [65, 37],
RIGHT: [68, 39]
}

const STOP_KEY = 32

const UPDATE_EVERY = 1000 / 60

const getInitialLevel = () => {
const inState = localStorage.getItem('level')
return inState ? parseInt(inState, 10) : 0
Expand Down Expand Up @@ -41,10 +51,70 @@ const getInitialState = containerSize => {
}
}

const reducer = state => state
const ACTION = {
CONTAINER_SIZE_CHANGE: 'CONTAINER_SIZE_CHANGE',
KEY_DOWN: 'KEY_DOWN',
KEY_UP: 'KEY_UP',
TICK: 'TICK'
}

const HANDLER = {
[ACTION.CONTAINER_SIZE_CHANGE]: (state, containerSize) => ({
...state,
containerSize,
...getProjectors(containerSize, state.game.size)
}),
[ACTION.KEY_DOWN]: (state, key) => {
if (MOVEMENT_KEYS.LEFT.includes(key)) {
return { ...state, movement: MOVEMENT.LEFT }
} else if (MOVEMENT_KEYS.RIGHT.includes(key)) {
return { ...state, movement: MOVEMENT.RIGHT }
}
return state
},
[ACTION.KEY_UP]: (state, key) => {
const newState = { ...state, movement: undefined }
if (key === STOP_KEY) {
if (state.stopTime) {
return { ...newState, stopTime: undefined, time: state.time + Date.now() - state.stopTime}
} else {
return { ...newState, stopTime: Date.now() }
}
}
return newState
},
[ACTION.TICK]: state => {
if (state.stopTime) return state

const time = Date.now()
const newGame = getNewGameState(state.game, state.movement, time - state.time)
const newState = { ...state, time }
if (newGame.lives < 1) {
return { ...newState, game: getGameStateFromLevel(LEVELS[state.level]) }
} else if (newGame.blocks.length < 1) {
const level = state.level === LEVELS.length ? state.level : state.level + 1
localStorage.setItem('level', level)
const game = getGameStateFromLevel(LEVELS[state.level])
return {
...newState,
level,
game,
...getProjectors(state.containerSize, game.size)
}
}
return { ...newState, game: newGame }
}
}

const reducer = (state, { type, payload }) => {
const handler = HANDLER[type]
if (!handler) return state
return handler(state, payload)
}

export default (containerSize) => {
const [state] = useReducer(reducer, containerSize, getInitialState)
const [state, dispatch] = useReducer(reducer, containerSize, getInitialState)
const act = (type, payload) => dispatch({ type, payload })
const {
projectDistance,
projectVector,
Expand All @@ -61,6 +131,23 @@ export default (containerSize) => {
}
} = state

useEffect(() => act(ACTION.CONTAINER_SIZE_CHANGE, containerSize), [containerSize])

useEffect(() => {
const onKeyDown = ({ which }) => act(ACTION.KEY_DOWN, which)
const onKeyUp = ({ which }) => act(ACTION.KEY_UP, which)
const tick = () => act(ACTION.TICK)

const timerId = setInterval(tick, UPDATE_EVERY)
const unregisterKeydown = registerListener('keydown', onKeyDown)
const unregisterKeyup = registerListener('keyup', onKeyUp)
return () => {
clearInterval(timerId)
unregisterKeydown()
unregisterKeyup()
}
}, [])

const viewWidth = projectDistance(width)
const unit = projectDistance(ball.radius)
return (
Expand Down

0 comments on commit 3300120

Please sign in to comment.