Achievements engine
А вот ещё класс от меня. Точнее даже не класс, а система классов плюс визуальный компонент… короче для краткости будем называть движком ачивок ![]()
И нужен, как вы уже наверно догадались, для менеджмента ачивок, хранения их значений между сессиями игры, отображение взятых ачивок и т.д.
Для всего этого безобразия нам потребуется куча классов которые я навыкладывал в предыдущих сериях, а именно Cookie.as, ageMath.as, ageVector.as, sounds.as, alphaFader.as. Все они уже есть в исходниках примера, так что отдельно качать ничего не надо.
Да я знаю что практика таскания кучи библиотек многим не по душе, однако я хочу отметить – я даю готовые решения, а не делаю уроки
так что этот беспредел будет и дальше продолжаться. Я вообще подумываю собрать все наработки в какое-то подобие фреймворка, точнее даже темплейта, который можно будет загрузить и уже на основе него ваять новую игрушку
Ну ладна, от лирики к нашим баранам, то есть ачивкам.
Сразу смотрим как это работает:
Первые три кнопки – получение ачивки, последняя кнопка очищает все набранные достижения.
Все ачивки делятся на два типа – обычные и с параметром.
Обычные – это такие, которые получаешь за определённое действие, например пройти первый уровень.
С параметром – это когда например чтобы получить ачивку надо убить 5 монстров. Все текущие значения сохраняются внутри движка ачивок, так что ни о чём думать не надо.
Как же использовать движок ачивок в своих проектах? Во-первых надо добавить мовиклип achInfo на главную временную линейку. Его можно кастомизировать под стиль игры. Проще всего скопировать его из примера. Назовём этот экземпляр «achInfoClip».
Потом в классе ach в функции loadAllAch() записываем те ачивки, которые нам нужны. Можно конечно и напрямую вызывать addAchToDB(…) из главной программы. Это кому как удобно.
Далее инициализируем движок ачивок:
ach.init('myAch',achInfoClip);
где первый параметр – имя куки, в который будут сохранятся достижения, второй – имя нашего информационного мовиклипа.
Далее можно загрузить старые значения ачивок:
ach.loadAchFromCookie();
и можно уже получать достижения
для простых ачивок есть функция:
ach.getAch('lev1');
для ачивок с параметром:
ach.incAchCnt('kill5');
Вот собственно и всё. Класс ach уже сам определит, была ли взята ачивка или нет. Если ещё нет – покажет информацию по ачивке через мовиклип achInfoClip. И конечно же сохранит результат в файл куки. Думаю довольно удобно.
Обнулить все результаты ачивок можно следующей функцией:
ach.initAchCookie();
Сам же код примера выглядит следующим образом. Из комментариев думаю всё ясно:
import main.*; //инициализация движка ачивок ach.init('myAch',achInfoClip); //также нам потребуется звук sounds.init(500,400); //Загружаем старые ачивки ach.loadAchFromCookie(); //Обновление информации по ачивкам function updateTXT():void { txt.text="Achievements:\n\n"; var iobj:String; for(iobj in ach.db) { txt.appendText(ach.db[iobj].title+' '); txt.appendText(ach.db[iobj].active?'on':'off'); //Если ачивка количественная - выводим сколько осталось в процентах if(ach.db[iobj].cntNeed>0) txt.appendText(' completed '+ach.db[iobj].cntCur/ach.db[iobj].cntNeed*100+'%'); txt.appendText('\n'); } } updateTXT(); //кнопки получения ачивок but1.addEventListener(MouseEvent.CLICK, but1_Click); function but1_Click(e : MouseEvent):void { ach.getAch('lev1'); updateTXT(); } but2.addEventListener(MouseEvent.CLICK, but2_Click); function but2_Click(e : MouseEvent):void { ach.getAch('dropAb'); updateTXT(); } but3.addEventListener(MouseEvent.CLICK, but3_Click); function but3_Click(e : MouseEvent):void { ach.incAchCnt('kill5'); updateTXT(); } //Стереть все записанные ачивки but4.addEventListener(MouseEvent.CLICK, but4_Click); function but4_Click(e : MouseEvent):void { ach.initAchCookie(); updateTXT(); }
Класс ach – главный класс движка ачивок. Здесь происходит всё управление:
package main { public class ach { static public var db:Object=new Object(); //Все ачивки здесь static public var achInfoMC:achInfo; //Мовиклип с инфой по ачивке static public var cookieName:String; //Имя куки файла куда пишем ачивки //Внутрение переменные static private var iobj:String; static private var myCookie:Cookie; //создаём ачивки. Можно конечно вызывать извне класса но думаю так удобней static public function loadAllAch() { addAchToDB("lev1","Beginner","Complete the first level."); addAchToDB("dropAb","Mad drop","Use 'Drop' ability four times during the battle."); addAchToDB("kill5","Warrior","Kill 5 enemies.",5); } // Инициализация движка ачивок // _cookieName - имя кукиса куда пишем взятые ачивки // _achInfoMC - имя мовиклипа, отвечающего за отображение инфы по взятой ачивке static public function init(_cookieName:String,_achInfoMC:achInfo) { achInfoMC=_achInfoMC; cookieName=_cookieName; myCookie=new Cookie(cookieName); loadAllAch(); } // Добавление ачивки базу // _achName - имя ачивки по которой будем её вызывать // _achTitle - отображаемое имя ачивки // _achDsc - описание ачивки // _achCnt - если не ноль - ачивка с параметром static public function addAchToDB(_achName:String,_achTitle:String,_achDsc:String,_achCnt:int=0) { db[_achName]=new achItem(_achName,_achTitle,_achDsc,_achCnt); } // Загрузка ачивок из кукисов static public function loadAchFromCookie() { for(iobj in db) { db[iobj].active=Boolean(myCookie.get(iobj+'_active')); db[iobj].cntCur=int(myCookie.get(iobj+'_cntCur')); } } // Обнуление всех ачивок static public function initAchCookie() { for(iobj in db) { myCookie.putNoFlush(iobj+'_active',0); myCookie.putNoFlush(iobj+'_cntCur',0); db[iobj].active=false; db[iobj].cntCur=0; } myCookie.flushData(); } // Записать получение ачивки с именем ach_name static public function getAch(ach_name:String) { //Берём ачивку только если она уже не взята if(!db[ach_name].active) { db[ach_name].active=true; if(sounds) sounds.PlaySnd("snd_ach"); achInfoMC.showAch(ach.db[ach_name]); myCookie.put(ach_name+'_active',db[ach_name].active); return true; } return false; } // Установить параметр ачивки ach_name в значение ach_cnt static public function setAchCnt(ach_name:String,ach_cnt:int) { if(!db[ach_name].active) { db[ach_name].cntCur=ach_cnt; myCookie.put(ach_name+'_cntCur',db[ach_name].cntCur); //Если параметр ачивки достиг максимального значения - получаем ачивку if(db[ach_name].cntCur>=db[ach_name].cntNeed) { db[ach_name].active=true; db[ach_name].cntCur=db[ach_name].cntNeed; if(sounds) sounds.PlaySnd("snd_ach"); achInfoMC.showAch(ach.db[ach_name]); myCookie.put(ach_name+'_active',db[ach_name].active); return true; } } return false; } // Увеличить на единицу параметр ачивки ach_name static public function incAchCnt(ach_name:String) { setAchCnt(ach_name,db[ach_name].cntCur+1); } } }
Класс achItem – описывает одну ачивку. В этом классе хранится только информация:
package main { public class achItem { public var name:String; //имя ачивки по которой будем её вызывать public var title:String; //отображаемое имя ачивки public var desc:String; //описание ачивки public var active:Boolean; //взята ли ачивка public var cntNeed:int; //если не ноль - ачивка с параметром public var cntCur:int; //текущее значение параметра ачивки //Конструктор класса ачивки - все пораметры соотвествуют названиям выше ) public function achItem(_name:String,_title:String,_desc:String,_cntNeed:int=0) { name=_name; title=_title; desc=_desc; cntNeed=_cntNeed; cntCur=0; active=false; } } }
Класс achInfo – панелька с информацией, которая выскакивает каждый раз, когда мы берём ачивку. Её легко кастомизировать под свой проект. Хочу обратить внимание на мовиклип achPic. В нём хранятся все пиктограммы достижений. Все кадры в нем поименованы так же, как и ачивки в программе. Однако если такой пиктограммы нет, то будет выбрана пиктограмма по-умолчанию – первый кадр с именем ‘ok’.
package main { import flash.utils.*; import flash.events.*; public class achInfo extends alphaFader { //Время показа инфы по взятой ачивке private const TIME_TO_SHOW:int=4000; //таймер для исчезновения этого мовиклипа private var removeTimer:Timer; public function achInfo() { removeTimer= new Timer(TIME_TO_SHOW,1); removeTimer.stop(); removeTimer.addEventListener(TimerEvent.TIMER, removeTimer_Timer); visible=false; } //Показать эту панель с инфой по ачивке thisAch public function showAch(thisAch:achItem):void { achObj.achPic.gotoAndStop(thisAch.name); achObj.titleTxt.text=thisAch.title; achObj.descTxt.text=thisAch.desc; removeTimer.start(); startFadeIn(); } //Плавное исчезновение панели function removeTimer_Timer(event:TimerEvent):void { startFadeOut(); } } }
Весь код примера можно скачать здесь: http://www.anegmetex.com/devblog/files/achEngine.rar
Категория: Полезные классы

Апрель 28th, 2011 at 15:23
…этот беспредел будет и дальше продолжаться…
Я за беспредел Олег!!!
Суппер статья, спас.
Апрель 29th, 2011 at 15:01
рад что пост оказался полезным