2d game with map data
https://luna-development.net/2dgame/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
7.1 KiB
255 lines
7.1 KiB
const Game = new Vue({ |
|
el: '#root', |
|
data: { |
|
map : [], |
|
viewAbleMap : [], |
|
player: { |
|
facing: 'down', |
|
isWalking: false, |
|
coolDownRunning: false, |
|
position: { |
|
x: 7, |
|
y: 7 |
|
} |
|
}, |
|
importJson: null, |
|
leftStep: false, |
|
currentMessage: null |
|
}, |
|
created() { |
|
let game = this; |
|
|
|
axios.get('maps/town.json').then((response) => { |
|
game.map = response.data; |
|
}); |
|
}, |
|
mounted() { |
|
this.generateMap(15, 15) |
|
}, |
|
methods: { |
|
generateMap(rowCount, tilesPerRow, importJson = null) { |
|
this.map = []; |
|
for (let rows = 0; rows < rowCount; rows++) { |
|
let newRow = []; |
|
|
|
for (let tiles = 0; tiles < tilesPerRow; tiles++) { |
|
let sprite = 'img/tiles/city_paths/tile_888.png'; |
|
|
|
if (importJson) { |
|
sprite = this.importJson[rows][tiles] ?? 'img/tiles/city_paths/tile_888.png'; |
|
} |
|
|
|
let newTile = { |
|
mapX: rows, |
|
mapY: tiles, |
|
sprite: sprite, |
|
isWalkable: true |
|
}; |
|
|
|
newRow.push(newTile); |
|
} |
|
|
|
this.map.push(newRow); |
|
} |
|
|
|
this.viewAbleMap = this.map; |
|
}, |
|
getTileStyle(tile) { |
|
if (!this.map[tile.mapX] || !this.map[tile.mapX][tile.mapY]) { |
|
return false; |
|
} |
|
|
|
let sprite = this.map[tile.mapX][tile.mapY]; |
|
return 'background-image: url("'+sprite.sprite+'");'; |
|
}, |
|
shiftMap(direction) { |
|
let game = this; |
|
|
|
if (this.player.facing !== direction) { |
|
this.player.facing = direction; |
|
return true; |
|
} |
|
|
|
if (this.player.coolDownRunning) { |
|
return false; |
|
} |
|
|
|
if (!this.getTargetTile() || !this.getTargetTile().isWalkable) { |
|
console.warn('collision detected'); |
|
return false; |
|
} |
|
|
|
this.startWalkCooldown(); |
|
this.updatePlayerPosition(direction); |
|
this.leftStep = !this.leftStep; |
|
|
|
this.player.isWalking = true; |
|
this.player.facing = direction; |
|
|
|
game.viewAbleMap.forEach((mapRow) => { |
|
mapRow.forEach((tile) => { |
|
if (direction === 'up') { |
|
tile.mapX--; |
|
} |
|
|
|
if (direction === 'down') { |
|
tile.mapX++; |
|
} |
|
|
|
if (direction === 'left') { |
|
tile.mapY--; |
|
} |
|
|
|
if (direction === 'right') { |
|
tile.mapY++; |
|
} |
|
}); |
|
}); |
|
}, |
|
updatePlayerPosition(direction) { |
|
let game = this; |
|
|
|
if (direction === 'up') { |
|
game.player.position.x--; |
|
} |
|
|
|
if (direction === 'down') { |
|
game.player.position.x++; |
|
} |
|
|
|
if (direction === 'right') { |
|
game.player.position.y--; |
|
} |
|
|
|
if (direction === 'left') { |
|
game.player.position.y++; |
|
} |
|
}, |
|
getPlayerSprite() { |
|
let step = ''; |
|
|
|
if (this.leftStep && this.player.isWalking) { |
|
step = '_0'; |
|
} else if (!this.leftStep && this.player.isWalking) { |
|
step = '_1'; |
|
} |
|
|
|
return 'img/sprites/' + this.player.facing + step + '.png'; |
|
}, |
|
getNpcSprite(tile) { |
|
console.log(tile); |
|
return 'img/npcs/' + tile.npc.spriteset + '/' + tile.npc.facing + '.png'; |
|
}, |
|
startWalkCooldown() { |
|
let game = this; |
|
game.player.coolDownRunning = true; |
|
setTimeout(() => { |
|
game.player.coolDownRunning = false; |
|
}, 200); |
|
}, |
|
action() { |
|
let targetTile = this.getTargetTile(); |
|
|
|
if (!targetTile.npc) { |
|
console.log('no action found'); |
|
return false; |
|
} |
|
|
|
if (targetTile.npc) { |
|
if (this.currentMessage) { |
|
if (targetTile.npc.text[this.currentMessage.counter+1]) { |
|
this.currentMessage = { |
|
counter: this.currentMessage.counter+1, |
|
text: targetTile.npc.text[this.currentMessage.counter+1] |
|
}; |
|
} else { |
|
this.currentMessage = null; |
|
} |
|
} else { |
|
this.currentMessage = { |
|
counter: 0, |
|
text: targetTile.npc.text[0] |
|
}; |
|
} |
|
} |
|
}, |
|
getTargetTile() { |
|
let targetTile = this.map[this.player.position.x][this.player.position.y]; |
|
|
|
if (this.player.facing === 'down') { |
|
targetTile = this.map[this.player.position.x+1][this.player.position.y]; |
|
} |
|
|
|
if (this.player.facing === 'up') { |
|
targetTile = this.map[this.player.position.x-1][this.player.position.y]; |
|
} |
|
|
|
if (this.player.facing === 'left') { |
|
targetTile = this.map[this.player.position.x][this.player.position.y+1]; |
|
} |
|
|
|
if (this.player.facing === 'right') { |
|
targetTile = this.map[this.player.position.x][this.player.position.y-1]; |
|
} |
|
|
|
return targetTile; |
|
} |
|
}, |
|
computed: {}, |
|
watch: { |
|
importJson() { |
|
this.importJson = JSON.parse(this.importJson); |
|
this.generateMap(15, 15, true) |
|
}, |
|
leftStep() { |
|
let audio = new Audio('audio/footstep01.ogg'); |
|
if (this.leftStep) { |
|
let audio = new Audio('audio/footstep00.ogg'); |
|
} |
|
|
|
audio.volume = 0.1; |
|
audio.play(); |
|
} |
|
} |
|
}); |
|
|
|
|
|
// Check for Keypress |
|
jQuery(document).keydown(function (e) { |
|
switch (e.keyCode) { |
|
// W, UP |
|
case 87: |
|
case 38: |
|
Game.shiftMap('up'); |
|
break; |
|
|
|
// A, LEFT |
|
case 65: |
|
case 37: |
|
Game.shiftMap('left'); |
|
break; |
|
|
|
// S, DOWN |
|
case 83: |
|
case 40: |
|
Game.shiftMap('down'); |
|
break; |
|
// D, RIGHT |
|
case 68: |
|
case 39: |
|
Game.shiftMap('right'); |
|
break; |
|
|
|
case 32: |
|
Game.action(); |
|
break; |
|
|
|
// do nothing |
|
default: |
|
break; |
|
} |
|
}); |
|
|
|
jQuery(document).keyup(function (e) { |
|
Game.player.isWalking = false; |
|
});
|
|
|