Уроки Flash: Metro Siberia Undeground (Частина 5), Програми для роботи з графікою, Програмні керівництва, статті

Це заключна частина туторіал, по створенню гри 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. Аналогічні дії для астероїдів.


Ось що у нас вийшло:


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*