0

So I have following code:

class SquareBlock {
constructor(){
    this.startPosition = rand(1, boardHeight - 3);
    this.block = [{x: 1, y: this.startPosition}];
    this.block.push({x: 1, y: this.startPosition + 1});
    this.block.push({x: 2, y: this.startPosition});
    this.block.push({x: 2, y: this.startPosition + 1});

    document.addEventListener('keydown', () => {return this.move();}, true);

    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = true;
        pointColor(this.block[n].x, this.block[n].y, 'blue');
    }

    this.start();
}

start(){        
    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = false;
        pointColor(this.block[n].x, this.block[n].y, 'transparent');
    }
    for(var n in this.block){
        this.block[n].x += 1;
    }
    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = true;
        pointColor(this.block[n].x, this.block[n].y, 'blue');
    }

    if(this.isSettledValidate() != 'stop'){
        setTimeout(() => {this.start()}, 100);
    }
}

isSettledValidate(){
    if(this.block[2].x == boardWidth - 2 || this.block[3].x == boardWidth - 2){
        return 'stop';
    }
    if(fields[getFieldId(this.block[2].x + 1, this.block[2].y)].hasBlock == true){
        return 'stop';
    }
    if(fields[getFieldId(this.block[3].x + 1, this.block[3].y)].hasBlock == true){
        return 'stop';
    }
}

move(ev){
    switch(ev.which){
        case 37:
        for(var n in this.block){
            if(this.block[n].y - 1 != 0){
                this.block[n].y -= 1;
            }
        }
        break;
        case 39:
        for(var n in this.block){
            if(this.block[n].y + 1 != boardHeight - 1){
                this.block[n].y += 1;
            }
        }
        break;
    }
}

}

And I have problem with document.addEventListener in constructor. What I want to achieve is to move SquareBlock one space left or right with move() class method. When I use code "document.addEventListener('keydown', move, true)" square won't move because "this" in move function points at "document" object. When I tried to fix this with arrow function (as in code above), "this" correctly points at square object but then it won't move either because square object doesn't have "which" property and I can't use it to scan keycodes. Forgive me if it's dumb question with simple solution but I'm novice programmer. I've read related topic about this in event handlers but I couldn't find an ansewr there.

0

2 Answers 2

1

The fastest quick fix for the current setup is to pass the eventargs in the arrow function: e => this.move(e):

document.addEventListener('keydown', e => this.move(e), true);

Simplified example for testing:

class SquareBlock {
  constructor(){
      document.addEventListener('keydown', e => this.move(e), true);      
  }

  move(ev){
    console.log(this , ev);
  }
}

new SquareBlock();

Alternatively, you can bind the function:

document.addEventListener('keydown',this.move.bind(this), true);  
Sign up to request clarification or add additional context in comments.

Comments

0

The value of this changes in javascript and it can be confusing. Have a look at apply and call for examples of manipulating the value of this when calling a method. In your example you might be able to get away with setting a variable to represent your current SquareBlock instance like this:

var me = this;
document.addEventListener('keydown', () => {return me.move();}, true);

The reasoning here (at least to my understanding) is that the event is raised from within a different context (document). By setting this into a variable me you can refer back to that context later.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.