Skip to content
This repository has been archived by the owner on Oct 18, 2019. It is now read-only.

Commit

Permalink
Path generation algorithm. Playing audio on click.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryuno-Ki committed Sep 9, 2018
1 parent d6359cc commit 2204140
Show file tree
Hide file tree
Showing 28 changed files with 495 additions and 247 deletions.
1 change: 1 addition & 0 deletions rollup.config.js
Expand Up @@ -49,6 +49,7 @@ export default {
copy({
'./src/game.css': './tmp/game.css',
'./src/vendor/kontra.js': './tmp/kontra.js',
'./src/assets/dial-up-sound.mp3': './dist/dial-up-sound.mp3',
'./src/assets/tileset.png': './dist/tileset.png'
}),

Expand Down
Binary file added src/assets/dial-up-sound.mp3
Binary file not shown.
Binary file added src/assets/dial-up-sound.ogg
Binary file not shown.
Binary file modified src/assets/tileset.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/tileset.xcf
Binary file not shown.
1 change: 1 addition & 0 deletions src/game.css
Expand Up @@ -10,4 +10,5 @@ body {

#game {
background-color: #eee;
cursor: pointer;
}
2 changes: 1 addition & 1 deletion src/index.js
Expand Up @@ -18,7 +18,7 @@ loadAssets().then(() => {

store.setState({ loaded: true })
// For debugging
setTimeout(() => { loop.stop() }, 300)
setTimeout(() => { loop.stop() }, 100)
}).catch((error) => {
console.error('Could not initialise, because', error)
})
4 changes: 4 additions & 0 deletions src/render.js
@@ -1,8 +1,12 @@
import createSwitchesSprite from './sprites/switches'
import tilesets from './tilesets'

const render = function () {
const tiles = tilesets()
tiles.render()

const switches = createSwitchesSprite(32 * 8, 32 * 9)
switches.render()
}

export default render
4 changes: 3 additions & 1 deletion src/sprites/index.js
@@ -1,10 +1,12 @@
/* global kontra */
const assets = [
'tileset.png'
'tileset.png',
'dial-up-sound.mp3'
]

function loadAssets () {
kontra.assets.imagePath = './'
kontra.assets.audioPath = './'
const loadedAssets = kontra.assets.load(...assets)
return loadedAssets
}
Expand Down
49 changes: 8 additions & 41 deletions src/sprites/switches.js
@@ -1,49 +1,16 @@
/* global kontra */
function renderSprite (self, active) {
const NUMBER_OF_IMAGES_ON_SPRITE = 3
const LEFT = 0
const MIDDLE = 1
const RIGHT = 2
const { context, image, height, width, x, y } = self

// Subimage values
const sy = y
const sWidth = width / NUMBER_OF_IMAGES_ON_SPRITE
const sHeight = height

// Destination values
const dx = x
const dy = y
const dWidth = sWidth
const dHeight = sHeight

let sx
// Determine, which sprite on spritesheet to display
if (active === true) {
sx = LEFT * sWidth
} else if (active === false) {
sx = RIGHT * sWidth
} else {
sx = MIDDLE * sWidth
}

setTimeout(() => {
// Draw whole spritesheet for debugging
// context.drawImage(image, dx, dy, dWidth, dHeight)
context.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
}, 0)
}

function createSwitchesSprite (x, y, active) {
function createSwitchesSprite (x, y) {
const spriteOptions = {
x: x || 0,
y: y || 0,
image: kontra.assets.images.Switch,
type: 'Switch'
x,
y,
color: 'transparent',
height: 32,
width: 32,
type: 'switch'
}

spriteOptions.render = function () { renderSprite(this, active) }
const sprite = kontra.sprite(spriteOptions)
kontra.pointer.track(sprite)
return sprite
}

Expand Down
10 changes: 10 additions & 0 deletions src/tilesets/constraints.js
@@ -0,0 +1,10 @@
const constraints = {
edges: [{
canConnectToTop: false,
canConnectToRight: false,
canConnectToBottom: false,
canConnectToLeft: false
}]
}

export default constraints
112 changes: 6 additions & 106 deletions src/tilesets/index.js
@@ -1,107 +1,6 @@
/* global kontra */
import generate from 'maze'
import neighborsByType from './neighbors'

const { abs, floor, random } = Math
const numberOfTilesInRow = 10
const numberOfTilesInCol = 10

/**
* Returns a random integer between min (inclusive) and max (inclusive)
* Using Math.round() will give you a non-uniform distribution!
* @private
*/
const getRandomInt = function (min, max) {
return floor(random() * (max - min + 1)) + min
}

/**
* Builds up the grid used for the computation of the maze
* @private
*/
const computeGrid = function () {
const lengthOfGrid = numberOfTilesInRow * numberOfTilesInCol
const emptyGrid = new Array(lengthOfGrid)
const grid = emptyGrid.fill(0).map((cell, index) => {
const x = index % numberOfTilesInRow
const y = (index - x) / numberOfTilesInRow
const numberOfTileTypes = 16
const value = getRandomInt(1, numberOfTileTypes)
return {
x,
y,
value
}
})
return grid
}

/**
* Determine, whether two cells are next to each other
* @private
*/
const adjacent = function (first, second) {
const fx = first.x
const fy = first.y
const fv = first.value + 1 // Values are indexed by 1
const sx = second.x
const sy = second.y
const sv = second.value + 1 // Values are indexed by 1
console.log('Position', fx, fy, sx, sy)

const rowDistance = sx - fx
const colDistance = sy - fy
const sameRow = rowDistance === 0
const sameCol = colDistance === 0
console.log('Shared row or column', sameRow, sameCol)

const isAbove = sameRow && colDistance === 1
const isBelow = sameRow && colDistance === -1
const isRight = sameCol && rowDistance === 1
const isLeft = sameCol && rowDistance === -1
const allowedNeighbors = neighborsByType[ sv ]
console.log('Adjacent', isAbove, isBelow, isRight, isLeft)
console.log('Neighbors', allowedNeighbors)

if (isAbove) {
return allowedNeighbors[ 't' ].includes(fv)
} else if (isRight) {
return allowedNeighbors[ 'r' ].includes(fv)
} else if (isBelow) {
return allowedNeighbors[ 'b' ].includes(fv)
} else if (isLeft) {
return allowedNeighbors[ 'l' ].includes(fv)
}
return false
}

/**
* Pick an element from array
* @private
*/
const choose = function (array) {
return array[ floor(random() * array.length) ]
}

/**
* Transforms the computed maze to a structure for kontra
* @private
*/
const transformMapToArray = function (mazeMap) {
const mazeNestedArray = Array.from(mazeMap)
const mazeArray = mazeNestedArray.map((cell) => {
const [ node, neighbors ] = cell
return node.value
})
return mazeArray
}

const getLayerData = function () {
const nodes = computeGrid()
const mazeMap = generate(nodes, adjacent, choose)
const data = transformMapToArray(mazeMap)
return data
}
import maze from './maze'
import sizes from './sizes'

const ground = function (tileEngine) {
const level = 1 // TODO: Read from store
Expand All @@ -112,16 +11,17 @@ const ground = function (tileEngine) {
tileEngine.addLayers({
name: 'ground',
zIndex: level * 10,
data: getLayerData()
data: maze()
})
}

const tilesets = function () {
const { rows, cols } = sizes
const tileEngine = kontra.tileEngine({
tileHeight: 32,
tileWidth: 32,
height: numberOfTilesInCol,
width: numberOfTilesInRow
height: rows,
width: cols
})
ground(tileEngine)
return tileEngine
Expand Down
46 changes: 46 additions & 0 deletions src/tilesets/maze/index.js
@@ -0,0 +1,46 @@
import sizes from '../sizes'
import modem from './modem'
import path from './path'
import pc from './pc'
import servers from './servers'
import switches from './switches'
import xyToIndex from './xyToIndex'

const getFixedTiles = function () {
const withModem = modem()
const withPc = pc()
const withSwitch = switches()
const withServer = servers()
const prefilledMaze = [
...withModem,
...withPc,
...withSwitch,
...withServer
]
return prefilledMaze
}

const generateMaze = function () {
const { rows, cols } = sizes
const emptyMaze = new Array(rows * cols)
const generatedMaze = emptyMaze.fill(0)
const maze = getFixedTiles()

maze.forEach((entry) => {
const { x, y, value } = entry
const index = xyToIndex(x, y)
generatedMaze[ index ] = value
})

path(generatedMaze)
return generatedMaze
}


const maze = function () {
const generatedMaze = generateMaze()
console.log('Generated maze', generatedMaze)
return generatedMaze
}

export default maze
12 changes: 12 additions & 0 deletions src/tilesets/maze/indexToXY.js
@@ -0,0 +1,12 @@
import sizes from '../sizes'

// index start at 0
// x and y start at 1
const indexToXY = function (index) {
const { cols } = sizes
const x = 1 + (index % cols)
const y = 1 + (index - (x - 1)) / cols
return { x, y }
}

export default indexToXY
16 changes: 16 additions & 0 deletions src/tilesets/maze/isAllowedUnsetIndex.js
@@ -0,0 +1,16 @@
import sizes from '../sizes'

const isAllowedUnsetIndex = function (maze, index) {
const { rows, cols } = sizes
const lowerLimit = 0
const upperLimit = rows * cols

const unsetTiles = [ 0, 9, 10, 11 ]
const id = maze[ index ]

const isWithinLimits = index >= lowerLimit && index < upperLimit
const isNotSetYet = unsetTiles.includes(id)
return isWithinLimits && isNotSetYet
}

export default isAllowedUnsetIndex
15 changes: 15 additions & 0 deletions src/tilesets/maze/modem.js
@@ -0,0 +1,15 @@
import sizes from '../sizes'

const modem = function () {
const { rows, cols } = sizes

const modemValue = 16
const modemTile = {
x: cols,
y: rows - 1,
value: modemValue
}
return [ modemTile ]
}

export default modem
55 changes: 55 additions & 0 deletions src/tilesets/maze/nextDirection.js
@@ -0,0 +1,55 @@
import neighbors from '../neighbors'
import randomPick from '../randomPick'
import indexToXY from './indexToXY'
import isAllowedUnsetIndex from './isAllowedUnsetIndex'
import xyToIndex from './xyToIndex'

const pickNextDirection = function (possibleDirections, options) {
const numberOfDirections = possibleDirections.length
const moreData = options || {}
let index

if (numberOfDirections === 0) {
throw new Error('No directions to choose from!')
}

if (numberOfDirections === 1) {
index = possibleDirections[ 0 ]
} else {
// TODO: Pick the closest direction towards end
// index = randomPick(possibleDirections)
index = possibleDirections[ 0 ]
}

return {
index,
...moreData
}
}

const nextDirection = function (maze, current) {
const currentIndex = current.index
const currentId = current.id
const { x, y } = indexToXY(currentIndex)

const connections = neighbors.find((neighbor) => neighbor.id === currentId)
const { toTop, toRight, toBottom, toLeft } = connections

const allDirections = []
if (toTop) { allDirections.push(xyToIndex(x, y - 1)) }
if (toRight) { allDirections.push(xyToIndex(x + 1, y )) }
if (toBottom) { allDirections.push(xyToIndex(x, y + 1)) }
if (toLeft) { allDirections.push(xyToIndex(x - 1, y )) }

const possibleDirections = allDirections
.filter((index) => isAllowedUnsetIndex(maze, index))

return pickNextDirection(possibleDirections, {
toTop: toTop && toBottom ? true : !toTop,
toRight: toLeft && toRight ? true : !toRight,
toBottom: toTop && toBottom ? true : !toBottom,
toLeft: toLeft && toRight ? true : !toLeft
})
}

export default nextDirection

0 comments on commit 2204140

Please sign in to comment.