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

   
Новости  
   

Глава 8. Лестницы

Лестницы – это одна из общих форм движения в игровых платформах. Герой может использовать лестницы, чтобы подняться или опуститься на нужные плитки. Научим Героя лазать вверх или вниз по лестнице при нажатии клавиш вверх-вниз, кроме этого Герой будет останавливаться около лестницы.

Пока лестницы выглядят легкими, самое время решить кое-какие проблемы. Первое, какие это лестницы?

(Глядя на картинку, скажу – приставные.)

На картинке 4 типа лестницы. На плитке А лестница внутри плитки ( с нижней на верхнюю грань плитки А или черный ход с плитки В на плитку выше А ), да и плитка не проходима. Что может делать Герой на плитке А? Он может подняться вверх или спуститься, но он не может пойти влево-вправо, иначе он застрянет в стене. Спроси любого, кто застревал в стене, и они скажут, - самочувствие не из лучших. (Здесь Герой лазает по лестницам по внешним стенкам.)

Лестница на плитке В стоит на проходимой плитке, да плитка сверху тоже имеет лестницу, так что Герой может подниматься и опускаться по лестнице. Герой может пойти влево-вправо, но при этом он упадет с лестницы. (Опять же особенности проекции, вид не сверху, а с фронта и движение по У – движение вверх.)

Лестница на плитке С, такая же, как на плитке В, только лестницы внизу нет. Герою некуда спускаться, только вверх (в облака) или влево-вправо.

Лестница D стоит на проходной плитке, только упирается в небо, и показывает ошибку дизайна уровня. (Как знать, может то, что надо!) Герой может подняться по лестнице и на ней заночевать или спрыгнуть? Может ли он прыгнуть направо и остаться на плитке рядом с лестницей?

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

Правила

Напишем некоторые правила для лестниц и Героя, перемещающегося по ним:

  1. Герой перемещается по лестнице с помощью клавиш ВВЕРХ-ВНИЗ.
  2. Герой перемещается вверх, если на плитке есть лестница.
  3. Герой перемещается вниз, если лестница есть на нижей плитке и касается верхней плитки.
  4. Герой может перемещаться влево/вправо с лестницы, если не будет касаться стены.
  5. Герой не может прыгать с лестницы и на лестнице.

(Последнее ограничение действительно опасно для Героя, если лестница, такая, как нарисована.)

Это пока все.

Одну лестницу, пожалста

Мы будем использовать отдельный клип с рисунком лестницы при создании плитки с лестницей. Пока, нам не требуется углубляться в дебри рисования изображения каждой лестницы на разном фоне. Для присоединения клипа лестницы к объекту, в библиотеке в свойство "Export this movie" клипа с лестницей впишем "ladder".

В клипе лестница нарисована во всю плитку и по центру.

Как и с любой плиткой, объявим новый тип плитки для лестницы:

// Один тип лестницы – не проходной
game.Tile7= function () {};
game.Tile7.prototype.walkable=false;
game.Tile7.prototype.frame=2;
game.Tile7.prototype.ladder=true;
game.Tile7.prototype.item="ladder";

// Другой тип лестницы – проходной
game.Tile8= function () {};
game.Tile8.prototype.walkable=true;
game.Tile8.prototype.frame=1;
game.Tile8.prototype.ladder=true;
game.Tile8.prototype.item="ladder";

Два типа лестниц – проходные и нет, с разным номером кадра для показа, но с одинаковыми свойствами – item - Наименование - будем использовать его, чтобы присоединить картинку к плитке, и lader - статус плитки - будем использовать для проверки наличия Героя рядом с лестницей.

Присоединение клипа с лестницей к плитке производится в функции buildMap после перехода к корректному кадру показа плитки:

game.clip[name].gotoAndStop(game[name].frame);
// Проверим (Рядом ЕСТЬ лестница)
if (game[name].item != undefined) {


// ДА – присоединяем клип с лестнице
game.clip[name].attachMovie(game[name].item, "item", 1);
}

Этот код проверяет наличие свойства item и, если свойство в текущей плитке имеется, то ее клип привоединяется к общей структуре клипов. Так можно присоединить разные клипы, но ВНИМАНИЕ!! прошу вас, не присоединяйте много клипов к одной плике, ничего хорошего из этого не получится, морока одна.

Чтобы не вводить дважды один и тот же код, давайте перейдем к функции moveChar и посмотрим на ее окончание. Введем новую функцию updateChar и конец функции moveChar будет выглядеть так.

updateChar (ob, dirx, diry);
return (true);

А функция updateChar будет содержать:

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

// Запомним координаты Х / У в свойствах клипа
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);
// Проверим (Плитка под объектом Дверь и это Герой)?
if (game["t_"+ob.ytile+"_"+ob.xtile].door and ob==_root.char) {

// ДА – Меняем карту игры
changeMap(ob);
}

}

В функцию fall добавим:

// Свойство объекта – ползет по лестнице – установим в 0
ob.climb = false;

Изменим и функцию detectKeys для учета нажатия новых клавиш:

// Проверим (Нажато ВПРАВО)?
if (Key.isDown(Key.RIGHT)) {

// Получить препятствия по углам
getMyCorners (ob.x-ob.speed, ob.y, ob);
// Проверим (Герой НЕ на лестнице и Препятствий нет)?
if (!ob.climb or ob.downleft and ob.upleft and ob.upright and ob.downright) {

// ДА – значит идем направо
keyPressed=_root.moveChar(ob, 1, 0);
}

// НЕТ - Проверим (Нажато ВЛЕВО)?
} else if (Key.isDown(Key.LEFT)) {

// Получить препятствия по углам
getMyCorners (ob.x-ob.speed, ob.y, ob);
// Проверим (Герой НЕ на лестнице и Препятствий нет)?
if (!ob.climb or ob.downleft and ob.upleft and ob.upright and ob.downright) {

// ДА – значит идем влево
keyPressed=_root.moveChar(ob, -1, 0);
}

// НЕТ - Проверим (Нажато ВВЕРХ)?
} else if (Key.isDown(Key.UP)) {

// ДА - Проверим (Герой НЕ в прыжке и лестница вверх есть рядом)?
if (!ob.jump and checkUpLadder (ob)) {

// ДА – значит поднимаемся вверх по лестнице
keyPressed=_root.climb(ob, -1);
}

// НЕТ - Проверим (Нажато ВНИЗ)?
} else if (Key.isDown(Key.DOWN)) {

// ДА - Проверим (Герой НЕ в прыжке и лестница вниз рядом есть)?
if (!ob.jump and checkDownLadder (ob)) {

// ДА – значит поднимаемся вверх по лестнице
keyPressed=_root.climb(ob, 1);
}

}

После определения нажатия клавиш ВЛЕВО/ВПРАВО будем проверять - Герой торчит на лестнице (!ob.climb) или нет, а также есть ли у него препятствия.

Для клавиш ВВЕРХ/ВНИЗ, в первую очередь, проверим состояние Героя - не летит ли он в прыжке, и наличие лестниц с помощью двух новых функций: checkUpLadder и checkDownLadder. Если все нормально, новая функция climb перемещает Героя.

Функции перемещения по лестнице

Создадим 3 новые функции для перемещения Героя по лестнице, 1-ая функция – проверка возможности перемещения вверх, 2-ая функция – проверка возможности перемещения вниз, 3-я функция – перемещение объекта по лестнице.

//****************
// Функция: checkUpLadder
// Назначение: Проверка наличия лестницы вверх
// Параметры:
// ob - объект
// Возвращает:
// true - Есть
// false - НЕТ
// ****************************
function checkUpLadder (ob) {

// Определим позицию плитки Выше и Ниже объекта
// Надо быть внимательным к именованию переменных,
// Flash 8 различает строчные и прописные буквы в имени переменных
var downY = Math.floor((ob.y+ob.height-1)/game.tileH);
var upY = Math.floor(((ob.y-ob.height)-ob.speed)/game.tileW);

// Запомним свойство ladder плиток слева-справа, оно божет быть и undefined
var upLadder = game["t_"+upY+"_"+ob.xtile].ladder;
var downLadder = game["t_"+downY+"_"+ob.xtile].ladder;

// Запомним и проходимость плитки сверху
var upBlock = game["t_"+upY+"_"+ob.xtile].walkable;

// Проверим (Лестница наверх ЕСТЬ или Плитка сверху ПРОХОДИМА)?
if(upLadder==true or upBlock ==true){

// ДА – Проверим (Лестница вверх/вниз есть)?
if(upLadder or downLadder){

// ДА - конец
return(true);
}

}else{

// НЕТ – Вычислим координату У для объекта
ob.y = ob.ytile*game.tileH+ob.height;
// Обновим объект при движении вниз
updateChar(ob, 0, -1);
return(false)
}

}

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

//****************
// Функция: checkDownLadder
// Назначение: Проверка наличия лестницы вниз
// Параметры:
// ob - объект
// Возвращает:
// true - Есть
// false - НЕТ
// ****************************
function checkDownLadder (ob) {

// Вычислим позицию плитки под объектом, т.е. ниже объекта
var downY = Math.floor((ob.speed+ob.y+ob.height)/game.tileH);

// Запомним наличие там лестницы
var downLadder = game["t_"+downY+"_"+ob.xtile].ladder;

// Проверим (Есть внизу лестница)?
if (downLadder) {

// ДА - конец
return (true);

} else {

// НЕТ – значит падаем
fall (ob);
}

}

Для проверки перемещения вниз, нам необходимо проверить, а есть ли лестница ниже Героя. Но по сравнению с перемещением вверх, позицию нижней плитки определяем по формуле – (ob.speed+ob.y+ob.height)/game.tileH. Далее аналогично предыдущей функции.

//****************
// Функция: climb
// Назначение: Перемещение по лестнице вверх/вниз
// Параметры:
// ob - объект
// diry - направление перемещения по вертикали (-1 – вверх, 1 – вниз)
// Возвращает:
// ****************************
function climb (ob, diry) {

// Переводим объект в состояние – Ползет по лестнице
ob.climb=true;
// Состояние объекта – Не в прыжке
ob.jump=false;
// Изменяем У координату в соответствии с направлением перемещения
ob.y += ob.speed*diry;
// Вычисляем координату по Х, выравниваем объект по центру плитки
ob.x = (ob.xtile *game.tileW)+game.tileW/2;
// Обновляем объект
updateChar (ob, 0, diry);
return (true);

}

В функции climb , в первую очередь, устанавливаем значение флага перемещения climb – true, а флага jump - false. Затем вычисляем новую координату У нашего Героя. Потом установим Х координату Героя в центре лестницы.

ob.x = (ob.xtile *game.tileW)+game.tileW/2;

Герой подимается и его центр находится в пределах плитки, но было бы странно видеть перемещение по краю лестницы. (Это только для каскадеров, цирковых артистов и жуликов.)

Поэтому обновим текущую позицию объекта, используя туже функцию updateChar.

Исправление ошибок. 05.02.2005. Функция checkUpLadder была переписана по предложениям Эрика Лайобиса (Eric Liobis). Старая версия функции некорректно определяла стены из плиток без лестниц, для Героя перемещающегося по лестнице.

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

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

Читаем дальше - Глава 9. Глупый враг

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

 

Всего: 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