clean up field component, make jumps more "realistic"

main
koehr 6 years ago
parent 062d249d00
commit 54f352c577

47
package-lock.json generated

@ -2783,6 +2783,7 @@
"version": "0.0.9",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"inherits": "~2.0.0"
}
@ -2807,7 +2808,8 @@
"buffer-shims": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"caseless": {
"version": "0.12.0",
@ -2824,12 +2826,14 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"combined-stream": {
"version": "1.0.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@ -2842,17 +2846,20 @@
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"cryptiles": {
"version": "2.0.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"boom": "2.x.x"
}
@ -2892,7 +2899,8 @@
"delayed-stream": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"delegates": {
"version": "1.0.0",
@ -2924,7 +2932,8 @@
"extsprintf": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"forever-agent": {
"version": "0.6.1",
@ -3047,6 +3056,7 @@
"version": "3.1.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"boom": "2.x.x",
"cryptiles": "2.x.x",
@ -3094,6 +3104,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "1.0.1"
}
@ -3107,7 +3118,8 @@
"isarray": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"isstream": {
"version": "0.1.2",
@ -3180,12 +3192,14 @@
"mime-db": {
"version": "1.27.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"mime-types": {
"version": "2.1.15",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"mime-db": "1.27.0"
}
@ -3261,7 +3275,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"oauth-sign": {
"version": "0.8.2",
@ -3319,7 +3334,8 @@
"process-nextick-args": {
"version": "1.0.7",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"punycode": {
"version": "1.4.1",
@ -3357,6 +3373,7 @@
"version": "2.2.9",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"buffer-shims": "~1.0.0",
"core-util-is": "~1.0.0",
@ -3408,7 +3425,8 @@
"safe-buffer": {
"version": "5.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"semver": {
"version": "5.3.0",
@ -3432,6 +3450,7 @@
"version": "1.0.9",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"hoek": "2.x.x"
}
@ -3465,6 +3484,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -3475,6 +3495,7 @@
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.0.1"
}
@ -3503,6 +3524,7 @@
"version": "2.2.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"block-stream": "*",
"fstream": "^1.0.2",
@ -3558,7 +3580,8 @@
"util-deprecate": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"uuid": {
"version": "3.0.1",

@ -1,14 +1,12 @@
<template>
<div id="field" :class="daytimeClass">
<input v-keep-focussed type="text"
@keydown.up="player_velocity_y = -8"
@keydown.down="player_velocity_y = 8"
@keydown.up="jump = jump ? jump : 16"
@keydown.right="player_velocity_x = 8"
@keydown.left="player_velocity_x = -8"
@keyup.up="player_velocity_y = 8"
@keyup.down="player_velocity_y = 8"
@keyup.right="player_velocity_x = 0"
@keyup.left="player_velocity_x = 0"
@keypress.p="togglePause"
/>
<mountain-background :x="128 + x / 8" :time="time" />
<div id="wrap" :style="{transform: `translate(${tx}px, ${ty}px)`}">
@ -17,13 +15,18 @@
</template>
</div>
<div id="player" :class="[player_direction]" />
<div id="level-indicator">x:{{ floorX }}, y:{{ floorY }} ({{clock}})</div>
<div id="level-indicator">
x:{{ floorX }}, y:{{ floorY }}
<template v-if="moving !== false">({{clock}})</template>
<template v-else>(PAUSED)</template>
</div>
</div>
</template>
<script>
// import throttle from 'lodash/throttle'
import Level from './level'
import Player from './player'
import MountainBackground from './Background'
const BLOCK_SIZE = 32
@ -42,7 +45,8 @@ export default {
y: 0,
player_direction: 'left',
player_velocity_x: 0,
player_velocity_y: 9,
player_velocity_y: 8,
jump: 0,
gravity: 8.0 / 20,
moving: false,
time: 250
@ -62,22 +66,30 @@ export default {
}
},
computed: {
blockAtPlayer () { return this.rows[PLAYER_Y][PLAYER_X] },
blockLeftOfPlayer () { return this.rows[PLAYER_Y][PLAYER_X - 1] },
blockRightOfPlayer () { return this.rows[PLAYER_Y][PLAYER_X + 1] },
blockAbovePlayer () { return this.rows[PLAYER_Y - 1][PLAYER_X] },
blockBelowPlayer () { return this.rows[PLAYER_Y + 1][PLAYER_X] },
blockedUp () { return !this.blockAbovePlayer.walkable },
blockedDown () { return !this.blockBelowPlayer.walkable },
blockedLeft () { return !this.blockLeftOfPlayer.walkable },
blockedRight () { return !this.blockRightOfPlayer.walkable },
rows () { return level.grid(this.floorX, this.floorY) },
surroundings () {
const at = this.rows[PLAYER_Y][PLAYER_X]
const left = this.rows[PLAYER_Y][PLAYER_X - 1]
const right = this.rows[PLAYER_Y][PLAYER_X + 1]
const above = this.rows[PLAYER_Y - 1][PLAYER_X]
const below = this.rows[PLAYER_Y + 1][PLAYER_X]
const blocked = {
at: !at.walkable,
left: !left.walkable,
right: !right.walkable,
above: !above.walkable,
below: !below.walkable
}
return { at, left, right, below, blocked }
},
cornerX () { return this.x === ~~this.x }, // cornering a block
cornerY () { return this.y === ~~this.y },
floorX () { return Math.floor(this.x) },
floorY () { return Math.floor(this.y) },
tx () { return (this.x - this.floorX) * -BLOCK_SIZE },
ty () { return (this.y - this.floorY) * -BLOCK_SIZE },
rows () { return level.grid(this.floorX, this.floorY) },
daytimeClass () {
const t = this.time
if (t >= 900 || t < 80) return "night"
@ -109,46 +121,40 @@ export default {
// this.player_velocity_y += this.gravity
let vx = this.player_velocity_x * RECIPROCAL
let vy = this.player_velocity_y * RECIPROCAL
let vy = (this.player_velocity_y - this.jump) * RECIPROCAL
if (this.jump > 0) this.jump--
// change player graphic according to direction
if (vx < 0) this.player_direction = 'left'
if (vx > 0) this.player_direction = 'right'
// don't walk / fall into blocks
if (vx > 0 && this.blockedRight) vx = 0
if (vx < 0 && this.blockedLeft) vx = 0
if (vy > 0 && this.blockedDown) {
// jump to the top of the block
vy = -((~~y + 1) - y) + 1
// vy = 0
}
if (vy < 0 && this.blockedUp) vy = 0
const { blocked } = this.surroundings
if (vx > 0 && blocked.right) vx = 0
if (vx < 0 && blocked.left) vx = 0
if (vy > 0 && blocked.below) vy = 0
if (vy < 0 && blocked.above) vy = 0
this.x += vx
this.y += vy
this.moving = setTimeout(() => this.move(), 50)
this.moving = setTimeout(() => this.move(), 64) // roughly every 4 frames
},
togglePause () {
if (this.moving === false) { // is paused
this.moving = true // avoid (unlikely) race condition
this.move()
} else {
clearTimeout(this.moving)
this.moving = false
}
}
}
}
</script>
<style src="./assets/field.css" />
<style>
#field {
position: relative;
width: 1024px;
height: 1024px;
margin: auto;
overflow: hidden;
background-color: #56F;
}
#field > input {
position: absolute;
opacity: 0;
display: block;
width: 1px;
height: 1px;
}
#level-indicator {
position: absolute;
top: 0;
@ -183,49 +189,4 @@ export default {
display: flex;
flex-flow: row wrap;
}
.block.grass { background-image: url(./assets/grass01.png); }
.block.tree_top_left { background-image: url(./assets/tree_top_left.png); }
.block.tree_top_middle { background-image: url(./assets/tree_top_middle.png); }
.block.tree_top_right { background-image: url(./assets/tree_top_right.png); }
.block.tree_crown_left { background-image: url(./assets/tree_crown_left.png); }
.block.tree_crown_middle { background-image: url(./assets/tree_crown_middle.png); }
.block.tree_crown_right { background-image: url(./assets/tree_crown_right.png); }
.block.tree_trunk_left { background-image: url(./assets/tree_trunk_left.png); }
.block.tree_trunk_middle { background-image: url(./assets/tree_trunk_middle.png); }
.block.tree_trunk_right { background-image: url(./assets/tree_trunk_right.png); }
.block.tree_root_left { background-image: url(./assets/tree_root_left.png); }
.block.tree_root_middle { background-image: url(./assets/tree_root_middle.png); }
.block.tree_root_right { background-image: url(./assets/tree_root_right.png); }
.block.tree_top_left_mixed { background-image: url(./assets/tree_top_left_mixed.png); }
.block.tree_crown_left_mixed { background-image: url(./assets/tree_crown_left_mixed.png); }
.block.tree_trunk_left_mixed { background-image: url(./assets/tree_trunk_left_mixed.png); }
.block.tree_root_left_mixed { background-image: url(./assets/tree_root_left_mixed.png); }
.block.tree_top_right_mixed { background-image: url(./assets/tree_top_right_mixed.png); }
.block.tree_crown_right_mixed { background-image: url(./assets/tree_crown_right_mixed.png); }
.block.tree_trunk_right_mixed { background-image: url(./assets/tree_trunk_right_mixed.png); }
.block.tree_root_right_mixed { background-image: url(./assets/tree_root_right_mixed.png); }
.block.soil { background-image: url(./assets/soil.png); }
.block.soil_gravel { background-image: url(./assets/soil_gravel.png); }
.block.stone_gravel { background-image: url(./assets/rock_gravel.png); }
.block.stone { background-image: url(./assets/rock.png); }
.block.bedrock { background-image: url(./assets/bedrock.png); }
.block.cave { background-color: #000; }
#field .block:hover { outline: 1px solid white; z-index: 10; }
.morning0 .block, .morning0 #player { filter: saturate(50%) brightness(0.6) hue-rotate(-10deg); }
.morning1 .block, .morning1 #player { filter: saturate(100%) brightness(0.8) hue-rotate(-20deg); }
.morning2 .block, .morning2 #player { filter: saturate(200%) hue-rotate(-30deg); }
.evening0 .block, .evening0 #player { filter: brightness(0.8) hue-rotate(-10deg); }
.evening1 .block, .evening1 #player { filter: brightness(0.6) hue-rotate(-20deg); }
.evening2 .block, .evening2 #player { filter: brightness(0.4) hue-rotate(-10deg) saturate(50%); }
.night .block, .night #player { filter: brightness(0.3) saturate(30%); }
</style>

@ -0,0 +1,60 @@
#field {
position: relative;
width: 1024px;
height: 1024px;
margin: auto;
overflow: hidden;
background-color: #56F;
}
#field > input {
position: absolute;
opacity: 0;
display: block;
width: 1px;
height: 1px;
}
.block.grass { background-image: url(./grass01.png); }
.block.tree_top_left { background-image: url(./tree_top_left.png); }
.block.tree_top_middle { background-image: url(./tree_top_middle.png); }
.block.tree_top_right { background-image: url(./tree_top_right.png); }
.block.tree_crown_left { background-image: url(./tree_crown_left.png); }
.block.tree_crown_middle { background-image: url(./tree_crown_middle.png); }
.block.tree_crown_right { background-image: url(./tree_crown_right.png); }
.block.tree_trunk_left { background-image: url(./tree_trunk_left.png); }
.block.tree_trunk_middle { background-image: url(./tree_trunk_middle.png); }
.block.tree_trunk_right { background-image: url(./tree_trunk_right.png); }
.block.tree_root_left { background-image: url(./tree_root_left.png); }
.block.tree_root_middle { background-image: url(./tree_root_middle.png); }
.block.tree_root_right { background-image: url(./tree_root_right.png); }
.block.tree_top_left_mixed { background-image: url(./tree_top_left_mixed.png); }
.block.tree_crown_left_mixed { background-image: url(./tree_crown_left_mixed.png); }
.block.tree_trunk_left_mixed { background-image: url(./tree_trunk_left_mixed.png); }
.block.tree_root_left_mixed { background-image: url(./tree_root_left_mixed.png); }
.block.tree_top_right_mixed { background-image: url(./tree_top_right_mixed.png); }
.block.tree_crown_right_mixed { background-image: url(./tree_crown_right_mixed.png); }
.block.tree_trunk_right_mixed { background-image: url(./tree_trunk_right_mixed.png); }
.block.tree_root_right_mixed { background-image: url(./tree_root_right_mixed.png); }
.block.soil { background-image: url(./soil.png); }
.block.soil_gravel { background-image: url(./soil_gravel.png); }
.block.stone_gravel { background-image: url(./rock_gravel.png); }
.block.stone { background-image: url(./rock.png); }
.block.bedrock { background-image: url(./bedrock.png); }
.block.cave { background-color: #000; }
#field .block:hover { outline: 1px solid white; z-index: 10; }
.morning0 .block, .morning0 #player { filter: saturate(50%) brightness(0.6) hue-rotate(-10deg); }
.morning1 .block, .morning1 #player { filter: saturate(100%) brightness(0.8) hue-rotate(-20deg); }
.morning2 .block, .morning2 #player { filter: saturate(200%) hue-rotate(-30deg); }
.evening0 .block, .evening0 #player { filter: brightness(0.8) hue-rotate(-10deg); }
.evening1 .block, .evening1 #player { filter: brightness(0.6) hue-rotate(-20deg); }
.evening2 .block, .evening2 #player { filter: brightness(0.4) hue-rotate(-10deg) saturate(50%); }
.night .block, .night #player { filter: brightness(0.3) saturate(30%); }
Loading…
Cancel
Save