Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.01.2014, 22:00   #11
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

Я нашел этот урок на си++, и по нему у меня все получилось.
Вот ссылка. http://www.cocos2d-x.org/wiki_extens...d-x?tag_id=318

По вашим урокам я только читал логику. К сожалению по неведомым мне причинам, функции и классы, которые использовали вы, отличаются от тех, которые используются в тех уроках и ваши у меня не видел компилятор. Может быть вы используете старые классы и методы, которых нет у меня в сборке? Или наоборот?

Последний урок: "Последние штрихи" на сайте нет, а по вашим примерам у меня не работает. Не видит библиотеку: "SimpleAudioEngine.h"

А вопросы я с удовольствием позадаю. Я первый раз сел за разработку игр. Это все очень интересно, просто безумно
niixon вне форума Ответить с цитированием
Старый 05.01.2014, 23:17   #12
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Возможно, у меня кокос старше. Я брала его по ссылке в первом сообщении:
Цитата:
Часть по установке Cocos2D на ваш компьютер можно прочитать здесь
Эти штуки постоянно меняются, и уже нужно смотреть на самом сайте кокоса, чем тот, что скачали вы, отличается от скачанного мной.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 06.01.2014, 00:17   #13
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

Я хочу разобрать каждую строчку из примера. Если будет время, помогите разобраться. Я буду стараться больше рассказывать как я понимаю то, или иное действие. Если будет не правильно, то исправьте пожалуйста.

1. Класс CCArray

cocos2d::CCArray *_targets;
cocos2d::CCArray *_projectiles;

Как я понял, класс CCArray используется как массив переменной длинны для различных объектов. Что-то типа arrayList из java. _targets для целей, _projectiles, для пуль. Потом в функции addTarget(), в массив _targets методом _targets->addObject(target); вставляется спрайт с картинкой цели.
Потом в методе update(), если есть столкновение, нужный объект удаляется из массива. _targets->removeObject(target); - по каким-то причинам, программа понимает какой именно объект надо удалить. Это я пока не понял.

2. Создание спрайта, загрузка картинки. Класс CCSprite

CCSprite *player = CCSprite::create("player-hd.png", CCRectMake(0, 0, 20, 20));
player->setPosition( ccp(player->getContentSize().width/2+30, winSize.height/2) );
this->addChild(player, 1);

1 строчка: здесь создается указатель на наш српайт с картинкой игрока. Через метод create() подгружаем картинку. Это первый параметр в функции, а для чего второй параметр?
2 строчка: устанавливаем позицию появления на сцене, или на слое? Или на экрана? Как правильно сказать? В параметры функции setPosition(), передаем:
1. player->getContentSize().width/2 - как правильно сказать, что здесь происходит? Вызываем метод getContentSize(), этот метод наверняка возвращает объект, который содержит в себе всевозможные размеры(константы ?). Мы обращаемся к переменной width(ширина), это ширина нашего спрайта? и делим ее на пополам. Для чего?
2. winSize.height/2 - winSize тоже объект с размером, и в нем хранятся наверное разные константы с размерами? Мы достаем из него значение height(длинна) и тоже делим на пополам. Но это уже длинна не нашего спрайта, а наверное всего экрана...
Получается поделив ширину спрайта на пополам и поделив длину экрана на пополам мы получаем центр экрана с левой стороны? И там отобразится наш спрайт?
Но дальше непонятнее всего, все эти значения передаются в параметры метода ccp. Что он возвращает? Для чего он?

3. Функция HelloWorld::init()

Эта функция вызывается при старте программы, в ней происходит инициализация переменных, создание белого фона, загрузка спрайта с игроком, вызов нужных нам функций.
Вопрос: Эта функция выполняется постоянно с какой-то частотой? Или она запускается 1 раз? В этой функции вызывается метод update(), его надо вызывать очень часто, чтобы отследить столкновение. Получается, что функция init(), вызывается постоянно в каком-то цикле? Но если она постоянно вызывается... в ней каждый раз пересоздаются все переменные и постоянно выделяется память под наши массивы(цели и пули).

_targets = new CCArray;
_projectiles = new CCArray;

... но эти переменные нельзя в каждом кадре пересоздавать. Ведь это массивы объектов и они заполняются данным.

3.1 Класс CCSize,CCDirector

CCSize и CCPoint - для каких целей можно использовать эти классы?
CCDirector - это один из главных классов. Что можно про него сказать, чтобы понять для чего он и какая у него роль?
static Director* sharedDirector() - на оф сайте сказано, что этот метод устарел, и лучше использовать getInstance().
static Director* getInstance() - получается можно и его использовать. Суть его такая: создается и возвращается указатель на объект класса Director и через него вызывается методы getWinSize(), getVisibleSize(), getVisibleOrigin();

CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

getWinSize(); - returns the size of the OpenGL view in points
getVisibleSize(); - returns visible size of the OpenGL view in points
getVisibleOrigin(); - returns visible origin of the OpenGL view in points

Не могу правильно перевести, что возвращают эти методы, гугл переводчик ужасно переводит(. То, что возвращают размер это понятно, но чего именно и в каком представлении этот размер записывается и хранится в переменных класса CCSize CCPoint?

На скриншоте показано, какие значения хранят 3 переменные.
Изображения
Тип файла: png 4.png (20.6 Кб, 144 просмотров)

Последний раз редактировалось niixon; 06.01.2014 в 11:31. Причина: Добавление скриншота
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 01:39   #14
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

3.2 Классы CCMenuItemImage, CCMenu

Код:
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback));
	pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                origin.y + pCloseItem->getContentSize().height/2));

CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
Класс CCMenuItemImage используется для хранение картинки в разных состояниях. Можно использовать для кнопки например? Мы вызываем статический метод create(const char *normalImage, const char *selectedImage, CCObject *target, SEL_MenuHandler selector );
Инициализируем переменную *pCloseItem. В метод передаем (обычная картинка, картинку, которая будет отображаться при нажатии на картинку, this - это текущий объект(тут более менее понятно), и последнее, menu_selector(HelloWorld::menuClose Callback)).

menu_selector(HelloWorld::menuClose Callback) - при нажатии на картинку, будет вызван метод menuCloseCallback(). Мы тут можем выбрать любой свой метод? И так отслеживать нажатия на картинку?
menu_selector() - что это за функция? Как это объяснить?

Потом устанавливаем позицию отображения на экране нашей картинки.Тут я еще разберусь... не все понятно пока что.

Класс CCMenu можно использовать для создания полноценного меню? Как я понял, этот класс как коллекция, в нем можно хранить разные объекты, текст, картинки и может быть еще что-то? И все, что вставлено в него, будет отображаться друг за другом или как-нибудь упорядочено? При помощи функции pMenu->addChild() можно добавлять объекты типа MenuItem? Но прототип функции выглядит так:
virtual void addChild(CCNode *child, int zOrder); Так можно или нельзя добавлять к меню, различные объекты меню, типа текста, картинок и т.д.

Цитата:
Что такое CCNode
CCNode — класс родитель всего, что вы сможете лицезреть на экране вашего устройства или в симуляторе. Это аналог NSObject в Cocoa, тоже абстрактный класс, который вам не стоит пытаться создать и добавить на экран(да и не получится, вероятнее всего), но он хранит в себе логику общую для всего, что может быть отображено на экране.
Наверное MenuItem, это наследник CCNode? По этой причине, мы можем в функцию addChild() передавать объект класса MenuItem?

Далее мы создаем объект меню (pMenu), и инициализируем его, передавая в метод creat() класса CCMenu объект: pCloseItem и null. Почему второй параметр нуль? Как я понял по прототипу static CCMenu* create(CCMenuItem *item, ... ); функция принимает переменное число аргументов, то есть, я могу создать сколько угодно объектов MenuItem разного типа (картинка, текст ...), и при создании меню, передать эти объекты в параметры методу CCMenu::create()?

Потом добавляем на нашу сцену(или экран) меню, которое хранит в себе все айтемы, которые туда добавили. В нашем случае, добавили только картинку. И последний вопрос: this->addChild(pMenu, 1); При добавлении, используется this. Это текущий объект и он непосредственно имеет доступ к экрану. Через него вызываем метод, в который вставляем объект, который нужно добавить на экран. И второй параметр? Для чего он?
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 02:31   #15
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

3.3 Вызовы функций

Код:
this->schedule( schedule_selector(HelloWorld::update) );
this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 );
this->setTouchEnabled(true);
Прототипы: schedule()
1. void schedule (SEL_SCHEDULE selector);
2. void schedule (SEL_SCHEDULE selector, float interval);


Описание:
1. Функция с одним параметром.
Цитата:
Schedules a custom selector, the scheduled selector will be ticked every frame.
То есть то, что передаем в этот метод будет запланировано на вызов при обновлении каждого кадра? Я правильно понял?

2. С двумя параметрами.
Цитата:
Schedules a selector that runs only once, with a delay of 0 or larger
Эта функция вызывается только 1 раз с указанной задержкой.

schedule_selector - как объяснить, для чего нужна эта функция, или это не функция?

Теперь стало понятно, как происходит постоянный вызов функции update().

Последний раз редактировалось niixon; 06.01.2014 в 11:34.
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 11:28   #16
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

4. void HelloWorld::addTarget()

Код:
CCSprite *target = CCSprite::create("monster-hd.png", CCRectMake(0,0,27,40) );
target->setTag(1);
Здесь все понятно. Создаем спрайт с картинкой нашего монстра. Второй параметр, он не ясен до сих пор. И устанавливаем его тэг равным единице(1 цель, 2 снаряд).


Определяем появление монстра вдоль оси Y
Код:
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int minY = target->getContentSize().height/2;
int maxY = winSize.height - target->getContentSize().height/2;
int rangeY = maxY - minY;
int actualY = ( rand() % rangeY ) + minY;
winSize – размер экрана?
minY – высота монстра деленная на пополам
maxY – высота экрана – высота монстра / 2
rangeY – здесь получаем значение… как его объяснить? Получается диапазон между высотой монстра и местом на экране.
actualY – а здесь, уже конкретно создается рандомное значение по оси Y. В диапазоне от rangeY(свободного диапазона) до minY(высота монстра)


Далее создаем монстра за правым краем, учитывая его рандомное появление по всей оси Y

Код:
target->setPosition( ccp(winSize.width + (target->getContentSize().width/2), actualY) );
this->addChild(target);
И добавляем цель на экран. Но в функцию addChild() используем 1 параметр, а не 2. int zOrder не используем. Для чего он нужен?

winSize.width + (target->getContentSize().width/2) – ширина экрана + ширина монстра / 2. (это Х позиция)
actualY – (это Y позиция), которую сгенерировал наш рандом


Далее определяем скорость перемещения монстра

Код:
int minDuration = (int)2.0; // минимальная скорость
int maxDuration = (int)4.0;	 // максимальная скорость
int rangeDuration = maxDuration - minDuration; // это получается диапазон… между скоростями
int actualDuration = ( rand() % rangeDuration )+ minDuration; // и здесь уже опять же, рандомно задается скорость для текущего монстра,
учитывая диапазон значений (от текущий диапазон) до (минимальное значение).
И что для меня странным оказалось, чем меньше числа, тем быстрее скорость перемещения объектов на сцене. 
Чем выше числа, тем медленнее соответственно.
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 12:08   #17
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

4.1 Классы CCFiniteTimeAction, CCSequence, CCMoveTo, CCCallFuncN. Создание действия
Код:
CCFiniteTimeAction* actionMove = CCMoveTo::create( (float)actualDuration, ccp(0 - target->getContentSize().width/2, actualY) );
CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create( this, callfuncN_selector(HelloWorld::spriteMoveFinished));
_targets->addObject(target);
target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );
CCFiniteTimeAction – пока не могу четко сказать, для чего нужен этот класс. По его названию и по описанию немного понятно следующее: он используется для хранения данных связанных со временем и перемещением. Возможны действия с длительностью, продолжительностью, или какие-то бесконечные(зацикленные действия). Расскажи пожалуйста про этот класс более подробно.


CCMoveTo - Moves a CCNode object to the position x,y(перемещение объекта в положение x, y).
Цитата:
Мы используем действие CCMoveTo, чтобы заставить объект двигаться из-за экрана в левую сторону. Замечу, что вы можете изменять время движения, и сейчас скорость варьируется от 2 до 4 секунд.
static CCMoveTo* create (float duration, const CCPoint & position); - float duration - ( (float)actualDuration – рандомное значение скорости перемещения ),
const CCPoint & position – (ccp(0 - target->getContentSize().width/2, actualY) – здесь координаты появления на экране, откуда начнет свое действие? Так? Значение по Y – это наше значение, которое высчитывали выше. А вот x – target - это наш монстр. Берем его значение ширины, делим на два и это получается значение х? Допустим ширина спрайта 40дп. 40/2 = 20. 0 – 20 = -20. Это вряд ли будет значение появления спрайта по оси х, это больше похоже на координату, куда он должен двигаться(или переместиться). Не очень тут понял. )


CCCallFuncN - описания на оф сайте я не нашел.
Цитата:
CCCallFuncN позволяет нам указать функцию, которая будет выполняться после того, как действие завершится. В этой игре мы поставим это действие выполняться после того, как монстры зайдут за левый край экрана, и будем удалять их со слоя, как только они скроются. Это нужно для того, чтобы не было утечек памяти каждый раз, когда у нас будет тонна неиспользуемых спрайтов за экраном. Замечу, что есть другие (и лучшие пути) решения этой проблемы, например, многократно использующиеся массивы спрайтов, но у нас уроки для новичков, поэтому пойдем легким путем.
static CCCallFuncN * create (CCObject *pSelectorTarget, SEL_CallFuncN selector); - В первый параметр передаем this, это текущий объект игры - (Со всеми нашими сценами и и т.д и т.п. Как можно описать этот момент? К чему имеет доступ этот this и что из себя представляет, не конкретно в си++, а именно логика в игре.) И второй параметр callfuncN_selector() – я не смог найти четкого объяснения этой вещи. Это точно функция(или нет? какой-то оператор?), но для чего она(он) и как работает. В нашем случае, принимает в себя HelloWorld::spriteMoveFinished – вот в таком виде. Я бы сразу понял, если бы вызывался метод (статический метод) spriteMoveFinished(), но здесь нет () после имени функции, да и метод совершенно не статический. Для меня такой вид новый и не понимаю, что здесь происходит. Скорее всего, просто(каким-то хитрым способом) передается название функции, которую надо будет вызвать в нужный момент. Как-то так?
Теперь можно сделать вывод, что actionMoveDone будет нужен, (не могу четко сформулировать правильную мысль) при окончании перемещения, и как только перемещение должно прекратиться, будет вызван метод spriteMoveFinished(), который и удалит объект со сцены и из массива _targets.


CCSequence - Runs actions sequentially, one after another(последовательное выполнение действий. Одно за другим)
Цитата:
Действие CCSequence позволяет связывать нам цепочкой действия, которые должны выполниться последовательно по одному. Таким образом, вы можете вызвать сначала действие CCMoveTo, а по его завершении, действие CCCallFuncN.
static CCSequence* create (CCFiniteTimeAction *pAction1, ... ); - это конструктор с переменным числом параметров. Получается, что мы можем создать CCSequence(как какое-то представление из разных действий). И все наши CCFiniteTimeAction будут выполняться последовательно, друг за другом. Но для чего третmим параметром идет null?

Последний раз редактировалось niixon; 06.01.2014 в 13:43.
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 12:52   #18
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

5. void HelloWorld::spriteMoveFinished(CCNode* sender)

Код:
void HelloWorld::spriteMoveFinished(CCNode* sender)
{
   CCSprite *sprite = (CCSprite *)sender;
   this->removeChild(sprite, true);
 
   if (sprite->getTag() == 1)  // цель
   {
     _targets->removeObject(sprite);
   }
  else if (sprite->getTag() == 2) // снаряд
   {
    _projectiles->removeObject(sprite);
   }
}
Функция на вход принимает указатель на объект типа CCNode. Но передаем мы в нее указатель на объект типа CCSprite. Так можем делать потому, что CCSprite наследник CCNode?
Потом делаем (каст) создаем спрайт, который и есть тот объект со сцены, который надо удалить. По его тэгу узнаем кто он (цель или пуля) и методом removeObject() удаляем из массива объектов. Но каким образом функция removeObject() поняла, какой именно объект внутри себя ей надо удалить. Например на сцене находится 3 монстра, в одного из них попала пуля. Вызывается метод spriteMoveFinished() в него передается спрайт(монстр) в которого попали и удаляем его из массива. Но как функция поняла, что удалить надо именно того в кого попали? Я бы понял, если бы мы указали индекс, или id спрайта. Наверное в каждом спрайте(объекте) есть свой идентификатор и функция по нему определяет какой спрайт надо удалить?
И еще не понятно, если удалили из массива, то нужно удалить и со сцены? Код удаления со сцены я не увидел пока что.
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 13:49   #19
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

4.2 target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );
CCAction* runAction(CCAction * action);

Через указатель на объект CCSprite вызывается метод runAction(), в котором мы создаем CCSequence(здесь хранится последовательность действий). Таким образом запускается созданный спрайт. То, что мы для него запланировали, запускается через функцию runAction();

Цитата:
Executes an action, and returns the action that is executed.

This node becomes the action's target. Refer to CCAction::getTarget()

Warning
Actions don't retain their target.
Returns
An Action pointer
niixon вне форума Ответить с цитированием
Старый 06.01.2014, 14:24   #20
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

6. HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)

6.1 Классы CCTouch, CCPoint

Код:
// Выбираем один из кликов для работы с ним
CCTouch* touch = (CCTouch*)( touches->anyObject() );
CCPoint location = convertTouchToNodeSpace(touch);
touches - указатель но объект типа CCSet, что представляет из себя этот объект? Что это? Вызываем его метод anyObject();
Цитата:
Return the first element if it contains elements, or null if it doesn't contain any element.
Возвращает какой-то первый элемент... первый клик? Первое нажатие? И этот объект будет хранить в себе координаты нажатия? Что именно тут происходит.

Цитата:
// Выбираем один из кликов для работы с ним
То есть, (CCSet* touches, CCEvent* event) пришедшие клики, это почти одно и тоже? В чем разница? Сам клик и какое-то событие? Что это за объекты?


CCPoint - на сайте у него нет описания. Для чего этот класс?
convertTouchToNodeSpace (CCTouch *touch); - создаем объект класса CCPoint location и инициализируем эту переменную возвращаемым значением из функции convertTouchToNodeSpace, в которую мы передали пришедшее нажатие. Она возвращает объект CCPoint, он наверное хранит в себе координаты нажатия и еще что-нибудь?


Код:
location = CCDirector::sharedDirector()->convertToGL(location);
Здесь статическая функция sharedDirector(), создает(или возвращает указатель на текущий объект класса CCDirector, это как 1 из главных системных классов?) и вызывает метод convertToGL(), в который передается location, точка(координата нашего нажатия).
Цитата:
converts a UIKit coordinate to an OpenGL coordinate Useful to convert (multi) touch coordinates to the current layout (portrait or landscape)
Не могу корректно перевести, получается функция преобразует координаты нажатия в зависимости от того, в каком положении находится устройство, в портретной ориентации или альбомной?

Последний раз редактировалось niixon; 06.01.2014 в 14:36.
niixon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разработка игр Kaddok Свободное общение 6 18.05.2012 22:06
Разработка социальных игр tfe2012 Фриланс 0 23.08.2011 18:57
разработка игр на Python OrcXCyber Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 24.03.2011 10:26
Требуются талантливые люди. Разработка PC-игр. zzzAleXzzz Фриланс 2 22.01.2011 23:09
разработка онлайн-игр dvizzz Gamedev - cоздание игр: Unity, OpenGL, DirectX 1 18.06.2010 23:52