My code works (doesn't fail), but it doesn't do the right thing.
I call the "generate" function every time i want to generate a new "chunk", passing a new number into the function each time its called. It generates the chunk fine, but it doesn't generate what I want it to generate.
I want it to generate either a space, a jump, a slide, or a gap, if the previous generation was a space. But if the previous generation wasn't a space, generate a space. It doesn't do that. It sometimes generates 2 gaps, 2 jumps, or 2 slides after each other and i have no idea why... ???
Here is my code:
var ptg = 'space'; // what was previously generated to top
var wtgt; // what is currently being generated to top
var chunktogenerateto = 0;
function generate(a){
chunktogenerateto = a;
var rand1 = Math.floor(Math.random()*100) + 1;
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
wtgt = 'jump';
}
else if(ptg == 'space' && rand1 <= 75 && rand1 > 50){
wtgt = 'slide';
}
else if(ptg == 'space' && rand1 > 75){
wtgt = 'gap';
}
else{
wtgt = 'space';
}
ptg = wtgt;
topGen(wtgt);
}
function topGen(g){
document.getElementById('t' + chunktogenerateto).setAttribute('src','images/terrain/t' + g + '.png');
}
I hope it's not a typo... HELP!
Where the calls to "generate" are coming from:
var chunkpos = new Array();
chunkpos[0] = -100;
chunkpos[1] = 0;
chunkpos[2] = 100;
chunkpos[3] = 200;
chunkpos[4] = 300;
chunkpos[5] = 400;
chunkpos[6] = 500;
chunkpos[7] = 600;
chunkpos[8] = 700;
chunkpos[9] = 800;
chunkpos[10] = 900;
chunkpos[11] = 1000;
var temppos = new Array();
var time1;
var millis1;
var time2;
var millis2;
var millis3;
var firstreset = true;
var pos;
var poschange;
function moveLevel(){
if(firstreset == true){
resetTime();
}
var time2 = new Date();
var millis2 = time2.getTime();
var millis3 = millis2 - millis1;
poschange = Math.floor(millis3 / 5);
for(i = 0; i < chunkpos.length; i++){
temppos[i] = chunkpos[i] - poschange;
if(temppos[i] <= -150){
generate(i);
temppos[i] += 1200;
}
pos = temppos[i];
document.getElementById('chunk' + i).setAttribute('style','left: ' + pos + 'px;');
}
}
function resetTime(){
time1 = new Date();
millis1 = time1.getTime();
if(firstreset != true){
for(i = 0; i < chunkpos.length; i++){
chunkpos[i] = temppos[i];
}
}
firstreset = false;
setTimeout('resetTime()',1000);
}
Where the calls to "moveLevel" are coming from:
window.onload = function(){
if(test = 'runnable')
{
gameLoop();
}
else
{
document.getElementById('gm').innerHTML = (gm + 'Failed to run game.');
}
}
function gameLoop(){
if(currentscreen == 'playing'){
moveLevel();
}
setTimeout('gameLoop()',0);
}
Here is a download link to a zip file containing all of the code: ParkourFreak.zip The code i'm having trouble with is under scripts/generation.js. The main game page (where the generation is visible is index.html.
5 Answers 5
Rather than each if statement starting with "if(ptg == 'space' ... etc" - do this first in one simple "if not space return space".
After that you can start on your random - that should work for you.
1 Comment
Roughly a quarter of the time you previously had a space, it will create another, because of this code:
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
Note that it's creating a space when a space was previously created.
Side note:
There's no need for the && rand1 > 25 on this line:
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
Since you previously had if(ptg == 'space' && rand1 <= 25){, it's impossible as of that line for rand1 to be <= 25 when ptg == 'space'.
(And similarly the && rand2 > 50 on the following condition.)
7 Comments
Are you sure you're incrementing chunktogenerateto?
It appears to stay at 0 with the current code, is that in a segment you haven't shown?
Edit: oh, it's the argument of the function. Try logging that variable, maybe that's the problem?
1 Comment
// elsewhere
var wtgts = ['space','jump','slide','gap'];
// in the function
if(ptg !== 'space') {
wtgt = 'space';
} else {
var randidx = Math.floor(Math.random()*4);
wtgt = wtgts[randidx];
}
Or even in the function:
var newidx = (ptg == 'space') ? Math.floor(Math.random()*4) : 0;
wtgt = wtgts[newidx];
- The weights were equal, so just pick a random index from 0 to 3 and use that to pick an action from an array.
- Separate the logic for ptg being space so that you only test for it once
- Consider denoting the actions as numbers instead of strings, as the assignment, comparison etc will be faster and more robust.
1 Comment
I thought the problem lied with the generation, when in fact all I had to do to solve it was to change this:
if(temppos[i] <= -100){
generate(i);
temppos[i] += 1200;
}
to this:
if(temppos[i] <= -100){
generate(i);
chunkpos[i] += 1200;
temppos[i] += 1200;
}
ptgprobably gets clobbered somewhere outside the code you posted. Try to get rid of globals and the spooky-action-at-a-distance: makegeneratea pure function with the previous image as a parameter, and the next image the return value. (I'd also get rid of makingrndan integer and the unnecessary greater-than comparisons but that's just me.)console.log(ptg)at the start of your function, andconsole.log(wtgt)after theif..elseblock. Ifptgis something else than what it should be after the previous call, you know what to look for.