如何针对特定目的正确使用点击功能

How to use a click function correctly for a specific purpose

我正在创建一个用于个人发展的小游戏,它是一个简单的四人连线游戏,我已经创建了我的舞台并将行和列设置为 'undefined' 所有这些代码都可以正常运行,但是在下一个块引用你应该开始理解我的问题了。

  actions: {
   start: function() {
      this.set('playing', true);
      this.set('winner', undefined);
    this.set('draw', false);
    this.set('state', [
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
    ]);
    this.set('moves', {'x': 0, 'o': 0});
    this.set('player', 'x');
    var markers = this.get('markers');
    for(var idx = 0; idx < 24; idx++) {
      markers.x[idx].visible = false;
      markers.o[idx].visible = false;
    }
    this.get('stage').update();
  }
}

下面是我的点击功能,它允许我点击我的网格。创建的标记被放置在点击的网格中但是我需要标记将点击的列下拉到未定义的最低可能行,但是如果它已经是!未定义那么它应该在同一列的正上方的行中.我在下面添加了我的点击功能。

click: function(ev) {
    if(this.get('playing') && !this.get('winner')) {
        if(ev.target.tagName.toLowerCase() == 'canvas' && ev.offsetX < 
           360 && ev.offsetY < 360) {
            var x = Math.floor((ev.offsetX) / 51.5);
            var y = Math.floor((ev.offsetY) / 60);
            var state = this.get('state');
            if(!state[x][y]) {
              var player = this.get('player')
              state[x][y] = player;

          var move_count = this.get('moves')[player];
          var marker = this.get('markers')[player][move_count];
          marker.visible = true;
          if (player == 'x') {
            marker.x = 20 + x * 51.5;
            marker.y = 20 + y * 60;
          } else {
            marker.x = 20 + x * 51.5;
            marker.y = 20 + y * 60;
          }

          this.check_winner();

          this.get('moves')[player] = move_count + 1;
          if (player == 'x'){
            this.set ('player', 'o');
          } else {
            this.set('player', 'x');
          }
          this.get('stage').update();
        }
      }
    }
 },

点击位置的 y 坐标无关紧要。你总是想找到尽可能高的位置。为此,只需检查网格中是否已经有标记(我假设 y=0 是第一行;如果不是,则需要反转循环):

var gridHeight = state[0].length;
for(y = 0; y < gridHeight; ++y) {
    if(state[x][y]) {
         //this cell is occupied, so choose the cell above
         break;
    }
}
y = y - 1;

之后,y 保存要添加标记的单元格的 y 坐标。如果该列已满,也可能发生 y=-1。您应该处理这种情况并告诉用户重新选择。

这里有两个不同状态的例子:

var state = [
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, undefined, undefined, undefined],
    ];

function findMarkerYCoordinate(x) { 
    var gridHeight = state[0].length;
    for(y = 0; y < gridHeight; ++y) {
        if(state[x][y]) {
             //this cell is occupied, so choose the cell above
             return y - 1;
        }
    }
    return y - 1;
 }

document.write("Test on empty grid<br/>");
for(var x = 0; x < state.length; ++x)
    document.write("Position for column " + x + ": " + findMarkerYCoordinate(x) + "<br/>");
    
state = [
      [undefined, undefined, undefined, undefined, undefined, 1],
      [undefined, undefined, undefined, undefined, 1, 1],
      [undefined, undefined, undefined, undefined, undefined, 1],
      [undefined, undefined, undefined, undefined, undefined, undefined],
      [undefined, undefined, undefined, 1, 1, 1],
      [undefined, undefined, undefined, undefined, 1, 1],
      [undefined, undefined, undefined, undefined, undefined, undefined],
    ];
document.write("Test on partially filled grid<br/>");
for(var x = 0; x < state.length; ++x)
    document.write("Position for column " + x + ": " + findMarkerYCoordinate(x) + "<br/>");
   

Below is the small change made to make the code functional

  if(ev.target.tagName.toLowerCase() == 'canvas' && ev.offsetX < 360 && ev.offsetY < 360) {
        var x = Math.floor((ev.offsetX) / 51.5);
        var y = Math.floor((ev.offsetY));
        var state = this.get('state');
        var gridHeight = state[0].length;

          for(y = 0; y < gridHeight; y++ ) {
            if(state[x][y]) {
            //this cell is occupied, so choose the cell above
            // y = y - 1
            break;

          }
        }
        y = y - 1;

The 'y = y - 1;' was moved out of the for loop and allowed the code to function correctly