Платформа зенда fetchAll

Проблема в том, что checkSnakeForFood() не работает так, как вы ожидаете, потому что newHead еще не был добавлен в тело змеи к тому времени, когда вы проверяете столкновение с головой пищи.

Проверяется только змеиный хвост, и процедура checkSnakeForFood() сообщает, что текущее размещение еды (прямо под newHead) не является столкновением, поэтому тело петли while не выполняется, и еда не движется , Вот диаграмма того, что происходит:

 0123456789
0+--------- 
1|.........
2|.F######.
3|.......##
    ^^^^^^^
       |
only these segments get
tested for collision

newHead и food имеют одинаковое местоположение, [2, 2], обозначаемое как F. Они сталкиваются, поэтому if (headX == food.x && headY == food.y) верно. Однако, когда на следующей строке вызывается checkSnakeForFood(), в цикле учитываются только элементы хвоста # for (let i = 0; i < snake.length; i++). checkSnakeForFood() затем возвращает true, и цикл while никогда не перемещает пищу.

Вы можете решить эту проблему, unshift набрав newHead перед попыткой вызвать checkSnakeForFood(), следующим образом:

  //create new head
  let newHead = {
    x: headX,
    y: headY
  }

  //add head to snake, *before* checking for collision with the food
  snake.unshift(newHead);

  //if snake eats food -do this
  if (headX == food.x && headY == food.y) {
    //create new food position
    while (!checkSnakeForFood()) {  // <-- now this will successfully detect
                                    // that the snake head is touching the food

Теперь столкновение головы с едой будет регистрироваться правильно, и еда будет перемещаться до тех пор, пока он не столкнется с хвостом змеи или :

     0123456789
    0+--------- 
    1|.........
    2|.F######.
    3|.......##
       ^^^^^^^^
           |
    all segments are correctly
    tested for collision

Однако я рекомендую рефакторинг, чтобы избежать подобных ошибок. Вы можете сделать snake объектом с функциями-членами для столкновения и перемещения и свойствами для его direction и tail. Ваша функция draw очень перегружена и отвечает гораздо больше, чем обещает ее название.

Отделение newHead похоже на подверженный ошибкам подход; манипулирование головой непосредственно на массиве избавит вас от путаницы.

А пока вот обновленный код, который заставит вас снова двигаться (не забудьте щелкнуть ссылку Full page во фрагменте, чтобы правильно играть в игру:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

//set canvas dimension equal to css dimension
canvas.width = 768;
canvas.height = 512;

//now put those dimensions into variables
const cvsW = canvas.width;
const cvsH = canvas.height;

//create snake unit
const unit = 16;

//create snake array
let snake = [{
  x: cvsW / 2,
  y: cvsH / 2
}];

//delcare global variable to hold users direction
let direction;

//create food object
let food = {
  x: Math.floor(Math.random() * ((cvsW / unit) - 1) + 1) * unit,
  y: Math.floor(Math.random() * ((cvsH / unit) - 1) + 1) * unit
}

//read user's direction
document.addEventListener('keydown', changeDirection);

function changeDirection(e) {
  //set direction
  if (e.keyCode == 37 && direction != 'right') direction = 'left';
  else if (e.keyCode == 38 && direction != 'down') direction = 'up';
  else if (e.keyCode == 39 && direction != 'left') direction = 'right';
  else if (e.keyCode == 40 && direction != 'up') direction = 'down';
}

function draw() {
  //refresh canvas
  ctx.clearRect(0, 0, cvsW, cvsH);
  //draw snake
  for (let i = 0; i < snake.length; i++) {
    ctx.fillStyle = 'limegreen';
    ctx.fillRect(snake[i].x, snake[i].y, unit, unit);
  }

  //grab head position
  let headX = snake[0].x;
  let headY = snake[0].y;

  //posistion food on board
  ctx.fillStyle = 'red';
  ctx.fillRect(food.x, food.y, unit, unit);

  //send the snake in chosen direction
  if (direction == 'left') headX -= unit;
  else if (direction == 'up') headY -= unit;
  else if (direction == 'right') headX += unit;
  else if (direction == 'down') headY += unit;

  // //check if snake hit wall
  // if(headX < 0 || headY < 0 || headX > (cvsW-unit) || headY > (cvsH-unit)) {
  // 	clearInterval(runGame);
  // }

  if (headX < 0) headX = cvsW - unit;
  else if (headX > cvsW - unit) headX = 0;
  else if (headY < 0) headY = cvsH - unit;
  else if (headY > cvsH - unit) headY = 0;

  // for(let i = 0; i < snake.length; i++) {
  // 	if(headX == snake[i].x && headY == snake[i].y) {
  // 		clearInterval(game);
  // 	}
  // }

  //create new head
  let newHead = {
    x: headX,
    y: headY
  }

  //add head to snake
  snake.unshift(newHead);

  //if snake eats food -do this
  if (headX == food.x && headY == food.y) {
    //create new food position
    while (!checkSnakeForFood()) {
      food = {
        x: Math.floor(Math.random() * ((cvsW / unit) - 1) + 1) * unit,
        y: Math.floor(Math.random() * ((cvsH / unit) - 1) + 1) * unit
      }
    }

    //add 3 units to the snake
    for (let i = 30; i > 0; i--) {
      snake.unshift(newHead);
    }
  } else {
    //remove tail
    snake.pop();
  }
}

//run game engine
let runGame = setInterval(draw, 40);

function checkSnakeForFood() {
  for (let i = 0; i < snake.length; i++) {
    if (snake[i].x === food.x && snake[i].y === food.y) return false;
  }
  return true;
}
[ 114]
<canvas id="canvas"></canvas>

5
задан Jeremy Privett 13 October 2008 в 10:29
поделиться

2 ответа

Для переопределения этого метода, необходимо было бы разделить Zend_Db_Table_Abstract на подклассы. Как так:

<?php
abstract class My_Db_Table_Abstract extends Zend_Db_Table_Abstract
{
    ...

    public function fetchAll($where, $order)
    {
        ...
    }

    ...
}

Затем удостоверьтесь, что Ваши модели расширяют My_Db_Table_Abstract вместо этого. Таким образом, Вы всегда наследуете свой переопределенный fetchAll метод.

9
ответ дан 14 December 2019 в 01:20
поделиться

Да. Просто определите новый fetchAll () метод в Вашей модели с той же конструкцией как метод Zend_db_table_abstract (т.е. тот же вход / вывод) затем в конце Вашего вызова метода родительский метод:

родитель:: fetchAll ($params)

Andrew

0
ответ дан 14 December 2019 в 01:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: