Главная
Форум
Баннеры
ТОП Сайтов
Мониторинг серверов
Банлист Сервера
Статистика Сервера
Наши отзывы
Новые сообщения · Участники · Правила форума · Поиск · RSS
  • Страница 1 из 1
  • 1
Движок для игры-бродилки (часть 3)
DooDLeZДата: Воскресенье, 28.03.2010, 20:25 | Сообщение # 1

WebMaster
Сообщений: 485
[ ]
:-(
Вот мы и добрались до финальной части урока по созданию игры бродилки Emanuele Feronato .
Для тех, кто впервые зашел к нам «на огонек», настоятельно рекомендую ознакомиться с содержанием части 1 и части 2 данного урока.
Ну чтож, продолжаем!!!

ПОВЕРХНОСТЬ.
На данный момент мы использовали 7 типов поверхности. Пришло время ввести еще несколько. Итак мы добавляем:
Движок для игры-бродилки (часть 3)
- шипы – поверхность, которая убивает (или наносит повреждения) игрока при попадании на нее
- двери – непроходимая поверхность, которая может стать проходимой при условии наличия у игрока ключа
- наклонные поверхности - прото наклонные поверхности. Но обращаю Ваше внимание – не делайте невозможных наклонов. На рисунке зеленым цветом показаны возможные типы наклонов, а красным – невозможные.
Движок для игры-бродилки (часть 3)

Теперь, для большего реализма, пришло время ввести в нашу игру новых действующих лиц:
- монеты
- ключи
- враги
Движок для игры-бродилки (часть 3)
МОНЕТЫ
Собираем монеты – зарабатываем баллы.

КЛЮЧИ
Необходимы для прохождения игроком закрытых дверей

ВРАГИ
Ну как же без противника! Каждая игра имеет в наличии множество разнообразных врагов.

С действующими лицами определились, теперь собираем силы для последнего рывка!
Итак, код:

Code
var tile_size:Number = 20;
var ground_acceleration:Number = 1;
var ground_friction:Number = 0.8;
var air_acceleration:Number = 0.5;
var air_friction:Number = 0.7;
var ice_acceleration = 0.15;
var ice_friction:Number = 0.95;
var treadmill_speed:Number = 2;
var max_speed:Number = 3;
var xspeed:Number = 0;
var yspeed:Number = 0;
var falling:Boolean = false;
var jumping:Boolean = false;
var on_slope:Boolean = false;//наклонная ли текущая поверхность
var gravity:Number = 0.5;
var jump_speed:Number = 6;
var climbing:Boolean = false;
var climb_speed:Number = 0.8;
var level:Array = new Array();
var enemy:Array = new Array();//матрица для врага
var coin:Array = new Array();//матрица для монет
var key:Array = new Array();//матрица для ключа
level[0] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
level[1] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
level[2] = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 1];
level[3] = [1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[4] = [1, 0, 1, 2, 2, 1, 0, 4, 4, 8, 3, 3, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1];
level[5] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 1];
level[6] = [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 1, 0, 0, 0, 0, 0, 1];
level[7] = [1, 1, 1, 0, 0, 1, 0, 0, 0, 10, 1, 11, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1];
level[8] = [1, 1, 1, 1, 0, 9, 0, 0, 10, 1, 1, 1, 11, 0, 7, 0, 0, 6, 0, 0, 0, 0, 7, 0, 1];
level[9] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 4, 4, 1, 8, 1, 8, 1];
var walkable_tiles:Array = Array(0, 5, 6, 7, 10, 11);//отдельно определяем типы поверхностей сквозь которые может двигаться игрок
var player:Array = [10, 6];
enemy[0] = [10, 3, -2];//позиция для первого врага, первые 2 элемента - координаты х и у, третий элемент - скорость движения
enemy[1] = [3, 3, -2];//позиция для второго врага, первые 2 элемента - координаты х и у, третий элемент - скорость движения
coin[0] = [2, 2];//позиция первой монеты, х и у
coin[1] = [23, 4];//позиция второй монеты, х и у
key[0] = [1, 5, 5, 8];//позиция ключа, х и у и позиция двери х и у
//==========смерть игрока=========================
function place_player() {//удаляем игрока с карты и аттачим его вновь в начальных координатах
level_container.hero.removeMovieClip();
x_pos = player[0]*tile_size+tile_size/2;
y_pos = player[1]*tile_size+tile_size/2+1;
level_container.attachMovie("hero","hero",_root.level_container.getNextHighestDepth(),{_x:x_pos, _y:y_pos});
}
//======создаем карту уровня==========
function create_level(l) {
_root.createEmptyMovieClip("level_container",1);     
level_height = l.length;     
level_width = l[0].length;     
for (y=0; y<level_height; y++) {     
    for (x=0; x<level_width; x++) {     
     if (l[y][x] != 0) {
      t = level_container.attachMovie("tile", "t"+y+"_"+x, _root.level_container.getNextHighestDepth(), {_x:x*tile_size, _y:y*tile_size});
      t.gotoAndStop(l[y][x]);
     }
    }     
}     
place_player();     
for (x=0; x<coin.length; x++) {//размещаем монеты на карте     
    coin_mc = level_container.attachMovie("coin", "coin_"+_root.level_container.getNextHighestDepth(), _root.level_container.getNextHighestDepth(), {_x:coin[x][0]*tile_size+tile_size/2, _y:coin[x][1]*tile_size+tile_size/2+1});     
    coin_mc.onEnterFrame = function() {     
     if (this.hitTest(level_container.hero._x, level_container.hero._y, true)) {//если герой пересекается с монетой она удаляется (сюда же надо добавить и счетчик баллов)
      this.removeMovieClip();
     }
    };     
}     
for (x=0; x<key.length; x++) {//размещаем на карте ключи     
    key_mc = level_container.attachMovie("key", "key"+_root.level_container.getNextHighestDepth(), _root.level_container.getNextHighestDepth(), {_x:key[x][0]*tile_size+tile_size/2, _y:key[x][1]*tile_size+tile_size/2+1});     
    key_mc.ind = x;     
    key_mc.onEnterFrame = function() {     
     if (this.hitTest(level_container.hero._x, level_container.hero._y, true)) {//если герой пересекается с ключем - значение ячейки с дверью в массиве меняется на 0, клип с дверью удаляется с карты, ключ также удаляется
      open_x = [key[this.ind][2]];
      open_y = [key[this.ind][3]];
      level[open_y][open_x] = 0;
      _root.level_container["t"+open_y+"_"+open_x].removeMovieClip();
      this.removeMovieClip();
     }
    };     
}     
for (x=0; x<enemy.length; x++) {//размещаем врагов на карте     
    foe = level_container.attachMovie("patrol", "patrol_"+_root.level_container.getNextHighestDepth(), _root.level_container.getNextHighestDepth(), {_x:enemy[x][0]*tile_size+tile_size/2, _y:enemy[x][1]*tile_size+tile_size/2+1});
    foe.speed = enemy[x][2];
    foe.onEnterFrame = function() {//позиционируем врагов на карте (аналогично функции function get_edges() для игрока) и задаем математику движения
     this.x_pos = this._x;
     this.y_pos = this._y;
     this.x_pos += this.speed;
     this.left_foot_x = Math.floor((this.x_pos-6)/tile_size);
     this.right_foot_x = Math.floor((this.x_pos+5)/tile_size);
     this.foot_y = Math.floor((this.y_pos+9)/tile_size);
     this.bottom = Math.floor((this.y_pos+8)/tile_size);
     this.left_foot = level[this.foot_y][this.left_foot_x];
     this.right_foot = level[this.foot_y][this.right_foot_x];
     this.left = level[this.bottom][this.left_foot_x];
     this.right = level[this.bottom][this.right_foot_x];
     if (this.left_foot != 0 and this.right_foot != 0 and this.left == 0 and this.right == 0) {
      this._x = this.x_pos;
     } else {
      this.speed *= -1;
     }
    };     
}     
}       
create_level(level);       
//======определяем варианты движения героя по разным типам поверхности===============       
function ground_under_feet() {       
bonus_speed = 0;     
left_foot_x = Math.floor((x_pos-6)/tile_size);     
right_foot_x = Math.floor((x_pos+5)/tile_size);     
foot_y = Math.floor((y_pos+9)/tile_size);     
left_foot = level[foot_y][left_foot_x];     
right_foot = level[foot_y][right_foot_x];     
if (left_foot != 0) {     
    current_tile = left_foot;
} else {     
    current_tile = right_foot;
}     
switch (current_tile) {//если значение текущей поверхности ….     
    case 0 :
     over = "air";
     speed = air_acceleration;
     friction = air_friction;
     falling = true;
     break;
    case 1 :
     over = "ground";
     speed = ground_acceleration;
     friction = ground_friction;
     break;
    case 2 :
     over = "ice";
     speed = ice_acceleration;
     friction = ice_friction;
     break;
    case 3 :
     over = "treadmill";
     speed = ground_acceleration;
     friction = ground_friction;
     bonus_speed = -treadmill_speed;
     break;
    case 4 :
     over = "treadmill";
     speed = ground_acceleration;
     friction = ground_friction;
     bonus_speed = treadmill_speed;
     break;
    case 5 :
     over = "cloud";
     speed = ground_acceleration;
     friction = ground_friction;
     break;
    case 6 :
     over = "ladder";
     speed = ground_acceleration;
     friction = ground_friction;
     break;
    case 7 :
     over = "trampoline";
     speed = ground_acceleration;
     friction = ground_friction;
     break;
    case 8 ://...равно 1, то "под ногами" игрока "шипы"     
     over = "spikes";
     if (left_foot == 8 and right_foot == 8) {//если игрок обоими ногами находится на этой поверхностью он умирает
      place_player();
     }
    default ://для прочих значений поверхности задаем скорость движения и скольжения     
     over = "ground";
     speed = ground_acceleration;
     friction = ground_friction;
     break;
}     
}       
//=======позиционируем игрока===============       
function get_edges() {       
right = Math.floor((x_pos+5)/tile_size);     
left = Math.floor((x_pos-6)/tile_size);     
bottom = Math.floor((y_pos+8)/tile_size);     
top = Math.floor((y_pos-9)/tile_size);     
top_right = level[top][right];     
top_left = level[top][left];     
bottom_left = level[bottom][left];     
bottom_right = level[bottom][right];     
}       
//====проверка поверхности на возможность идти сквозь нее=================       
function is_walkable(tile) {       
walkable = false;//движение сквозь - запрещено     
if (!on_slope) {//если тип поверхности не наклоная, то….     
    for (x=0; x<walkable_tiles.length; x++) {     
     if (tile == walkable_tiles[x]) {//проверяем есть ли данная поверхность в массиве поверхностей, через которые возможно движение, если да, то движение разрешено
      walkable = true;
      break;
     }
    }     
} else {//если наклонная поверхность, то движение разрешено     
    walkable = true;     
}     
return (walkable);     
}       
//========движение по наклонным поверхностям==============       
function is_on_slope() {       
on_slope = false;//по умолчанию поверхность не наклонна     
x_slope_detector = Math.floor(x_pos/tile_size);//определяем позицию ячейки по позиции игрока     
y_slope_detector = Math.floor(y_pos/tile_size);//определяем позицию ячейки по позиции игрока     
if (jumping or falling) {//если игрок в прыжке или падении     
    if (level[y_slope_detector][x_slope_detector] == 10 or level[y_slope_detector][x_slope_detector] == 11) {//если тут - "наклонная поверхность" то в зависимости от ее типа определяем х позицию склона     
     if (level[y_slope_detector][x_slope_detector] == 10) {
      x_offset = tile_size-x_pos%tile_size;
     }
     if (level[y_slope_detector][x_slope_detector] == 11) {
      x_offset = x_pos%tile_size;
     }
     if (y_pos>Math.floor(y_pos/tile_size)*tile_size-9+x_offset) {
     // здесь возможен дополнительный код для усложнения повторного прыжка
     }
    }     
}     
if (!jumping and !falling) {//если игрок не в прыжке и не в падении, то  в зависимости от типа наклонной поверхности изменяем положение игрока по вертикали     
    if (level[y_slope_detector+1][x_slope_detector] == 10 or level[y_slope_detector+1][x_slope_detector] == 11) {     
     y_pos = (y_slope_detector+1)*tile_size+tile_size/2+1;
     y_slope_detector += 1;
    }     
    if (level[y_slope_detector][x_slope_detector] == 10 or level[y_slope_detector][x_slope_detector] == 11) {     
     if (level[y_slope_detector][x_slope_detector] == 10) {
      x_offset = tile_size-x_pos%tile_size;
     }
     if (level[y_slope_detector][x_slope_detector] == 11) {
      x_offset = x_pos%tile_size;
     }
     y_pos = Math.floor(y_pos/tile_size)*tile_size-9+x_offset;
     on_slope = true;
    }     
}     
if (!jumping and !falling and !on_slope and over != "ladder") {//если игрок не прыгает, не падает, не находится на наклонной поверхности и не на лестнице определяем его положение по вертикали.     
    y_pos = (y_slope_detector)*tile_size+tile_size/2+1;     
}     
}       
//========столкновение с препятствиями====================       
function check_collisions() {       
    //====столкновения при движении по вертикали===============       
get_edges();       
is_on_slope();//движение по наклонным поверхностям       
y_pos += yspeed;       
get_edges();       
if (yspeed>0 and !on_slope) {//код идентичен коду урока 2 лишь добавленна проверка на наклонность поверхности       
    if ((bottom_right != 0 and bottom_right != 6 and bottom_right != 10 and bottom_right != 11) or (bottom_left != 0 and bottom_left != 6 and bottom_left != 10 and bottom_left != 11)) {     
     if (bottom_right != 5 and bottom_left != 5) {     
      if ((bottom_right == 7 or bottom_left == 7) and (Math.abs(yspeed)>1)) {
       yspeed = yspeed*-1;
       jumping = true;
       falling = true;
      } else {
       y_pos = bottom*tile_size-9;
       yspeed = 0;
       falling = false;
       jumping = false;
      }
     } else {     
      if (prev_bottom<bottom) {
       y_pos = bottom*tile_size-9;
       yspeed = 0;
       falling = false;
       jumping = false;
      }
     }     
    }     
}       
if (yspeed<0) {       
    if ((top_right != 0 and top_right != 5 and top_right != 6) or (top_left != 0 and top_left != 5 and top_left != 6)) {     
     y_pos = bottom*tile_size+9;     
     yspeed = 0;     
     falling = false;
     jumping = false;
    }
}     
    //====столкновения при движении по горизонтали===============     
x_pos += xspeed;     
get_edges();     
if (xspeed<0) {     
    // во второй части урока данная строка выглядела так - "if ((top_left != 0 and top_left != 5 and top_left != 6 and top_left != 7) or (bottom_left != 0 and bottom_left != 5 and bottom_left != 6 and bottom_left != 7))" теперь, оптимизировав код и выделив отдельно типы поверхности, сквозь которые можно проходить, мы упрощаем запись:
    if (!is_walkable(top_left) or !is_walkable(bottom_left)) {
     x_pos = (left+1)*tile_size+6;
     xspeed = 0;
    }
}     
if (xspeed>0) {     
    if (!is_walkable(top_right) or !is_walkable(bottom_right)) {
     x_pos = right*tile_size-6;
     xspeed = 0;
    }
}     
prev_bottom = bottom;     
}     
//========двигаемся по карте===========     
_root.onEnterFrame = function() {     
ground_under_feet();     
walking = false;     
climbing = false;     
if (Key.isDown(Key.LEFT)) {     
    xspeed -= speed;
    walking = true;
}     
if (Key.isDown(Key.RIGHT)) {     
    xspeed += speed;
    walking = true;
}     
if (Key.isDown(Key.UP)) {     
    get_edges();
    if (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6) {
     jumping = false;
     falling = false;
     climbing = true;
     climbdir = -1;
    }
}     
if (Key.isDown(Key.DOWN)) {     
    get_edges();
    if ((over == "ladder") or (top_right == 6 or bottom_right == 6 or top_left == 6 or bottom_left == 6)) {
     jumping = false;
     falling = false;
     climbing = true;
     climbdir = 1;
    }
}     
if (Key.isDown(Key.SPACE)) {     
    //get_edges();
    if (!falling and !jumping) {
     jumping = true;
     yspeed = -jump_speed;
    }
}     
if (!walking) {     
    xspeed *= friction;
    if (Math.abs(xspeed)<0.5) {
     xspeed = 0;
    }
}
if (xspeed>max_speed) {
    xspeed = max_speed;
}
if (xspeed<max_speed*-1) {
    xspeed = max_speed*-1;
}
if (falling or jumping) {
    yspeed += gravity;
}
if (climbing) {
    yspeed = climb_speed*climbdir;
}
if (!falling and !jumping and !climbing) {
    yspeed = 0;
}
xspeed += bonus_speed;
check_collisions();
level_container.hero._x = x_pos;
level_container.hero._y = y_pos;
xspeed -= bonus_speed;
};

И вот, после долгих стараний, итоговая верстия нашей игры:


  • Страница 1 из 1
  • 1
Поиск:


Все права принадлежат PainKiller.Net.Ru 2009-2010. Дизайн сайта разработан - PainKiller.Net.Ru
Внимание! Рип шаблона запрещен "Нарушение авторского права"! Design bY PainKiller.Net.Ru
Тиц и pr сайта