function Tetris(selector, option) {
self = this;
this.container = {
elem: document.querySelector(selector),
selector: selector
};
this.option = option;
this.container.elem.style.height = this.option.height + "px";
this.container.elem.style.width = this.option.width + "px";
this.cells = {
width: this.option.width / this.option['block-size'],
height: this.option.height / this.option['block-size'],
}
this.getModel=function()
{
return new self.Models();
}
this.select = function(x, y) {
let target = m.block(x, y);
console.log({x,y})
let oldClass = target.className;
target.className = oldClass + " select";
return self;
}
this.Models=Models;
this.fill = async function() {
let block = function(text=null) {
let block = document.createElement("div")
block.className = "cell";
block.style.height = self.option["block-size"] + "px";
block.style.width = self.option["block-size"] + "px";
block.innerHTML=text;
return block
}
await (function() {
let y = 0;
let x = 0;
let count = (self.option.height * self.option.width) / Math.pow(self.option['block-size'], 2);
for (i = 0; i < count; i++) {
bl = block();
if (i != 0 && (i * self.option['block-size']) % self.option.width == 0) {
y++;
x = 0;
}
bl.setAttribute("data-y", y);
bl.setAttribute("data-x", x);
self.container.elem.appendChild(bl);
x++;
}
})()
return self;
}
}
Object.defineProperty(Models.prototype, 'height', {get(){
return m.position[m.position.length-1].y+1-a.offset.y;
}})
Object.defineProperty(Models.prototype, 'width', {get(){
return m.position[m.position.length-1].x+1-a.offset.x;
}})
function Models( name) {
m = this; //*1
console.log(m,"777");
this.status = "";
this.block = function(x, y) {
return self.container.elem.querySelector(`[data-x='${x}'][data-y='${y}']`);
}
this.name=name;
this.position=[];
this.action=new Actions();
this.L = function() {
m.position= [{
x: 0,
y: 0
}, {
x: 0,
y: 1
}, {
x: 0,
y: 2
}, {
x: 1,
y: 2
}];
return this;
}
this.show = async function() { //*2
console.log( m,'mmm') //*3
await(
function() {
m.position.forEach(function(e) {
self.select(e.x, e.y)
});
})()
}
return this;
}
function Actions() {
a = this;
this.offset={
x:0,
y:0
}
this.clearActions = async function() {
let selects = self.container.elem.querySelectorAll(".select:not(.droped)");
await (
function() {
selects.forEach(function(e) {
e.className = e.className.replace(/select/, "")
e.className = e.className.replace(/s{2,}/g, "")
})
})()
}
this.left = async function(step) {
if (m.status == "droped") {
return false;
}
await (
function() {
a.clearActions().then(function() {
m.position = m.position.map(function(e) {
return {
x: e.x - step,
y: e.y
};
})
m.show();
})
a.offset.x-=step;
})()
}
this.right = async function(step) {
if (m.status == "droped") {
return false;
}
await (
function() {
a.clearActions().then(function() {
console.log(m.position,"111")
m.position = m.position.map(function(e) {
return {
x: e.x + step,
y: e.y
};
})
m.show();
})
a.offset.x+=step;
})()
}
this.drop = function() {
async( function() {
await(
function() {
d = setInterval(function() {
a.clearActions().then(function() {
m.position = m.position.map(function(e) {
return {
x: e.x,
y: e.y + 1
};
})
a.offset.y++;
if (m.position[m.position.length - 1].y == (self.cells.height - 1)) {
clearInterval(d);
m.position.forEach(function(e) {
let block = m.block(e.x, e.y);
block.className = block.className + " droped";
});
m.status = "droped";
}
m.show();
})
}, self.option.speed)
})()
})().then(function() {
})
return m;
}
this.speedDrop = function() {
}
this.rotate = async function(deg) {
const CosDeg90=Math.cos(deg*(180/Math.PI));
const SinDeg90=Math.sin(deg*(180/Math.PI));
await (
function() {
a.clearActions().then(function() {
m.position = m.BasePosition.map(function(e, i) {
rx= Math.abs(Math.floor((e.x+5)*CosDeg90+(e.y+5)*SinDeg90));
ry= Math.abs(Math.floor((e.x+5)*SinDeg90+(e.y+5)*CosDeg90));
return {
x: rx,
y: ry
};
})
m.show();
})
})()
}
}
tetris = new Tetris(".tetris", {
"block-size": 20,
width: 300,
height: 500,
speed: 200
})
console.dir(tetris)
var f = new tetris.Models("1"); //*4
f.L();
let f2= new tetris.Models("2"); //*5
tetris.fill().then(function() {
console.log({f,f2})
f.show().then(function(){ //*6
})
})
document.addEventListener("keydown", function(event) {
if (event.key == "ArrowRight") {
f.action.right(1);
}
if (event.key == "ArrowLeft") {
f.action.left(1);
}
})
я объявляю экземпляры объекта в *4 и в *5
в объекте есть
position, который описывает координаты квадратов
в первом случае я вызываю
L(), который перезаписывает
position
во втором случае идет просто объявление экземпляра, то есть f2.position=[]
дальше вызываю f.show() в *6
и дальше в *3 смотрю, что переменная m которая равняется this в *1 , хотя у f2 не вызывался show()
если изменить show в *2 на
this.show = async function(){m=this ....}.bind(this);
то все работает, как должно
отсюда вопрос зачем явно через bind привязывать к контексту, если m ссылается на this?
и стоит ли теперь async функции всегда привязывать через bind(this) ?
буду благодарен за любую информацию