на главную почта поиск
 
поиск
Диона Холдинг
   
   
FLASH-версия 
 Версия для печати 
  Новости
 

   
Новости  
   

Глава 5. Встреча со стеной

Отлично, наш Герой ходит и бегает, а как же углы и стенки. Сделаем нашего Героя способным определять стены или другие не проходимые плитки.

(Ну вот, и Герой стал черпашкой ниндзя.)

В главе 1 для объектов введено свойство "walkable". Когда объект плитка в текущей позиции имеет свойство «не проходим», наш Герой не может встать на эту плитку. Ну а затем, если свойство "walkable" стало "true", то Герой может идти дальше (это называется «логикой» игры, люди учатся этому в школе, некоторые в университете и далее по жизни).

Теперь делаем чудо, заложим следующее: после нажатия клавиши перемещения, проверим свойство проходимости плитки, на которую хочет вступить Герой. Если плитка проходима, то запускаем Героя. Если не проходима, то пропускаем нажатие клавиши.

Это замечательный способ устранения конфликтов со стенками.

Герой остановился около стены и следующим шагом он войдет в стену. Мы не хотим этого. Стой, чувак! Но мир не так замечателен, что если часть Героя будет конфликтовать со стеной.

Значит нужно предусмотреть возможность проверки конфликта между Героем и стенкой по 4 углам. Если любой из углов Героя (левый нижний угол, как на рисунке) будет в стене, то останавливаем Героя.

Или, если Герой рядом со стеной и может еще идти, то нужно проверить столкновение со стеной и остановить его (Героя, конечно, не стену же).

В этом случае, поставим Героя рядом со стенкой.

«О нет!» – скажете вы. «Это не возможно!» Не волнутесь, все не так страшно.

Дайте мне мои Углы

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

Создадим новую функцию getMyCorners:

//****************
// Функция: getMyCorners
// Назначение: Проверка препятствий по 4 углам объекта (Героя или еще кого)
// Параметры:
// x - будущая координата Х центра объекта
// y - будущая координата У центра объекта
// ob - объект,
// Возвращает: в объект записываются значения свойств upleft, downleft, upright, downright
// ****************************
function getMyCorners (x, y, ob) {

// Определяем позиции плиток по 4 углам объекта
ob.downY = Math.floor((y+ob.height-1)/game.tileH);
ob.upY = Math.floor((y-ob.height)/game.tileH);
ob.leftX = Math.floor((x-ob.width)/game.tileW);
ob.rightX = Math.floor((x+ob.width-1)/game.tileW);

// Установим свойства перемещения по проходимости плиток для углов объекта
ob.upleft = game["t_"+ob.upY+"_"+ob.leftX].walkable;
ob.downleft = game["t_"+ob.downY+"_"+ob.leftX].walkable;
ob.upright = game["t_"+ob.upY+"_"+ob.rightX].walkable;
ob.downright = game["t_"+ob.downY+"_"+ob.rightX].walkable;

}

Эта функция получает 3 параметра: Х/У координаты центра объекта и собственно объект. Подождите, мы уже знаем Х/У позицию объекта, мы сохраняли ее в свойствах объекта. Да, но это координаты ТЕКУЩЕГО положения объекта, а здесь нам нужны координаты БУДУШЕГО положения при перемещении.
Первое, расчитываем плитки, которых может касаться объект. По центру (слева или справа) он (объект) может касаться одной плитки, с верху другой, а с низу третьей. Добавим к У координате высоту Героя и разделим на высоту плитки, в результате получаем номер плитки, где объект с меньшей координатой (downY) должен оставаться.

Последние 4 строки используют расчитанные позиции плиток по четырем углам объекта. Например, левый верхний угол использует позиции upY и leftX . Как видите все расчитанные позиции сохраняются в свойствах объекта ob и у нас есть доступ к ним в процессе перемещения объекта. Я хочу отметить, что функция getMyCorners будет работать с любым движущимся объектом, не только Героем.

Перемещение

Теперь нам известны возможные касания плиток с углами объекта и мы можем легко описать движение для Героя: если все углы проходимы, то движемся, иначе остановка. Больше действий нужно сделать, чтобы правильно разместить Героя около стены при ее касании. Наша модифицированная функция moveChar содержит 4 возможных направления касания, но нужно будет написать еще 4 раза для каждого угла. Вот как это выглядит:

//****************
// Функция: moveChar
// Назначение: Перемещение объекта (Героя или еще кого)
// Параметры:
// ob - объект,
// dirx - направление по горизонтали -1, 0, 1,
// diry - направление по вертикали -1, 0, 1
// Возвращает: true
// ****************************
function moveChar(ob, dirx, diry) {

// Получим возможные угловые плитки ограничители по вертикали (сверху)
getMyCorners (ob.x, ob.y+speed*diry, ob);
// Проверим (Идем вверх)?
if (diry == -1) {

// Проверим (Справа-Слева нет преграды)?
if (ob.upleft and ob.upright) {

// ДА – Перемещаемся.
ob.y += speed*diry;

} else {

// НЕТ – Пододвинемся к стенке
ob.y = ob.ytile*game.tileH+ob.height;
}

}

// Проверим (Идем вниз)?
if (diry == 1) {

// Проверим (Слева-Справа нет преграды)?
if (ob.downleft and ob.downright) {

// ДА – Премещаемся
ob.y += ob.speed*diry;

} else {

// НЕТ – Пододвинемся к стенке
ob.y = (ob.ytile+1)*game.tileH-ob.height;
}

}

// Получим возможные угловые плитки ограничители по горизонтали (справа)
getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);
// Проверим (Идем влево)?
if (dirx == -1) {

// Проверим (Сверху-Снизу нет препятствий)?
if (ob.downleft and ob.upleft) {

// ДА - Перемещаемся
ob.x += speed*dirx;

} else {

// НЕТ – пододвинемся к стенке
ob.x = ob.xtile*game.tileW+ob.width;
}

}

// Проверим (Идем вправо)?
if (dirx == 1) {

// Проверим (сверху-снизу нет преграды)?
if (ob.upright and ob.downright) {

// ДА – перемещаемся
ob.x += speed*dirx;

} else {

// НЕТ – пододвигаемся к стенке
ob.x = (ob.xtile+1)*game.tileW-ob.width;
}

}

// Расчитанные координаты передадим объекту
ob.clip._x = ob.x;
ob.clip._y = ob.y;

// Переходим к нужному кадру анимации перемещения
ob.clip.gotoAndStop(dirx+diry*2+3);
// Определяем координаты плитки объекта
ob.xtile = Math.floor(ob.clip._x/game.tileW);
ob.ytile = Math.floor(ob.clip._y/game.tileH);
return (true);

}

Прежде всего функция получает объект перемещения и направления перемещения по нажатым клавишам. Строка:

getMyCorners (ob.x, ob.y+ob.speed*diry, ob);

Подсчитывает препятствия по угловым точкам, в том числе и для вертикального перемещения. После этого мы определяем возможные препятствия на пути движения:

if (diry == -1) {

if (ob.upleft and ob.upright) {

ob.y += ob.speed*diry;
} else {

ob.y = ob.ytile*game.tileH+ob.height;

}

}

Этот блок кода обслуживает перемещение вверх. При перемещении вниз, опять же нужно проверить а есть ли ограничения в движении.

И если один из углов Героя встречается со стенкой, то значение свойств ob.upleft или ob.upright будет "false", мы размещаем объект около стены. Для объекта его центральная точка должна быть размещена ниже верхней границы плитки на величину char.height.

По вертикали формула ob.ytile*game.tileH размещает центр объект ниже чем надо, поэтому добавляем высоту объекта, чтобы объект встал рядом со стенкой.

Аналогичные действия функция moveChar выполняет по всем направлениям ( низ - diry == 1, лево - dirx == -1, право - dirx == 1).

Последняя строка размещает клип объекта в расчитанную позицию, определяется требуемый кадр анимации и определяются новые координаты центра объекта (xtile, ytile). Как и прежде, функция возвращает "true".

Можно загрузить исходный код и клипы отсюда.

Есть вопросы - пишите мне на semikin@dionaholding.ru

Читаем дальше - Глава 6. Открытая дверь

Возвращаемся на Начало учебника

 

Всего: 5

Электронные формы от Adobe

14 ноября с.г. компания представила новую версию всем известного средства Adobe Acrobat. 8-ая по счету версия принесла новые возможности по переходу от бумажных документов к электронным.
читать
 

АрмПарк - Универсальная учетная система

Серия материалов о программе - АрмПарк - Универсальная учетная система. Решение для тех кому необходимо быстро создать и внедрить электронную картотеку по учету - документов, матералов, оборудования, ресурсов или зеленых человечков.
читать
 

Программирование игр на основе плиток

Представляется перевод замечательного учебника по созданию движка игры на основе плиток (Tile Based Games). Я благодарен автору Tonypa за разрешение публикации перевода. Если у Вас возникают вопросы, пишите и я постараюсь Вам помочь.
читать
 

Универсальная информационная система-конструктор Учет документов (Доклад на конференции).

Доклад на Третьей практической конференции по Электронному Документообороту - "Программа "Учет документов" ", 9 декабря, Москва, Мэрия Москвы.
читать
 

Интеграция систем с использованием новых технологий

Один из ключевых моментов совершенствования электронного бизнеса - это повышение гибкости процессов за счет ускорения реализации решений в области интеграции.
читать
Всего: 5

Rambler's Top100

   
   

новости

продукты

решения

услуги

о компании

   
   
125315, Москва, Часовая ул., д.30
Телефон: (095)797-32-82; Факс: (095)797-32-81
© 2005 ООО "Диона Холдинг"
Администратор: admin@dionaholding.ru