|
function Game(inputMapping, autoRepeat, threshold) { |
|
var thisObject = this, |
|
i; |
|
|
|
this.firstLoop = true; |
|
|
|
this.blocks = []; |
|
this.controlGroup = null; |
|
|
|
|
|
this.previewBlocks = []; |
|
for (i = 0; i < 4; i += 1) { |
|
this.previewBlocks.push(new Block({blockX: -10, blockY: -10, preview: true})); |
|
} |
|
|
|
this.scoreOutput = new TtyBlock("scoreDiv", 3); |
|
this.linesOutput = new TtyBlock("linesDiv", 3); |
|
this.levelOutput = new TtyBlock("levelDiv", 3); |
|
this.tickerOutput = new TtyBlock("tickerDiv", 5); |
|
this.scoreTracker = new ScoreTracker(this.scoreOutput, this.linesOutput, this.levelOutput, this.tickerOutput); |
|
|
|
this.dropPeriod = this.scoreTracker.getLevelPeriod(); |
|
this.timeToNextDrop = this.dropPeriod; |
|
|
|
|
|
this.keyChargeTime = threshold; |
|
this.keyRepeatTime = autoRepeat; |
|
|
|
this.bottomTimer = null; |
|
this.bottomLockTime = 500; |
|
this.lastBottomedState = false; |
|
|
|
this.lastTime = null; |
|
|
|
this.gameLost = false; |
|
|
|
|
|
this.previewLength = 5; |
|
this.randBag = new RandomBag(this.previewLength); |
|
|
|
this.previewGroups = []; |
|
for (i = 0; i < this.previewLength; i += 1) { |
|
this.previewGroups.push(new PreviewGroup(330, 70 * i + 35)); |
|
} |
|
|
|
this.swapGroup = null; |
|
this.swapAllowed = true; |
|
|
|
|
|
|
|
this.occupiedPositions = {}; |
|
|
|
this.input = { |
|
shiftLeft: { |
|
autoRepeat: true, |
|
handler: function () { |
|
if (thisObject.controlGroup.shift(true)) { |
|
thisObject.resetLockCounter(true); |
|
} |
|
} |
|
}, |
|
shiftRight: { |
|
autoRepeat: true, |
|
handler: function() { |
|
if (thisObject.controlGroup.shift(false)) { |
|
thisObject.resetLockCounter(true); |
|
} |
|
} |
|
}, |
|
softDrop: { |
|
autoRepeat: true, |
|
preCharged: true, |
|
handler: function() { |
|
thisObject.dropBlock(); |
|
thisObject.scoreTracker.softDrop(); |
|
} |
|
}, |
|
hardDrop: { handler: function() { |
|
var dist = thisObject.controlGroup.fall(); |
|
thisObject.scoreTracker.hardDrop(dist); |
|
thisObject.lockBlocks(); |
|
}}, |
|
rotateLeft: { handler: function() { |
|
if (thisObject.controlGroup.turn(false)) { |
|
thisObject.resetLockCounter(true); |
|
} |
|
}}, |
|
rotateRight: { handler: function() { |
|
if (thisObject.controlGroup.turn(true)) { |
|
thisObject.resetLockCounter(true); |
|
} |
|
}}, |
|
swap: { handler: function() { |
|
thisObject.swap(); |
|
}} |
|
}; |
|
|
|
this.inputMapping = inputMapping; |
|
} |
|
|
|
|
|
|
|
|
|
Game.prototype.newBlock = function (calledBySwap) { |
|
var thisObject = this, |
|
shape = this.randBag.popQueue(), |
|
newBlocks = [], |
|
curBlock, |
|
i; |
|
|
|
this.dropPeriod = this.scoreTracker.getLevelPeriod(); |
|
|
|
|
|
for (i = 0; i < 4; i += 1) { |
|
curBlock = new Block({blockX: -10, blockY: -10, shape: shape, occupiedPositions: this.occupiedPositions}); |
|
newBlocks.push(curBlock); |
|
this.blocks.push(curBlock); |
|
} |
|
|
|
this.controlGroup = new ControlGroup(newBlocks, shape, function(x, y){ |
|
return thisObject.isLegalPosition(x, y); |
|
}); |
|
|
|
if (this.controlGroup.isIllegalStart) { |
|
this.gameLost = true; |
|
} |
|
|
|
if (!calledBySwap) { |
|
|
|
this.swapAllowed = true; |
|
} |
|
|
|
this.updatePreviews(this.randBag.getQueue()); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Game.prototype.processInput = function(dTime) { |
|
var curInput, |
|
keyName, |
|
curKeys, |
|
pressed, |
|
curInput, |
|
i; |
|
|
|
for (actionType in this.inputMapping) { |
|
curKeys = this.inputMapping[actionType]; |
|
curInput = this.input[actionType]; |
|
pressed = false; |
|
for (i = 0; i < curKeys.length; i += 1) { |
|
if (jaws.pressed(curKeys[i])) { |
|
pressed = true; |
|
} |
|
} |
|
|
|
|
|
if (pressed) { |
|
|
|
if (!curInput.lastState) { |
|
curInput.handler(); |
|
curInput.lastState = true; |
|
curInput.charged = (curInput.preCharged ? true : false); |
|
curInput.holdTime = 0; |
|
} |
|
|
|
if (curInput.autoRepeat) { |
|
curInput.holdTime += dTime; |
|
|
|
|
|
if ((!curInput.charged) && (curInput.holdTime > this.keyChargeTime)) { |
|
|
|
curInput.holdTime -= this.keyChargeTime; |
|
curInput.handler(); |
|
curInput.charged = true; |
|
} |
|
|
|
if (curInput.charged && (curInput.holdTime > this.keyRepeatTime)) { |
|
curInput.holdTime -= this.keyRepeatTime; |
|
curInput.handler(); |
|
} |
|
} |
|
} else { |
|
|
|
curInput.lastState = false; |
|
} |
|
} |
|
}; |
|
|
|
Game.prototype.update = function(time) { |
|
var curTime, |
|
dTime, |
|
i; |
|
|
|
|
|
if (this.firstLoop) { |
|
this.firstLoop = false; |
|
|
|
this.newBlock(); |
|
|
|
this.lastTime = time; |
|
} |
|
|
|
curTime = time; |
|
dTime = curTime - this.lastTime; |
|
this.lastTime = curTime; |
|
|
|
this.processInput(dTime); |
|
|
|
if (!this.controlGroup.isBottomed()) { |
|
this.lastBottomedState = false; |
|
this.applyGravity(dTime); |
|
|
|
} else { |
|
|
|
if (!this.lastBottomedState) { |
|
this.resetLockCounter(false); |
|
} else { |
|
this.bottomTimer -= dTime; |
|
|
|
if (this.bottomTimer <= 0 || this.slideCount >= 15) { |
|
this.lockBlocks(); |
|
} |
|
} |
|
this.lastBottomedState = true; |
|
} |
|
|
|
|
|
if (this.controlGroup) { |
|
|
|
this.controlGroup.configurePreviewBlocks(this.previewBlocks); |
|
} else { |
|
|
|
for (i = 0; i < 4; i += 1) { |
|
this.previewBlocks[i].setPosition(-10, -10); |
|
} |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
Game.prototype.draw = function(dTime) { |
|
var i; |
|
|
|
this.scoreOutput.draw(dTime); |
|
this.linesOutput.draw(dTime); |
|
this.levelOutput.draw(dTime); |
|
this.tickerOutput.draw(dTime); |
|
|
|
|
|
for (i = 0; i < 4; i += 1) { |
|
this.previewBlocks[i].drawIfInvalid(); |
|
} |
|
|
|
|
|
if (this.swapGroup) { |
|
this.swapGroup.draw(); |
|
} |
|
|
|
|
|
for (i = 0; i < this.previewGroups.length; i += 1) { |
|
this.previewGroups[i].draw(); |
|
} |
|
|
|
for (i = 0; i < this.blocks.length; i += 1) { |
|
this.blocks[i].drawIfInvalid(); |
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Game.prototype.isLegalPosition = function (x, y) { |
|
|
|
if (this.occupiedPositions[x+','+y]) { |
|
return false; |
|
} |
|
|
|
|
|
if (x >= 10 || x < 0 || y >= 20) { |
|
return false; |
|
} |
|
return true; |
|
}; |
|
|
|
|
|
|
|
|
|
Game.prototype.dropBlock = function (causedByGravity) { |
|
if (!causedByGravity) { |
|
this.timeToNextDrop = this.dropPeriod; |
|
} |
|
|
|
this.controlGroup.drop(); |
|
}; |
|
|