(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Уроки Flash: Metro Siberia Undeground (Часть 5)

Источник: demiart
Emanuele Ferontano (Перевод: Stasan)

Это заключительная часть туториала, по созданию игры MSU, она будет посвящена созданию дополнительных возможностей отсутствующих в оригинальной версии игры. В принципе всегда когда пишите клон игры, надо добавлять различные особенности иначе ваша игра не привлечет никакого внимания. Моя идея заключается в том, чтобы добавить в игру оружие. Вы можете сказать, что оригинальностью она не блещет, и в Интернете полно уроков по созданию стреляющих космических кораблей. Однако, просьба не забывать, что MSU это игра в которой используется лишь одна кнопка, и эта кнопка уже задействована для запуска двигателя. Я хочу сделать так чтобы, оружие работало постоянно, и уничтожало не только камни, но и резервуары с топливом, что заметно усложняет процесс их поднятия, а следовательно и всю игру.
Если вы не читали предыдущие уроки, то перед продолжением рекомендую прочесть их: Часть 1, Часть 2 и Части 3-4.

Ну, поехали. Сперва создадим новый Movie Clip, назовем его beam_spot, врубим linkage, внутри рисуем маленький красный шарик размером 2 на 2 пикселя и выравниваем его по центру.
Возвращаемся в рут на первом кадре пишем следующий код:

CODE

1. import flash.filters.GlowFilter;
2. var ship_filter:GlowFilter = new GlowFilter(0x00ff00, 0.8, 4, 4, 2, 3, false, false);
3. var smoke_filter:GlowFilter = new GlowFilter(0xff0000, 0.8, 4, 4, 2, 3, false, false);
4. var tunnel_filter:GlowFilter = new GlowFilter(0xffff00, 0.8, 4, 4, 2, 3, false, false);
5. var fuel_filter:GlowFilter = new GlowFilter(0x00ffff, 0.8, 4, 4, 2, 3, false, false);
6. var rock_filter:GlowFilter = new GlowFilter(0xffffff, 0.8, 4, 4, 2, 3, false, false);
7. var score_filter:GlowFilter = new GlowFilter(0xff00ff, 0.8, 2, 4, 2, 3, false, false);
8. gravity = 0.1;
9. thrust = 0.25;
10. yspeed = 0;
11. xspeed = 5;
12. distance = 0;
13. smoke_interval = 10000;
14. frames_passed = 0;
15. tunnel_height = 150;
16. fuel_freq = 10;
17. gasoline = 500;
18. rock_freq = 50;
19. engines = false;
20. _root.attachMovie("ship", "ship", _root.getNextHighestDepth(), {_x:150, _y:200});
21. _root.createEmptyMovieClip("beam", _root.getNextHighestDepth());
22. _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
23. _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
24. _root.attachMovie("score", "score", _root.getNextHighestDepth());
25. _root.attachMovie("beam_spot", "beam_spot", _root.getNextHighestDepth());
26. beam.filters = new Array(smoke_filter);
27. beam_spot.filters = new Array(smoke_filter);
28. ship.filters = new Array(ship_filter);
29. score.filters = new Array(score_filter);
30. ship.onEnterFrame = function() {
31.     score.sc.text = "Distance: "+distance+" - "+"Fuel: "+gasoline;
32.     if ((gasoline>0) and (engines)) {
33.         yspeed -= thrust;
34.         smoke_interval -= 0.25;
35.         gasoline -= 1;
36.     }
37.     if (Math.random()*1000<fuel_freq) {
38.         fuel = fuel_movie.attachMovie("fuel", "fuel"+fuel_movie.getNextHighestDepth(), fuel_movie.getNextHighestDepth(), {_x:510, _y:Math.random()*400+50});
39.         fuel.filters = new Array(fuel_filter);
40.         fuel.onEnterFrame = function() {
41.             this._x -= (xspeed*1.2);
42.             if (this.hitTest(beam_spot)) {
43.                 this._alpha -=5;
44.                 if (this._alpha<0) {
45.                     this.removeMovieClip();
46.                 }
47.             }
48.             dist_x = ship._x+28*Math.cos(angle)-this._x;
49.             dist_y = ship._y+28*Math.sin(angle)-this._y;
50.             dist = Math.sqrt(dist_x*dist_x+dist_y*dist_y);
51.             if (dist<10) {
52.                 gasoline += 100;
53.                 this.removeMovieClip();
54.             }
55.             if (this._x<-10) {
56.                 this.removeMovieClip();
57.             }
58.         };
59.     }
60.     if (Math.random()*1000<rock_freq) {
61.         rock = deadly_movie.attachMovie("rock", "rock"+deadly_movie.getNextHighestDepth(), deadly_movie.getNextHighestDepth(), {_x:510, _y:Math.random()*400+50, _rotation:Math.random()*360});
62.         rock.filters = new Array(rock_filter);
63.         rock.onEnterFrame = function() {
64.             this._x -= xspeed;
65.             if (this.hitTest(beam_spot)) {
66.                 this._alpha -=3;
67.                 if (this._alpha<0) {
68.                     this.removeMovieClip();
69.                 }
70.             }
71.             if (this._x<-10) {
72.                 this.removeMovieClip();
73.             }
74.         };
75.     }
76.     yspeed += gravity;
77.     this._y += yspeed;
78.     angle = Math.atan2(yspeed, xspeed);
79.     this._rotation = angle*180/Math.PI;
80.     beam.clear();
81.     beam.lineStyle(1, 0xffff00, 10+40*Math.random());
82.     beam.moveTo(this._x+30*Math.cos(angle), this._y+30*Math.sin(angle));
83.     for (x=1; x<=250; x++) {
84.         to_x = this._x+(30+x)*Math.cos(angle);
85.         to_y = this._y+(30+x)*Math.sin(angle);
86.         if ((deadly_movie.hitTest(to_x, to_y, true))or(fuel_movie.hitTest(to_x, to_y, true))) {
87.             break;
88.         }
89.     }
90.     beam.lineTo(to_x, to_y);
91.     beam_spot._x = to_x;
92.     beam_spot._y = to_y;
93.     frames_passed++;
94.     distance += xspeed;
95.     if (frames_passed>=smoke_interval) {
96.         sm = _root.attachMovie("smoke", "smoke"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:this._x-2, _y:this._y});
97.         sm.filters = new Array(smoke_filter);
98.         sm.onEnterFrame = function() {
99.             this._x -= xspeed;
100.             this._width += 0.2;
101.             this._height += 0.2;
102.             this._alpha -= 2;
103.             if (this._alpha<=0) {
104.                 this.removeMovieClip();
105.             }
106.         };
107.         frames_passed = 0;
108.     }
109.     if ((this._y>400) or (this._y<0) or deadly_movie.hitTest(this._x+28*Math.cos(angle), this._y+28*Math.sin(angle), true) or deadly_movie.hitTest(this._x+8*Math.cos(angle+Math.PI/2), this._y+8*Math.sin(angle+Math.PI/2), true) or deadly_movie.hitTest(this._x+8*Math.cos(angle-Math.PI/2), this._y+8*Math.sin(angle-Math.PI/2), true)) {
110.         yspeed = 0;
111.         this._y = 200;
112.         gasoline = 500;
113.         distance = 0;
114.         deadly_movie.removeMovieClip();
115.         fuel_movie.removeMovieClip();
116.         _root.createEmptyMovieClip("fuel_movie", _root.getNextHighestDepth());
117.         _root.createEmptyMovieClip("deadly_movie", _root.getNextHighestDepth());
118.     }
119. };
120. _root.onMouseDown = function() {
121.     engines = true;
122.     smoke_interval = 10;
123. };
124. _root.onMouseUp = function() {
125.     engines = false;
126.     smoke_interval = 100000;
127. };

Пых, впечатляет правда? Давайте приступим к разбору того, что мы тут наворотили, как обычно будут объяснены только новые фрагменты кода.

21. Создаем новый Movie Clip, в котором разместим лазерный луч, это будет простая линия.
25.Аттачим beam_spot, он будет обозначать конец лазерного луча.
26-27.Применяем фильтры к созданным символам, т.к. я хочу, чтобы лазер светился красноватым цветом, то применяю фильтр созданный для дыма.
80. Очищаем Movie Clip с лучом.
81. Для Movie Clip"a с лучом устанавливаем стиль рисования.
82. Рисуем лазерный луч перед кораблем используя тригонометрию.
83. Начало цикла который, будет выполняться 250 раз, т.к. ширина лазерного луча 250 px.
84-85. Используя тригонометрию, я определяю, где будет x-овый по счету пиксель луча при заданном повороте корабля.
86-88. Если х-овый пиксель касается астероида или резервуара с топливом, выходим из цикла for.
90. Рисуем линию лазера по пиксель который дал положительный hitTest, или рисуем луч размером 250 px если такого нет.
91-92. Передвигаем beam_spot на конец лазерного луча.

Что ж теперь мы можем определит когда лазерный луч пересекает астероид или цистерну, но мы не знаем какой точно из символов оказался на пути луча.
Мы можем провести hitTest между шариком на конце лазера и каждым астероидом и резервуаром.

42. hitTest между шариком и цистерной с топливом.
43. Если верно делаем цистерну более прозрачной.
44-46. Если резервуар становится полностью прозрачным, то удаляем его.

65-70. Аналогичные действия для астероидов.

Вот что у нас получилось:

Файлы для загрузки


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 01.07.2008 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
TeeChart Pro VCL/FMX with source code single license
WinRAR 5.x Standard Licence - для частных лиц 1 лицензия
Enterprise Connectors (1 Year term)
JIRA Software Commercial (Cloud) Standard 10 Users
SAP Crystal Reports 2008 INTL WIN NUL License
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Программирование в AutoCAD
Компьютерный дизайн - Все графические редакторы
Утиль - лучший бесплатный софт для Windows
Windows и Office: новости и советы
3D и виртуальная реальность. Все о Macromedia Flash MX.
Краткие описания программ и ссылки на них
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100