This is my first question on this exchange so be gentle. I have looked through the "similar" questions to no avail.
I am running this script on my local machine using Opera.
My brain is seriously hurting. I'm in physical pain. I've spent literally hours racking my brain trying to find the fault in this simple (admittedly novice) code. I can't seem to figure it out. Please help me before I run out of aspirin. Yes, I'm new to JavaScript. I apologize for that as I'm sure there are many of you who will see lots of novice mistakes in this code and practices that are less than perfect. But I'm really trying to learn.
Let me explain. Below is the ENTIRE game. I've only included it because I'm really just not sure how to proceed. I've been stepping through the code line by line for hours. The only thing you'd have to do is make a few assets and this crappy game would be up and running. Except for the BUG!
The player in this little game starts in town as denoted by the default value of mapFlag aka "town".
When the player reaches predetermined coordinates on the canvas, the background image is redrawn and mapFlag switches to the new flag, etc. New music plays and all that based on this mapFlag variable.
The problem is this: The game starts. We are in town. We move to the right and the map switches to the GRASS as planned. But the moment we step back to the left again, it goes back to TOWN. The only way this should happen is if the player's X and Y coordinate are less than or equal to those in this statement:
// Grass to town
if ((px <= 20) && (py <= 20) && (mapFlag == "grass")){
mapFlag = "town";
gravestones = [];
//px=300; py=300;
ex=200; ey=200;
return;
}
which is part of my mapSwitch function. However, even though my coordinates are definitely NOT less than 20, the game still switches everything back to TOWN unexpectedly. I've tried rebuilding the mapSwitch function to use if and else if instead but it operates the same. I've commented lines here and there trying to whittle it down and the only thing I can guess is that it has something to do with my ill-planned coordinate system causing some kind of death loop. But very slowly walking through this code line by line, I just can't seem to see how my if statement above could fail? There must be more to this story that I'm just too inexperienced or tired to notice. Please help!
If it matters, I've learned a LOT of things to NOT do during this project. One is that I should not use a coordinate system with individual variables like that but instead use a JavaScript Object (or class?) I guess there's a difference. More reading ahead in my journey. I've also learned that I need to do some serious reading on how to plan the order, layout, and general structure of functions and how they all tie together.
<canvas id="board" width="620" height="720" tabindex='1'></canvas>
<script>
// Constants and variables
const cvs = document.getElementById('board').getContext('2d');;
const movUnit = 20; //one block is 10 x 10 in game
const gameSpeed = 200;
const scoreIncrease = 1;
var px = 300;
var py = 300;
var ex = 100;
var ey = 100;
var mapFlag = "town";
var gravestones = [];
var score = 0;
var movAI=0;
var playerDeaths = 0;
// Setup Objects
var player = {
x: 40,
y: 40,
};
var enemy = {
x: 100,
y: 100,
};
// Graphics
let imgPlayer = new Image();
imgPlayer.src = "img/player.png";
let imgGrass = new Image();
imgGrass.src = "img/grass.png";
let imgTown = new Image();
imgTown.src = "img/town.png";
let imgCave = new Image();
imgCave.src = "img/cave.png";
let imgScore = new Image();
imgScore.src = "img/score.png";
let enemyPlayer = new Image();
enemyPlayer.src = "img/enemy.png";
let imgGrave = new Image();
imgGrave.src = "img/grave.png";
// Load or play audio
let sndFootstep = new Audio();
sndFootstep.src ="snd/footstep.mp3";
let sndDeath = new Audio();
sndDeath.src ="snd/death.mp3";
let sndMusic = new Audio();
sndMusic.src = "snd/music.mp3";
let sndCave = new Audio();
sndCave.src = "snd/cave.mp3";
//let sndTown = new Audio();
//sndTown.src = "";
// Listener
window.addEventListener("keydown", direction);
function mapSwitch(){
// Map Switch Checks
// Home Town to Grassy
if ((px >= 560) && (py >= 350) && (py <= 380) && (mapFlag == "town")){
mapFlag = "grass";
//px=100; py=360;
ex=200; ey=200;
return;
}
// Grass to town
if ((px <= 20) && (py <= 20) && (mapFlag == "grass")){
mapFlag = "town";
gravestones = [];
//px=300; py=300;
ex=200; ey=200;
return;
}
// grass to cave
if ((px >= 560) && (py >= 560) && (mapFlag == "grass")){
mapFlag = "cave";
gravestones = [];
px=60; py=60;
ex=40; ey=40;
return;
}
// cave to grass
if ((px <= 40) && (py <= 40) && (mapFlag == "cave")){
mapFlag = "grass";
gravestones = [];
px=540; py=540;
ex=560; ey=560;
return;
}
}
function detectHit(){
// Enemy Collides with Wall
if (ex >= 580){ex = 580;}
if (ex <= 20){ex = 20;}
if (ey >= 580){ey = 580;}
if (ey <= 20){ey = 20;}
// Player Collides with Wall
if (px <= 20){px=20;}
if (py <= 20){py=20;}
if (px >= 580){px=580;}
if (py >= 580){py=580;}
// Enemy kills player
if (ex == px && ey == py && mapFlag != "town"){
sndDeath.play();
playerDeaths += 1;
score -= 50;
gravestones.push([px, py]);
px = 200; py = 200;
}
mapSwitch();
}
function enemyAI(){
// Skip Enemy AI if in town
if (mapFlag == "town"){ return; }
// Pick a random number
movAI = Math.floor(Math.random() * 8) + 1;
// Enemy AI behavior based on random number
switch (movAI){
case 1:
ex += movUnit;
break;
case 2:
ex -= movUnit;
break;
case 3:
ey += movUnit;
break;
case 4:
ey -= movUnit;
break;
case 5:
chase();
break;
case 6:
chase();
break;
case 7:
chase();
break;
case 8:
chase();
break;
}
// See if enemy hit anything important
detectHit();
}
function chase(){
// If in town, skip chase
if (mapFlag = "town"){ return; }
// If in playable area get closer to player
if (ex < px) {ex += movUnit;}
if (ey < py) {ey += movUnit;}
if (ex > px) {ex -= movUnit;}
if (ey > py) {ey -= movUnit;}
}
function bgMusic(){
if (mapFlag == "town"){
sndMusic.pause();
sndCave.pause();
}
if (mapFlag == "grass"){
sndMusic.play();
sndCave.pause();
}
if (mapFlag == "cave") {
sndCave.play();
sndMusic.pause();
}
}
function draw(){
// Draw the current state of the game
enemyAI();
if (mapFlag == "town") { cvs.drawImage(imgTown, 0, 0);}
if (mapFlag == "grass"){ cvs.drawImage(imgGrass, 0, 0);}
if (mapFlag == "cave") { cvs.drawImage(imgCave, 0, 0);}
cvs.drawImage(imgScore, 0, 620);
cvs.drawImage(imgPlayer, px, py);
// Draw enemy as long as we're not in town
if (mapFlag != "town"){cvs.drawImage(enemyPlayer, ex, ey);}
// Show Death Count
cvs.fillStyle = "maroon";
cvs.font = "46px Arial";
cvs.fillText(playerDeaths, 180,670);
// Show Score and stop scoring if in town
if (mapFlag != "town") { score += scoreIncrease; }
cvs.fillStyle = "gold";
cvs.font = "46px Arial";
cvs.fillText(score, 240,715);
// Show coordinates for testing
cvs.fillStyle = "gray";
cvs.font = "10px Arial";
cvs.fillText("px: " + px + " py: " + py + " ex: " + ex + " ey: " + ey + " map: " + mapFlag, 400,640);
// Show Gravestones
for (var i = 0; i <= gravestones.length; i++){
for (var j = 0; j <= 2; j++){
cvs.drawImage(imgGrave, gravestones[i][0], gravestones[i][1]);
}
}
}
// GAME LOOPS
setInterval(draw, gameSpeed, px, py, ex, ey); // game loop
setInterval(bgMusic, 1000); // music loop
function direction(event){
let key = event.keyCode;
if(key == 37){
// LEFT
px -= movUnit;
}else if(key == 38){
// UP
py -= movUnit;
}else if(key == 39){
// RIGHT
px += movUnit;
}else if(key == 40){
// DOWN
py += movUnit;
}
sndFootstep.play();
detectHit();
}
</script>
Aucun commentaire:
Enregistrer un commentaire