Я создаю небольшую игру для личного развития, это простая игра с подключением четырех, и я создал свою сцену и установил для строк и столбцов значение «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();
  }
}

Ниже приведена моя функция щелчка, которая позволяет мне щелкать по моей сетке. Созданные маркеры помещаются в сетку с щелчком, однако мне нужно, чтобы маркеры опустили столбец, по которому щелкнули, в самую нижнюю возможную строку, которая не определена, но если она уже! Undefined, тогда она должна быть в строке чуть выше в том же столбце , Я добавил функцию щелчка ниже.

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();
        }
      }
    }
 },
0
J.Fair 23 Окт 2018 в 15:23

2 ответа

Лучший ответ

Координата 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/>");
   
0
Nico Schertler 24 Окт 2018 в 11:40

Ниже представлено небольшое изменение, сделанное для того, чтобы код работал.

  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;

'Y = y - 1;' был перемещен из цикла for и позволил коду работать правильно

0
J.Fair 24 Окт 2018 в 11:31
52948994