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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.01.2013, 02:04   #1
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию Разработка игр на С++ и Cocos2D-x

В общем, решила я заняться Cocos2D. Как обычно, инфы на русском очень-очень мало, а на С++ еще меньше, поэтому хочу каким-то образом это исправить. Пока я совсем новичок в этом деле, то буду просто переводить статьи продвинутых "товарищей по оружию". Это, конечно, не громадный вклад в гейм-индустрию, и многие могут сказать: "Зачем нужен перевод, если программисты в большинстве своем знают английский язык?" Не знаю, как вам, а мне все же приятнее читать статьи на родном языке. Может, кому-то поможет в освоении новых для себя технологий.

Туториал 1. Как написать простую игру с помощью Cocos2D
Это вольный перевод статей Ray Wenderlich и Yong Yang.

Часть по установке Cocos2D на ваш компьютер можно прочитать здесь

Добавление спрайта

Перед тем, как вы сможете добавить спрайт, вам необходимо несколько картинок для работы. Вы можете использовать картинки, нарисованные специально для данного туториала женой автора одной из переводимых статей – Рэя Вендерлича (http://www.raywenderlich.com/), скачать их можно тут Resource.rar

Скачав ресурсы, распакуйте их и перетащите в папку Resource в VisualStudio (у меня так не получилось, поэтому я добавляла картинки в папку Resource на жестком диске, а потом в студии правой кнопкой на Resource в панели Обозреватель решений – Добавить – Существующий элемент – и выбирала картинки. Замечу, что сразу они у меня почему-то в проекте не отобразились (а только после перезапуска студии), но обращаться к ним я все равно могла).

Теперь, когда у вас есть картинки, мы разместим нашего персонажа. В Cocos2D нижний левый угол картинки имеет координаты (0;0), а значения координат х и увеличиваются по направлению к правому верхнему углу. Поскольку данный проект в горизонтальном режиме, это обозначает, что верхний правый угол имеет координаты(480, 320), если вы запускаетесь на 3.5″ экране, и (568, 320), если запускаетесь на 4″.

Замечание: Те из вас, кто программировал для iOS могут возразить, что 4″ экран вмещает в себя 1136х640 пикселей. Вы правы, но Cocos2D оперирует поинтами, а не пикселями. На устройствах с Retina дисплеями 1 поинт = 2 пикселям, таким образом 1136х640 пикселей = 568х320 поинтам. Это очень удобно, потому что используя поинты в своих играх, координаты будут одинаковыми и для Retina дисплеев, и для других.

Также замечу, что по умолчания, когда вы задаете позицию объекта, она считается относительно центра добавляемого спрайта. Итак, если вы хотите, чтоб спрайт вашего персонажа был выровнен по левому краю экрана по горизонтали и центрирован по вертикали:
- Координату х установите в [ширина спрайта персонажа]/2.
- Координату у установите в [высота окна]/2.
Данная картинка поможет это лучше представить:
SpriteCoordinates.jpg

Итак, давайте попробуем! Откройте HelloWorldScene.cpp (в туториале было HelloWorldLayer, у вас этот файл может называться немного по-другому), и поместим в метод инициализации (bool HelloWorld::init()) следующий код:

Код:
bool HelloWorld::init()
{
	if(! CCLayer::init()){
		return false;
	}

	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 
	CCSprite *player = CCSprite::spriteWithFile("player.png");
	player->setPosition(ccp(player->getContentSize().width/2, 
winSize.height/2));
	this->addChild(player);

	return true;
}
Вы можете построить и запустить проект, и ваш спрайт там появится, но задний фон по умолчанию черный, а для нашего приложения лучше подойдет белый.
Легче всего установить необходимый цвет фона в Cocos2D с помощью класса CCLayerColor. Откроем HelloWorldScene.h и изменим родителя нашего класса HelloWorld:
Код:
class HelloWorld : public cocos2d::CCLayerColor
Затем откроем HelloWorldScene.cpp и внесем изменения в метод инициализации (init()) вместо строки if(! CCLayer::init())

Код:
if(! CCLayerColor::initWithColor(ccc4(255,255,255,255))){
	return false;
}
Скомпилируем и запустим приложение, и увидим наш спрайт на белом фоне.

Замечание: вы, возможно, заметили, что в ресурсах два варианта изображения нашего героя: player.png (27×40 пикселей), и player-hd.png (двойной размер – 54×80 пикселей). Это для одной крутой фичи Cocos2D – он достаточно умен для того, чтобы подставить графику с высоким разрешением, когда вы запускаетесь под Retina дисплеями! Только положите графику с удвоенным размером и добавьте окончание -hd.
Изображения
Тип файла: jpg ProjectileTriangle.jpg (10.6 Кб, 558 просмотров)
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 09.01.2013, 02:06   #2
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Движение монстров

Далее мы добавим монстров на нашу сцену, с которыми ниндзя будет сражаться. Позволим им перемещаться, чтобы было интереснее. Давайте будем создавать монстров за правым краем экрана и настроим для них движение влево. Добавим следующий метод перед методом init (не забываем прописать его сигнатуру в HelloWorldScene.h):
Код:
void HelloWorld::addMonster(){
	
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();

       CCSprite* monster = CCSprite::spriteWithFile("monster.png");
	
       // определим появление монстра вдоль оси Y
	int monsterHeight = monster->getContentSize().height;
	int monsterWidth = monster->getContentSize().width;
	int minY = monsterHeight / 2;
	int maxY = winSize.height - monsterHeight / 2;
	int rangeY = maxY - minY;
	int actualY = (rand() % rangeY) + minY;

	// создаем монстров немного за экраном по правому краю и в случайной позиции Y,
       // рассчитанной выше
	monster->setPosition(ccp(winSize.width + monsterWidth/2, actualY));
	this->addChild(monster);

	// считаем скорость монстров
	int minDuration = 4;
	int maxDuration = 6;
	int rangeDuration = maxDuration - minDuration;
	int actualDuration = (rand() % rangeDuration) + minDuration;

	// создаем действия
	CCFiniteTimeAction* actionMove = CCMoveTo::actionWithDuration( (float)actualDuration, 
		ccp(0 - monsterWidth/2, actualY) );
	CCFiniteTimeAction* actionMoveDone = CCCallFuncN::actionWithTarget( this, 
		callfuncN_selector(HelloWorld::spriteMoveFinished));

	monster->runAction(CCSequence::actions(actionMove, actionMoveDone, NULL));
}
Первая часть представляет собой то, о чем мы с вами говорили: вы производите нехитрые расчеты для определения позиции появления объекта, и добавляете его на сцену, как это было с изображением нашего героя.

Новым здесь будет добавление действий. Cocos2D предоставляет множество встроенных действий, которыми мы можем оживить наши спрайты: движение, прыжок, исчезновение, анимация и т.д. Сейчас мы использовали три действия на монстрах:
CCMoveTo: Мы используем действие CCMoveTo, чтобы заставить объект двигаться из-за экрана в левую сторону. Замечу, что вы можете изменять время движения, и сейчас скорость варьируется от 2 до 4 секунд.
CCCallFuncN: CCCallFuncN позволяет нам указать функцию, которая будет выполняться после того, как действие завершится. В этой игре мы поставим это действие выполняться после того, как монстры зайдут за левый край экрана, и будет удалить их со слоя, как только они скроются. Это нужно для того, чтобы не было утечек памяти каждый раз, когда у нас будет тонна неиспользуемых спрайтов за экраном. Замечу, что есть другие (и лучшие пути) решения этой проблемы, например, многократно использующиеся массивы спрайтов, но у нас уроки для новичков, поэтому пойдем легким путем.
CCSequence: Действие CCSequence позволяет связывать нам цепочкой действия, которые должны выполниться последовательно по одному. Таким образом, вы можете вызвать сначала действие CCMoveTo, а по его завершении, действие CCCallFuncN.

Теперь нам нужно вызвать метод создания монстров. Чтобы было интересно, давайте заставим монстров непрерывно появляться. Вы можете сделать это в Cocos2D, запланировав периодический вызов функции возврата. Будем вызывать ее один раз в две секунды. Добавьте следующий вызов в ваш метод init перед словом return.
Код:
this->schedule( schedule_selector(HelloWorld::gameLogic), 2.0 );
И добавьте следующую реализацию функции возврата (не забыв прописать ее в HelloWorldScene.h):
Код:
void HelloWorld::gameLogic(float dt){
	addMonster();
}
Скомпилируйте и запустите проект. Вы сможете увидеть, как бегут монстры через экран.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 09.01.2013, 02:07   #3
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Выстрел

Давайте добавим немного действий – научим ниндзя стрелять. Есть много вариантов реализации выстрела, но в этой игре мы сделаем его так, что когда игрок коснется экрана(кликнет мышью по экрану), произойдет выстрел в направлении от героя к месту клика.

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

Вот картинка, которая проиллюстрирует это:
ProjectileTriangle.jpg

Как вы можете видеть, у нас имеется маленький треугольник, созданный смещением х и у относительно исходной точки к точке клика. Нам только нужно сделать большой треугольник с такими же пропорциями – и мы получим конечную точку за экраном.

Итак, вернемся к нашему коду. Сначала нужно разрешить клик по нашему слою. Добавьте следующий код в метод init():
Код:
this->setIsTouchEnabled(true);
Так как мы разрешили клик на нашем слое, теперь мы будем получать функции возврата от событий клика. Давайте реализуем метод ccTouchesEnded, который будет вызываться, когда юзер завершит клик (его тоже нужно прописать в HelloWorldScene.h - void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);):
Код:
void HelloWorld::ccTouchesEnded(CCSet * touches, CCEvent * event){
	// Выбираем один из кликов для работы с ним
	CCTouch * touch = (CCTouch*)( touches->anyObject() );
	CCPoint location = convertTouchToNodeSpace(touch);

	// Устанавливаем начальные координаты снаряда	
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	CCSprite *projectile = CCSprite::spriteWithFile("projectile.png");
	projectile->setPosition(ccp(20, winSize.height / 2));
 
	// определяем смешение координат снаряда
	CCPoint offset = ccpSub(location, projectile->getPosition()); 
   
	// Выходим из функции, если выстрелили вниз или назад
	if(offset.x <= 0) return;

	// Добавляем снаряд на слой и дважды проверяем позицию
	this->addChild(projectile);
 

	int realX = winSize.width + (projectile->getContentSize().width/2);
       float ratio = (float) offset.y / (float) offset.x;
	int realY = (realX * ratio) + projectile->getPosition().y;
    CCPoint realDest = ccp(realX, realY);
 
    // Определяем как далеко вы выстрелили
    int offRealX = realX - projectile->getPosition().x;
    int offRealY = realY - projectile->getPosition().y;
    float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
    float velocity = 480/1; // 480пикселей/1секунда
    float realMoveDuration = length/velocity;
 
    // Двигаем снаряд в конечную точку
    projectile->runAction(CCSequence::actions(
		CCMoveTo::actionWithDuration(realMoveDuration, realDest),
		CCCallFuncN::actionWithTarget(this,                    callfuncN_selector(HelloWorld::spriteMoveFinished)),
		NULL));
   
}

Первым делом мы выбираем один из кликов, чтоб работать с ним, и используем convertTouchToNodeSpace, чтобы конвертировать координаты клика в координаты нашего слоя.

Далее мы загружаем картинку снаряда и устанавливаем его начальные координаты, как обычно. Затем определим, куда мы хотим переместить снаряд, используя вектор между кликом и игроком согласно алгоритма, приведенного ранее.

Замечу, что алгоритм не идеален. Мы заставляем снаряд двигаться, пока он не достигнет экрана по позиции Х, даже если он уже вышел за экран в Y-позиции. Существуют множество способов найти кратчайший путь за экран, но для этого туториала пусть будет как есть.

Последнее, что мы должны сделать – это определить продолжительность движения. Мы хотим, чтобы снаряд двигался с одинаковой скоростью, несмотря на направление движения, и опять нам понадобится математика. Вы можете выяснить расстояние, используя теорему Пифагора. Вспомните из курса геометрии правило, которое утверждает, что длина гипотенузы прямоугольного треугольника равна квадратному корню из суммы квадратов катетов. Когда у вас есть расстояние, разделите его на скорость, чтобы получить время.

Напоследок установите действия так же, как это делали для монстров. Скомпилируйте и запустите проект, и ваш ниндзя теперь имеет возможность разить орды противника!
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 09.01.2013, 02:08   #4
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Обнаружение столкновений

Итак, сейчас сюррикены летают везде, но что наш ниндзя действительно хочет – это уложить парочку монстров. Давайте добавим код, определяющий, когда наши снаряды поразили цель.

Есть несколько способов решить эту задачу с помощью Cocos2D, включая использование физических библиотек: Box2D или Chipmunk. Однако чтобы не усложнять, мы сделаем самостоятельно простое обнаружение столкновений.

Чтобы сделать это, сперва нужно запомнить снаряды и цели, которые присутствуют в данный момент на сцене. Добавим следующее объявление в класс HelloWorldScene:
Код:
protected:
	cocos2d::CCMutableArray<cocos2d::CCSprite*> *_targets;
	cocos2d::CCMutableArray<cocos2d::CCSprite*> *_projectiles;
И инициализируем эти массивы в методе init():
Код:
_targets = new CCMutableArray<CCSprite*>;
_projectiles = new CCMutableArray<CCSprite*>;
И, пока вы помните об этом, очистите память в деструкторе класса:
Код:
HelloWorld::~HelloWorld(){
	if(_targets){
		_targets->release();
		_targets = NULL;
	}

	if(_projectiles){
		_projectiles->release();
		_targets = NULL;
	}
}
Теперь модифицируем метод addMonster так, чтобы каждый монстр добавлялся в массив монстров, и установим ему тег для дальнейшего использования:
Код:
monster->setTag(1);
_targets->addObject(monster);
Также изменим метод ccTouchesEnded так, чтобы каждый снаряд добавлялся в массив снарядов, и тоже установим им тег для дальнейшего использования
Код:
projectile->setTag(2);
_projectiles->addObject(projectile);
И, наконец, изменим код функции spriteMoveFinished, удаляя из массива объект, который ушел за экран:
Код:
void HelloWorld::spriteMoveFinished(CCNode * node){	
	node->removeFromParentAndCleanup(true);
	if (node->getTag() == 1)  // монстр
       {
	    _targets->removeObject((CCSprite *)node);
       }
	else if (node->getTag() == 2) // снаряд
	{
		_projectiles->removeObject((CCSprite *)node);
	}	
}
Постройте и запустите проект, чтобы убедиться, что все работает. Сейчас нет большой разницы с предыдущим разом, но у нас уже есть учет монстров и снарядов, осталось реализовать определение столкновений.
Добавим новый метод (в .h-файле void update(cocos2d::ccTime dt);):
Код:
void HelloWorld::update(ccTime dt){
	CCMutableArray<CCSprite*> *projectilesToDelete = new CCMutableArray<CCSprite*>;
	CCMutableArray<CCSprite*>::CCMutableArrayIterator it, jt;

	for(it = _projectiles->begin(); it != _projectiles->end(); it++){
		CCSprite * projectile = *it;
		CCSize projectileSize = projectile->getContentSize();
		CCRect projectileRect = CCRectMake(projectile->getPosition().x - (projectileSize.width / 2),
			projectile->getPosition().y - (projectileSize.height / 2),
			projectileSize.width, projectileSize.height);

		CCMutableArray<CCSprite*> *targetsToDelete = new CCMutableArray<CCSprite*>;

		for(jt = _targets->begin(); jt != _targets->end(); jt++){
			CCSprite *target = *jt;
			CCSize targetSize = target->getContentSize();
			CCRect targetRect = CCRectMake(target->getPosition().x - (targetSize.width / 2),
				target->getPosition().y - (targetSize.height / 2),
				targetSize.width, targetSize.height);

			if(CCRect::CCRectIntersectsRect(projectileRect, targetRect)){
				targetsToDelete->addObject(target);
			}
		}

		for(jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++){
			CCSprite * target = *jt;
			_targets->removeObject(target);
			this->removeChild(target, true);			
		}

		if(targetsToDelete->count() > 0){
			projectilesToDelete->addObject(projectile);
		}
		targetsToDelete->release();
	}

	for(it = projectilesToDelete->begin(); it != projectilesToDelete->end(); it++){
		CCSprite * projectile = *it;
		_projectiles->removeObject(projectile);
		this->removeChild(projectile, true);
		
	}	
}
Вышенаписанное должно быть предельно ясно. Мы проходим по массивам снарядов и монстров, создаем прямоугольники, представляющие их границы, и используем CCRectIntersectsRect для проверки их пересечений. Если что-нибудь будет найдено, то удаляем это со сцены и из массивов.

Замечу, что вы должны добавить объект в массив «для удаления», потому что нельзя удалить объект из массива, пока вы идете по нему. Разумеется, есть более оптимальные способы решения этой задачи, но мы идем самым легким путем.

Осталась одна вещь, которую нужно сделать – запланировать запуск этого метода так часто, как это возможно, добавив следующую строку в метод init():
Код:
this->schedule( schedule_selector(HelloWorld::update) );
Запустите игру, и сейчас, когда снаряды пересекают цели, они исчезают.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 09.01.2013, 02:09   #5
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Последние штрихи

Мы уже очень близко к завершению нашего хоть и очень простого, зато работоспособного приложения. Было бы неплохо добавить сюда звуковых эффектов и музыки (какая же это игра без звука?) и немного простой игровой логики.

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

Итак, скопируйте файлы background-music-aac.wav и pew-pew-lei.wav в папку Resource, если вы этого еще не сделали ранее. Мы будем использовать wav, потому что wav поддерживается всеми платформами.

Затем подключим SimpleaudioEngine.h в HelloWorldScene.cpp.
Код:
#include "SimpleAudioEngine.h"
В методе init() начнем проигрывать фоновую музыку:
Код:
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav", true);
И в методе ccTouchesEnded проигрываем звуковой эффект:
Код:
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav", false);
Так как при закрытии игры у меня вываливалась ошибка, мне показалось правильным выключить музыку в самом конце, поэтому в файле AppDelegate.cpp в деструкторе класса я написала:
Код:
AppDelegate::~AppDelegate()
{
	CocosDenshion::SimpleAudioEngine::sharedEngine()->end();
}
Теперь давайте создадим новую сцену и слой, которые будут индикатором победы или поражения. Создайте новый файл, GameOverScene.h и пропишите там следующий код:
Код:
#ifndef _GAME_OVER_SCENE_H_
#define _GAME_OVER_SCENE_H_

#include "cocos2d.h"

class GameOverLayer : public cocos2d::CCLayerColor{
public:
	GameOverLayer():_label(NULL) {};
	virtual ~GameOverLayer();
	bool init();
	LAYER_NODE_FUNC(GameOverLayer);

	void gameOverDone();

	CC_SYNTHESIZE_READONLY(cocos2d::CCLabelTTF*, _label, Label);
};

class GameOverScene : public cocos2d::CCScene{
public:
	GameOverScene():_layer(NULL){};
	~GameOverScene();
	bool init();
	SCENE_NODE_FUNC(GameOverScene);

	CC_SYNTHESIZE_READONLY(GameOverLayer*, _layer, Layer);
};
#endif
В GameOverScene.cpp напишите следующее:
Код:
#include "GameOverScene.h"
#include "HelloWorldScene.h"

using namespace cocos2d;

bool GameOverScene::init(){
	if(CCScene::init()){
		this->_layer = GameOverLayer::node();
		this->_layer->retain();
		this->addChild(_layer);

		return true;
	}
	return false;
}

GameOverScene::~GameOverScene(){
	if(_layer){
		_layer->release();
		_layer = NULL;
	}
}

bool GameOverLayer::init(){
	if(CCLayerColor::initWithColor(ccc4(255,255,255,255))){
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		this->_label = CCLabelTTF::labelWithString("","Arial", 32);
		_label->retain();
		_label->setColor(ccc3(0,0,0));
		_label->setPosition(ccp(winSize.width / 2, winSize.height / 2));
		this->addChild(_label);

		this->runAction(CCSequence::actions(CCDelayTime::actionWithDuration(3),
			CCCallFunc::actionWithTarget(this, callfunc_selector(GameOverLayer::gameOverDone)),
			NULL));
		return true;
	}
	return false;
}

void GameOverLayer::gameOverDone(){
	CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());
}

GameOverLayer::~GameOverLayer(){
	if(_label){
		_label->release();
		_label = NULL;
	}
}
Замечу, что здесь два разных объекта: сцена и слой. Сцена может содержать сколько угодно слоев, однако, в этом примере он только один. На слой положим текст в центр экрана, который будет отображать фразы “You Win” или “You Lose” в течение трех секунд, а затем будем переходить снова в сцену Hello World.

Вернемся к задачам, GameOverScene должна быдет вызываться в двух случаях: если убито достаточное количество монстров или одному из монстров удалось улизнуть.

Мы добавим переменную в HelloWorldScene.h, в которой будем считать количество убитых героем врагов.
Код:
int _projectilesDestroyed;
В HelloWorldScene.cpp, добавим подключение для класса GameOverScene:
Код:
#include "GameOverScene.h"
Увеличиваем количество убитых монстров и проверяем на условие победы в методе update внутри цикла по массиву targetsToDelete после removeChild(target, true):
Код:
_projectilesDestroyed++;
if(_projectilesDestroyed > 30){
       GameOverScene *gameOverScene = GameOverScene::node();
	gameOverScene->getLayer()->getLabel()->setString("You win!");
	CCDirector::sharedDirector()->replaceScene(gameOverScene);
}
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 09.01.2013, 02:09   #6
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

И, наконец, давайте сделаем так, чтобы когда хотя бы один монстр убегает, мы проигрывали. В функции spriteMoveFinished() после условия проверки, удалился ли монстр с экрана (if (node->getTag() == 1)), пишем:
Код:
GameOverScene * gameOverScene = GameOverScene::node();
gameOverScene->getLayer()->getLabel()->setString("You lose :[");
CCDirector::sharedDirector()->replaceScene(gameOverScene);
Запустите игру, и вы сможете видеть сцену окончания игры, когда вы выиграли или проиграли.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 10.01.2013, 16:07   #7
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

Ха-ха, эту же статью на русском нашла здесь, и перевод там гораздо удачнее, (правда, она на Objective-C). Ну, как говорится, "хорошая мысля приходит опосля". В моем случае я нахожу то, что мне надо, когда уже все перевела (перевод с Objective-C на С++ тоже нашелся в середине написания мной игры).
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 05.07.2013, 12:06   #8
akuba
Новичок
Джуниор
 
Регистрация: 13.11.2009
Сообщений: 1
По умолчанию

автору респект однозначно! Речь идет не о статье в частности, а о конкретной реализации данного проекта на С++ и cocos2d-x. Да-да.. не о Objective-C и cocos2d-iphone, а именно связке С++/cocos2d-x. Здесь, как грят в Одессе, две большие разницы.
akuba вне форума Ответить с цитированием
Старый 04.01.2014, 11:25   #9
niixon
Пользователь
 
Регистрация: 03.08.2012
Сообщений: 23
По умолчанию

Скажите пожалуйста, автор, есть ли у вас еще обучающие статьи? Именно таких статей не хватает для самостоятельного обучения. И можно ли задавать вопросы по урокам здесь?
niixon вне форума Ответить с цитированием
Старый 04.01.2014, 14:07   #10
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,378
По умолчанию

niixon, я не автор, я типа переводчик Больше статей нет (так как нашла русский перевод, хоть и на ObjC), но если кому надо, могу попробовать попереводить еще. Вопросы задавать можно, отвечу в меру своих знаний.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 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