This commit is contained in:
koehr 2018-04-21 20:02:21 +02:00
commit 4e3fda1732
20 changed files with 9153 additions and 0 deletions

6
.babelrc Normal file
View file

@ -0,0 +1,6 @@
{
"presets": [
["env", { "modules": false }],
"stage-3"
]
}

9
.editorconfig Normal file
View file

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
.DS_Store
node_modules/
dist/
npm-debug.log
yarn-error.log
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln

18
README.md Normal file
View file

@ -0,0 +1,18 @@
# building-game
> A blocky, side-scrolling, building and exploration game
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
```
For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).

11
index.html Normal file
View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>building-game</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>

8368
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

35
package.json Normal file
View file

@ -0,0 +1,35 @@
{
"name": "building-game",
"description": "A blocky, side-scrolling, building and exploration game",
"version": "1.0.0",
"author": "koehr <n@koehr.in>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"seedrandom": "^2.4.3",
"vue": "^2.5.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"fast-simplex-noise": "^3.2.0",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}

29
src/App.vue Normal file
View file

@ -0,0 +1,29 @@
<template>
<div id="building-game">
<Field />
</div>
</template>
<script>
import Field from './Field'
export default {
name: 'building-game',
components: { Field },
data () {
return {
}
}
}
</script>
<style>
html,body,#app {
display: block;
width: 100vw;
background: black;
margin: 0;
padding: 0;
}
</style>

35
src/Block.vue Normal file
View file

@ -0,0 +1,35 @@
<template>
<div class="block" :class="type"></div>
</template>
<script>
export default {
name: 'block',
props: {
type: String
},
data () {
return {
}
}
}
</script>
<style>
.block {
flex: 0 0 auto;
width: 30px;
height: 30px;
background-color: #6DA956;
border: 1px solid transparent;
}
.block.air { background-color: #33A; }
.block.grass { background-color: #33A; height: 28px; border-bottom: 2px solid #0A0; }
.block.soil { background-color: #543; }
.block.gravel { background-color: #665; }
.block.stone { background-color: #555; }
.block.bedrock { background-color: #444; }
.block:hover {
border-color: rgba(255,255,255,0.2);
}
</style>

84
src/Field.vue Normal file
View file

@ -0,0 +1,84 @@
<template>
<div class="field">
<input v-keep-focussed type="text"
@keydown.down="goDown($event)"
@keydown.up="goUp($event)"
@keydown.right="x = x + 1"
@keydown.left="x = x > 0 ? x - 1 : 0"
/>
<template v-for="row in rows">
<div v-for="block in row" class="block" :class="block.type" />
</template>
</div>
</template>
<script>
import Level from './lib/level-generator'
const WIDTH = 32
const HEIGHT = 32
const level = new Level(WIDTH, HEIGHT)
export default {
name: 'field',
data () {
return {
x: 0,
y: 0
}
},
computed: {
rows () {
return level.grid(this.x, this.y)
}
},
methods: {
goDown (ev) {
if (ev.shiftKey) this.y += 32
else this.y++
},
goUp (ev) {
if (ev.shiftKey) this.y -= 32
else this.y--
this.y = Math.max(0, this.y)
}
}
}
</script>
<style>
.field {
display: flex;
flex-flow: row wrap;
width: 1024px;
margin: auto;
margin-top: calc(100vh - 1056px);
border: 16px solid #222;
}
.field > input {
position: absolute;
opacity: 0;
display: block;
width: 1px;
height: 1px;
}
.block {
flex: 0 0 auto;
width: 30px;
height: 30px;
background-color: #6DA956;
border: 1px solid transparent;
}
.block.air { background-color: #56F; }
.block.grass { background-color: #56F; height: 28px; border-bottom: 2px solid #0A0; }
.block.leaves { background-color: #383; }
.block.wood { background-color: #876; }
.block.soil { background-color: #543; }
.block.gravel { background-color: #665; }
.block.stone { background-color: #555; }
.block.bedrock { background-color: #333; }
.block.cave { background-color: #000; }
.block:hover {
border-color: rgba(255,255,255,0.2);
}
</style>

View file

@ -0,0 +1,57 @@
import SeedRng from 'seedrandom'
import FastSimplexNoise from 'fast-simplex-noise'
import * as T from './block-types'
import * as P from './block-probabilities'
import * as L from './block-levels'
export default class BlockGen {
constructor (seed = 'so freakin random') {
const simplex = new FastSimplexNoise({ random: SeedRng(seed) })
this.rand = (x, y) => 0.5 + 0.5 * simplex.raw2D(x, y)
}
block (level, column, above, before) {
if (level < L.PEAK) return this.air()
const r = Math.abs(this.rand(level, column))
if (level < L.GROUND) return this.tree(r, above)
if (level < L.ROCK) return this.ground(r, above)
if (level < L.UNDERGROUND) return this.rock(r)
return this.underground(r, above, before, level - L.UNDERGROUND)
}
// always returns air
air () {
return T.AIR
}
// returns mostly air, but sometimes starts a tree
tree (r, above) {
const peak = above === T.AIR && r < P.TREE
if (peak || above === T.WOOD) return T.WOOD
return T.AIR
}
// returns mostly soil and grass, sometimes gravel and sometimes air
ground (r, above) {
if (above === T.AIR && r < P.SOIL_HOLE) return T.AIR
if (above === T.AIR) return T.GRASS
if (above === T.WOOD) return T.SOIL
return r < P.SOIL_GRAVEL ? T.GRAVEL : T.SOIL
}
// returns mostly stones, sometimes gravel
rock (r) {
return r < P.ROCK_GRAVEL ? T.GRAVEL : T.STONE
}
// return mostly bedrock, sometimes caves, depending on the level
underground (r, above, before, level) {
if (above === T.STONE || above === T.GRAVEL) return T.BEDROCK
const a = P.CAVE / P.CAVE_MAX**2
const p = Math.min(P.CAVE, a * level**2)
if (r < p) return T.CAVE
return T.BEDROCK
}
}

4
src/lib/block-levels.js Normal file
View file

@ -0,0 +1,4 @@
export const PEAK = 24
export const GROUND = 28
export const ROCK = 32
export const UNDERGROUND = 48

View file

@ -0,0 +1,6 @@
export const TREE = 0.1
export const SOIL_HOLE = 0.3
export const SOIL_GRAVEL = 0.2
export const ROCK_GRAVEL = 0.1
export const CAVE = 0.5
export const CAVE_MAX = 250

9
src/lib/block-types.js Normal file
View file

@ -0,0 +1,9 @@
export const AIR = {type: 'air', hp: 0, damage: 0}
export const GRASS = {type: 'grass', hp: 1, damage: 0}
export const LEAVES = {type: 'leaves', hp: 1, damage: 0}
export const WOOD = {type: 'wood', hp: 5, damage: 0}
export const SOIL = {type: 'soil', hp: 2, damage: 0}
export const GRAVEL = {type: 'gravel', hp: 5, damage: 0}
export const STONE = {type: 'stone', hp: 10, damage: 0}
export const BEDROCK = {type: 'bedrock', hp: 25, damage: 0}
export const CAVE = {type: 'cave', hp: 0, damage: 0}

View file

@ -0,0 +1,55 @@
import * as T from './block-types'
import * as L from './block-levels'
import BlockGen from './block-generator'
export default class Level {
constructor (width, height) {
this._x = 0
this._y = 0
this._w = width
this._h = height
this._grid = new Array(height)
this.blockGen = new BlockGen('super random seed')
}
grid (x, y) {
this._x = x
this._y = y
this.generate()
return this._grid
}
generate () {
// TODO: caching
for (let i = 0; i < this._h; i++) {
this._grid[i] = this._row(i + this._y)
}
}
_row (level = 0) {
const row = Array(this._w)
const previousRow = this._grid[level - 1] || Array()
// first step: generate a row for the given level
for (let i = 0; i < row.length; i++) {
const above = previousRow[i]
row[i] = this.blockGen.block(level, i, above, row[i - 1])
}
// second step: add extras like tree leaves
if (level < L.GROUND && level > L.PEAK) {
for (let i = 0; i < row.length; i++) {
const above = previousRow[i]
const block = row[i]
if (block === T.WOOD && above === T.AIR) {
if (row[i - 1] === T.AIR) row[i - 1] = T.LEAVES
if (row[i + 1] === T.AIR) row[i + 1] = T.LEAVES
previousRow[i] = T.LEAVES
}
}
}
return row
}
}

14
src/main.js Normal file
View file

@ -0,0 +1,14 @@
import Vue from 'vue'
import App from './App.vue'
Vue.directive('keep-focussed', {
inserted (el, binding) {
el.focus()
el.addEventListener('blur', () => el.focus())
}
})
new Vue({
el: '#app',
render: h => h(App)
})

47
test/demo.html Normal file
View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<title>Simplex noise</title>
<style>
body, html { width: 100%; height: 100%; padding: 0; margin: 0; overflow: hidden; background: black; }
canvas { display: block; width: 1024px; height: 768px; margin: calc(50vh - 768px / 2) auto 0; border: 2px solid #333; }
</style>
<canvas></canvas>
<script src='simplex.js?8'></script>
<script>
var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = 1024;
canvas.height = 768;
var ctx = canvas.getContext('2d');
var image = ctx.createImageData(canvas.width, canvas.height);
var data = image.data;
var simplex = new SimplexNoise
function paint(data, w, h, steps = 100, threshold = 0, inverse = false) {
for (var x = 0; x < w; x++) {
for (var y = 0; y < h; y++) {
var value = simplex.noise(x / steps, y / steps);
value = 128 - 128 * value;
// value = Math.abs(256 * value);
var cell = (x + y * w) * 4;
if (threshold) value = value < threshold ? 0 : 255
if (inverse) value = 255 - value
data[cell] = value * x / y; // red
data[cell + 1] = value * y / x; // green
data[cell + 2] = 0; // blue
// data[cell] += Math.max(0, (25 - value) * 8);
data[cell + 3] = 255; // alpha.
}
}
}
console.time('simplex canvas')
paint(data, 1024, 768, 100)
console.timeEnd('simplex canvas')
ctx.fillColor = 'black';
ctx.fillRect(0, 0, 100, 100);
ctx.putImageData(image, 0, 0);
</script>

98
test/simplex.js Normal file
View file

@ -0,0 +1,98 @@
// Original from Stefan Gustavson's Java implementation,
// see http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
// ported to JavaScript by Sean McCullough
// Adapted and Ported to ES6 by Norman Köhring <nÆtkoehr.in>
const { floor, sqrt } = Math
const grad3 = [
[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],
[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],
[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]
]
const F2 = 0.5 * (sqrt(3.0) - 1.0)
const G2 = (3.0 - sqrt(3.0)) / 6.0
function dot (i, x, y) {
const g = grad3[i]
return g[0] * x + g[1] * y
}
/**
* Usage new SimplexNoise( r: { random: Callable } )
*/
const SimplexNoise = function (r = Math) {
if (!r.hasOwnProperty('random') || !r.random.call) {
throw new Error('optional first argument must contain a random function')
}
this.p = new Uint8Array(256)
for (let i = 0; i < 256; i++) this.p[i] = i
// shuffle the array
for (let i = 255; i > 0; i--) {
const n = floor((i + 1) * r.random())
const q = this.p[i]
this.p[i] = this.p[n]
this.p[n] = q
}
// To remove the need for index wrapping, double the permutation table length
this.perm = new Uint8Array(512)
this.permMod12 = new Uint8Array(512)
for (let i = 0; i < 512; i++) {
this.perm[i] = this.p[i & 255]
this.permMod12[i] = this.perm[i] % 12
}
}
SimplexNoise.prototype.noise = function (xin, yin) {
// Skew the input space to determine which simplex cell we're in
const s = (xin + yin) * F2 // Hairy factor for 2D
const i = floor(xin + s)
const j = floor(yin + s)
const t = (i + j) * G2
// The x,y distances from the unskewed cell origin
const x0 = xin - (i - t)
const y0 = yin - (j - t)
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
// Offsets for second (middle) corner of simplex in (i,j) coords
// lower triangle, XY order: (0,0)->(1,0)->(1,1)
const i1 = ~~(x0 > y0) // 1 if true, false otherwise
// upper triangle, YX order: (0,0)->(0,1)->(1,1)
const j1 = ~~(!i1) // 1 if i1 is 0, 0 otherwise
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
const x1 = x0 - i1 + G2 // Offsets for middle corner in (x,y) unskewed coords
const y1 = y0 - j1 + G2
const x2 = x0 - 1.0 + 2.0 * G2 // Offsets for last corner in (x,y) unskewed coords
const y2 = y0 - 1.0 + 2.0 * G2
// Work out the hashed gradient indices of the three simplex corners
const ii = i & 255
const jj = j & 255
const gi0 = this.permMod12[ii + this.perm[jj]]
const gi1 = this.permMod12[ii + i1 + this.perm[jj + j1]]
const gi2 = this.permMod12[ii + 1 + this.perm[jj + 1]]
// Calculate the noise contribution from the three corners
// let n0, n1, n2
const t0 = 0.5 - x0 * x0 - y0 * y0
const t1 = 0.5 - x1 * x1 - y1 * y1
const t2 = 0.5 - x2 * x2 - y2 * y2
const n0 = t0 < 0 ? 0.0 : (t0 ** 4) * dot(gi0, x0, y0) // (x,y) of grad3 used for 2D gradient
const n1 = t1 < 0 ? 0.0 : (t1 ** 4) * dot(gi1, x1, y1)
const n2 = t2 < 0 ? 0.0 : (t2 ** 4) * dot(gi2, x2, y2)
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.14805770653952 * (n0 + n1 + n2)
}
// export default SimplexNoise

178
test/simplex_orig.js Normal file
View file

@ -0,0 +1,178 @@
// Original from Stefan Gustavson's Java implementation, ported by Sean McCullough
// see http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
//
// Adapted and Ported to ES6 by Norman Köhring <nÆtkoehr.in>
/**
* You can pass in a random number generator object if you like.
* It is assumed to have a random() method.
*/
var SimplexNoise = function(r) {
if (r == undefined) r = Math;
this.grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],
[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],
[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]];
this.p = [];
for (var i=0; i<256; i++) {
this.p[i] = Math.floor(r.random()*256);
}
// To remove the need for index wrapping, double the permutation table length
this.perm = [];
for(var i=0; i<512; i++) {
this.perm[i]=this.p[i & 255];
}
// A lookup table to traverse the simplex around a given point in 4D.
// Details can be found where this table is used, in the 4D noise method.
this.simplex = [
[0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0],
[0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0],
[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0],
[1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0],
[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],
[2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0],
[2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]];
};
SimplexNoise.prototype.dot = function(g, x, y) {
return g[0]*x + g[1]*y;
};
SimplexNoise.prototype.noise = function(xin, yin) {
var n0, n1, n2; // Noise contributions from the three corners
// Skew the input space to determine which simplex cell we're in
var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (i+j)*G2;
var X0 = i-t; // Unskew the cell origin back to (x,y) space
var Y0 = j-t;
var x0 = xin-X0; // The x,y distances from the cell origin
var y0 = yin-Y0;
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
var y1 = y0 - j1 + G2;
var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
var y2 = y0 - 1.0 + 2.0 * G2;
// Work out the hashed gradient indices of the three simplex corners
var ii = i & 255;
var jj = j & 255;
var gi0 = this.perm[ii+this.perm[jj]] % 12;
var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12;
var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12;
// Calculate the contribution from the three corners
var t0 = 0.5 - x0*x0-y0*y0;
if(t0<0) n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
}
var t1 = 0.5 - x1*x1-y1*y1;
if(t1<0) n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1);
}
var t2 = 0.5 - x2*x2-y2*y2;
if(t2<0) n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.0 * (n0 + n1 + n2);
};
// 3D simplex noise
SimplexNoise.prototype.noise3d = function(xin, yin, zin) {
var n0, n1, n2, n3; // Noise contributions from the four corners
// Skew the input space to determine which simplex cell we're in
var F3 = 1.0/3.0;
var s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var k = Math.floor(zin+s);
var G3 = 1.0/6.0; // Very nice and simple unskew factor, too
var t = (i+j+k)*G3;
var X0 = i-t; // Unskew the cell origin back to (x,y,z) space
var Y0 = j-t;
var Z0 = k-t;
var x0 = xin-X0; // The x,y,z distances from the cell origin
var y0 = yin-Y0;
var z0 = zin-Z0;
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in.
var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
if(x0>=y0) {
if(y0>=z0)
{ i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
}
else { // x0<y0
if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
}
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
// c = 1/6.
var x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
var y1 = y0 - j1 + G3;
var z1 = z0 - k1 + G3;
var x2 = x0 - i2 + 2.0*G3; // Offsets for third corner in (x,y,z) coords
var y2 = y0 - j2 + 2.0*G3;
var z2 = z0 - k2 + 2.0*G3;
var x3 = x0 - 1.0 + 3.0*G3; // Offsets for last corner in (x,y,z) coords
var y3 = y0 - 1.0 + 3.0*G3;
var z3 = z0 - 1.0 + 3.0*G3;
// Work out the hashed gradient indices of the four simplex corners
var ii = i & 255;
var jj = j & 255;
var kk = k & 255;
var gi0 = this.perm[ii+this.perm[jj+this.perm[kk]]] % 12;
var gi1 = this.perm[ii+i1+this.perm[jj+j1+this.perm[kk+k1]]] % 12;
var gi2 = this.perm[ii+i2+this.perm[jj+j2+this.perm[kk+k2]]] % 12;
var gi3 = this.perm[ii+1+this.perm[jj+1+this.perm[kk+1]]] % 12;
// Calculate the contribution from the four corners
var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
if(t0<0) n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0, z0);
}
var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
if(t1<0) n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1, z1);
}
var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
if(t2<0) n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2, z2);
}
var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
if(t3<0) n3 = 0.0;
else {
t3 *= t3;
n3 = t3 * t3 * this.dot(this.grad3[gi3], x3, y3, z3);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to stay just inside [-1,1]
return 32.0*(n0 + n1 + n2 + n3);
};

78
webpack.config.js Normal file
View file

@ -0,0 +1,78 @@
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
}, {
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}