Итак, начинается новый раздел - экспресс программирование. Здесь я буду писать как и что можно быстро сделать на флэше. Также здесь же будут разные эксперименты.
Сейчас же я расскажу как быстро сделать игру на флэш - космический шутер (что-то вроде invaders). Цель на сегодня - сделать одноуровневую игру меньше чем за час.1. Создаю новый документ, делаю несколько мувиклипов: себя (треугольничек-мувиклип, имя - hero), врага (треугольничек-мувиклип, повёрнутый в другую сторону, имя - alien), свою пулю (её я решил сделать отдельно от вражеских пуль, пусть различаются хоть как-нибудь, имя - myBullet), вражескую пулю (alBullet).
2. Делаю два кадра: в первом будет надпись "Нажмите пробел для старта", во втором будет происходить весь игровой процесс. Все мувиклипы, созданные в пункте 1, должны быть на втором кадре!
3. Теперь время писать код. Сначала переменные: shoot - флажок, обозначает выстрелил ли я уже или нет (если false, то могу выстрелить, если true - нет), d и d2 - depth врагов. Тоже самое с bulletd и bulletd2 - depth пуль. Теперь поподробнее про это: во Flash нужно, чтобы все объекты, создаваемые в процессе игры, имели свою глубину. Если у двух или более объектов одинаковая глубина, флэш начинает тупить. Чтобы легче было контролировать все эти объекты, они будут пронумерованы. Например: alien0, alien1, alien2 ... Я предпочитаю for(i=d2;i<d;i++){ - получается проход по всем объектам от d2 до d. Чтобы, например, пройтись по aliens0,aliens1,aliens2,...,aliens19, нужно ввести:for(i=0;i<20;i++){ , затем в теле цикла достаточно будет написать _root["aliens"+i] , чтобы ссылаться поочерёдно на все объекты (aliens0,aliens1,aliens2,...,aliens19).
4. Объявляем переменные и заполняем экран врагами:
stop();
d = d2 = 0;
bulletd = bulletd2 = 100;
shoot = false;
for (i=0; i<10; i++) {
for (i2=0; i2<5; i2++) {
alien.duplicateMovieClip("al"+d,d);
_root["al"+d]._x = i*50+50;
_root["al"+d]._y = i2*50+50;
_root["al"+d].xSpeed = 1;
d++;
}
}
5. Затем нужно прописать _root.onEnterFrame = function(){ /*тело функции*/ }. Тогда то, что находится в теле функции будет выполняться 24 раза в секунду (по умолчанию, чтобы изменить - измените fps ролика). Теперь нужно реализовать стрельбу. Принцип такой: у вас всего одна пуля. Выстрелив, вы не можете стрелять, пока она во что-нибудь не врежется (или не улетит за пределы).
_root.onEnterFrame = function() {6. Описываем поведение врагов:
if (shoot == false && Key.isDown(Key.SPACE)) {
shoot = true;
myBullet._x = hero._x;
myBullet._y = hero._y;
}
if(shoot == true){
myBullet._y -= 10;
}else{
myBullet._x = -100;
}
if(myBullet._y < -50){
shoot = false;
}
}
if (d != d2) {7. Описываем поведение вражеских пуль:
for (i=d2; i<d; i++) {
if (_root["al"+i]) {
_root["al"+i]._x += _root["al"+i].xSpeed*5;
if(_root["al"+i].hitTest(myBullet)){
_root["al"+i].removeMovieClip();
shoot = false;
}
if (_root["al"+i]._x>530) {
_root["al"+i].xSpeed = -1;
}
if (_root["al"+i]._x<20) {
_root["al"+i].xSpeed = 1;
}
//random(200) - означает, что действие (здесь - стрельба врагов) будет выполняться
//в среднем раз в 200 проходов (при 24fps - один раз в 8.3 секунд)
if (random(200) == 0) {
bullet.duplicateMovieClip("bullet"+bulletd,bulletd);
_root["bullet"+bulletd]._x = _root["al"+i]._x;
_root["bullet"+bulletd]._y = _root["al"+i]._y;
_root["bullet"+bulletd].ySpeed = random(5)+3;
bulletd++;
}
}
}
}
if (bulletd != bulletd2) {8. Теперm нужно сделать функцию очистки, т.е. DELETE();
for (i=bulletd2; i<bulletd; i++) {
if (_root["bullet"+i]) {
if (_root["bullet"+i]._x<0 || _root["bullet"+i]._x>550 || _root["bullet"+i]._y<0 || _root["bullet"+i]._y>400) {
_root["bullet"+i].removeMovieClip();
}
_root["bullet"+i]._x += _root["bullet"+i].xSpeed;
_root["bullet"+i]._y += _root["bullet"+i].ySpeed;
if (_root["bullet"+i].hitTest(hero)) {
DELETE();
prevFrame();
}
}
}
}
function DELETE () {9. И немного оптимизации. Дело в том, что пуль будет много, и правая граница for'а будет постоянно уведичиваться. И спустя некоторое время игра начнёт сильно тормозить. Поэтому я всегда делаю проверку, и если на левой границе уже никого не осталось, то и не надо её считать :)
myBullet.removeMovieClip();
for(i=bulletd2;i<bulletd;i++){
_root["bullet"+i].removeMovieClip();
}
for(i=d2;i<d;i++){
_root["al"+i].removeMovieClip();
}
}
if (bulletd2 != bulletd && !_root["bullet"+bulletd2]) {10. И последние штрихи в этом кадре: условие победы и движение главного героя.
bulletd2++;
}
if (d2 != d && !_root["al"+d2]) {
d2++;
}
if (Key.isDown(Key.LEFT)) {11. Вернёмся к первому кадру: Пишем всю необходимую информацию (управление - влево, вправо, пробел. Чтобы начать игру, нажмите энтер. И пишел следующий код:
hero._x -= 7;
}
if (Key.isDown(Key.RIGHT)) {
hero._x += 7;
}
if(d2 == d){
DELETE();
prevFrame();
}
stop();
_root.onEnterFrame=function () {Итак, вот полный код этой игры. Поэксперементируейте, попробуйте изменить какие-нибудь значения.
if(Key.isDown(Key.ENTER)){
nextFrame();
}
}
stop();P.s. Вообще, эту игру я делал достаточно давно. Цель моя была тогда несколько другая: написать играбельную игру как можно меньшего размера. В оригинальной игре код немного изменён (например, мувиклипы создаются когда игра уже запушена. Таким образом в библиотеке всего один мувиклип: главный герой. Это сделано из-за того, что создание мувиклипы едят много памяти). Swf файл игры весит 1,394 байт :D
function DELETE () {
myBullet.removeMovieClip();
for(i=bulletd2;i<bulletd;i++){
_root["bullet"+i].removeMovieClip();
}
for(i=d2;i<d;i++){
_root["al"+i].removeMovieClip();
}
}
d = d2 = 0;
bulletd = bulletd2 = 100;
shoot = false;
for (i=0; i<10; i++) {
for (i2=0; i2<5; i2++) {
alien.duplicateMovieClip("al"+d,d);
_root["al"+d]._x = i*50+50;
_root["al"+d]._y = i2*50+50;
_root["al"+d].xSpeed = 1;
d++;
}
}
_root.onEnterFrame = function() {
if (shoot == false && Key.isDown(Key.SPACE)) {
shoot = true;
myBullet._x = hero._x;
myBullet._y = hero._y;
}
if(shoot == true){
myBullet._y -= 10;
}else{
myBullet._x = -100;
}
if (Key.isDown(Key.LEFT)) {
hero._x -= 7;
}
if (Key.isDown(Key.RIGHT)) {
hero._x += 7;
}
if(d2 == d){
DELETE();
prevFrame();
}
if (d != d2) {
for (i=d2; i<d; i++) {
if (_root["al"+i]) {
_root["al"+i]._x += _root["al"+i].xSpeed*5;
if(_root["al"+i].hitTest(myBullet)){
_root["al"+i].removeMovieClip();
shoot = false;
}
if (_root["al"+i]._x>530) {
_root["al"+i].xSpeed = -1;
}
if (_root["al"+i]._x<20) {
_root["al"+i].xSpeed = 1;
}
if (random(200) == 0) {
bullet.duplicateMovieClip("bullet"+bulletd,bulletd);
_root["bullet"+bulletd]._x = _root["al"+i]._x;
_root["bullet"+bulletd]._y = _root["al"+i]._y;
_root["bullet"+bulletd].ySpeed = random(5)+3;
bulletd++;
}
}
}
}
if (bulletd != bulletd2) {
for (i=bulletd2; i<bulletd; i++) {
if (_root["bullet"+i]) {
if (_root["bullet"+i]._x<0 || _root["bullet"+i]._x>550 || _root["bullet"+i]._y<0 || _root["bullet"+i]._y>400) {
_root["bullet"+i].removeMovieClip();
}
_root["bullet"+i]._x += _root["bullet"+i].xSpeed;
_root["bullet"+i]._y += _root["bullet"+i].ySpeed;
if (_root["bullet"+i].hitTest(hero)) {
DELETE();
prevFrame();
}
}
}
}
if (bulletd2 != bulletd && !_root["bullet"+bulletd2]) {
bulletd2++;
}
if (d2 != d && !_root["al"+d2]) {
d2++;
}
};
Комментариев нет:
Отправить комментарий