128 lines
5.0 KiB
JavaScript
128 lines
5.0 KiB
JavaScript
class Game{
|
|
constructor(eventBus, grid, previewGrid, pieceFactory){
|
|
this.eventBus = eventBus;
|
|
this.lastTime = performance.now();
|
|
this.dropCounter = 0;
|
|
this.dropInterval = 300;
|
|
this.grid = grid;
|
|
this.previewGrid = previewGrid;
|
|
this.pieceFactory = pieceFactory;
|
|
this.bagGenerator = this.pieceFactory.bagGenerator();
|
|
this.loopRequestID = null;
|
|
this.currentPiece = null;
|
|
this.nextPiece = null;
|
|
this.level = 1;
|
|
this.lines = 0;
|
|
this.score = 0;
|
|
this.moveHandler = this.moveHandler.bind(this);
|
|
this.lockPiece = this.lockPiece.bind(this);
|
|
this._setupInputListeners();
|
|
this.loop = this.loop.bind(this);
|
|
this.eventBus.emit("update", this.uiState());
|
|
this.subscriptions = []; // Подписки.
|
|
// Смотреть здесь
|
|
this.unsubscribleStartGameplay = this.eventBus.on("start-gameplay", ({})=>{
|
|
this._setupInputListeners();
|
|
});
|
|
this.unsubscribleStopGameplay = this.eventBus.on("stop-gameplay", ({})=>{
|
|
this.unSetupInputListeners();
|
|
})
|
|
}
|
|
getRenderState(){
|
|
return {
|
|
matrix:this.grid.matrix,
|
|
piece:this.currentPiece,
|
|
nextMatrix:this.previewGrid.matrix,
|
|
nextPiece:this.nextPiece,
|
|
};
|
|
}
|
|
moveHandler({dx, dy}){ //Деструктуризация moveState
|
|
this.move(dx, dy);
|
|
}
|
|
_setupInputListeners() {
|
|
this.move_off = this.eventBus.on("move", this.moveHandler);
|
|
this.rotate_off = this.eventBus.on("rotate", ()=>{
|
|
this.rotate();
|
|
});
|
|
this.lockPiece_off = this.eventBus.on("lockPiece", this.lockPiece);
|
|
}
|
|
unSetupInputListeners() {
|
|
// Вызываем сохраненные функции-отписки, которые мы получили от eventBus.on()
|
|
if(this.move_off) this.move_off();
|
|
if(this.rotate_off) this.rotate_off();
|
|
if(this.lockPiece_off) this.lockPiece_off();
|
|
}
|
|
loop(time){
|
|
const deltaTime = time - this.lastTime;
|
|
this.lastTime = time;
|
|
this.dropCounter += deltaTime;
|
|
if (this.dropCounter > this.dropInterval) {
|
|
this.eventBus.emit("move", {dx:0, dy:1});
|
|
this.dropCounter -= this.dropInterval;
|
|
}
|
|
this.eventBus.emit("render", this.getRenderState());
|
|
this.loopRequestID = window.requestAnimationFrame(this.loop);
|
|
}
|
|
spawnNewPiece() {
|
|
if(this.nextPiece == null) {
|
|
const currentType = this.bagGenerator.next().value;
|
|
const nextType = this.bagGenerator.next().value;
|
|
this.currentPiece = this.pieceFactory.generatePieceByType(currentType, this.grid.width, this.grid.height);
|
|
this.nextPiece = this.pieceFactory.generatePieceByType(nextType, this.previewGrid.width, this.previewGrid.height, true);
|
|
}
|
|
else{
|
|
const nextType = this.bagGenerator.next().value;
|
|
this.currentPiece = this.pieceFactory.generatePieceByType(this.nextPiece.type, this.grid.width, this.grid.height);
|
|
this.nextPiece = this.pieceFactory.generatePieceByType(nextType, this.previewGrid.width, this.previewGrid.height, true);
|
|
}
|
|
}
|
|
move(dx, dy){
|
|
if(this.currentPiece === null) return;
|
|
const moved = this.currentPiece.move(dx, dy);
|
|
if(!this.grid.isCollision(moved)){
|
|
this.currentPiece = moved;
|
|
/*if (dy === 1) {
|
|
this.dropCounter = 0;
|
|
}*/
|
|
}else if(dy == 1){
|
|
//this.eventBus.emit("render", this.getRenderState());
|
|
this.eventBus.emit("lockPiece",{piece:this.currentPiece});
|
|
}
|
|
}
|
|
rotate(){
|
|
if(this.currentPiece === null) return;
|
|
const rotated = this.currentPiece.rotate();
|
|
if(!this.grid.isCollision(rotated)){
|
|
this.currentPiece = rotated;
|
|
}
|
|
}
|
|
async lockPiece({piece}){
|
|
this.grid.matrix = this.grid.getMergedMatrix(piece);
|
|
const blinkedIndexes = this.grid.getBlinkedIndexes();
|
|
if(blinkedIndexes.length > 0){
|
|
this.eventBus.emit("force-render", this.getRenderState()); //
|
|
await this.eventBus.emitAsync("animate",{count:4, time:100, indexes:blinkedIndexes, matrix:this.grid.matrix});
|
|
this.lines += this.grid.deleteLines();
|
|
this.eventBus.emit("update", this.uiState());
|
|
}
|
|
this.spawnNewPiece();
|
|
if(this.grid.isCollision(this.currentPiece)){
|
|
this.eventBus.emit("gameEnd",{});
|
|
}
|
|
}
|
|
uiState(){
|
|
return {
|
|
level:this.level,
|
|
lines:this.lines,
|
|
score:this.score
|
|
}
|
|
}
|
|
start(){
|
|
if(this.loopRequestID) return;
|
|
this.spawnNewPiece();
|
|
this.lastTime = performance.now();
|
|
this.loopRequestID = window.requestAnimationFrame(this.loop)
|
|
}
|
|
}
|
|
|