今天把捕魚達人的項目給做完了,基本功能都實現了,第一天把cocoscreator 做了一部分,算是熟悉了捕魚達人的一些特點,
第二天用cocos2d-x寫,感覺還是不錯的,
首先把場景佈置了一下,按鈕跟打飛機的按鈕是不同的,在這上面稍微花費了一點時間,星期二就讓我們自己把一些場景佈置以及場景的轉換,
auto start = MenuItemImage::create(
"1.png",
"2.png",
CC_CALLBACK_1(HelloWorld::onStart, this));
start->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y - start->getContentSize().height + visibleSize.height/2 + 50));
auto quit = MenuItemImage::create(
"bbbbb1.png",
"bbbbb2.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
quit->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + start->getPositionY() - quit->getContentSize().height - 50));
auto menu = Menu::create(start,quit, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
需要加載兩張不同的圖片,點擊到按鈕就會切換圖片達到按鈕的效果;
就HelloWorldScene和打飛機的都一樣的,所以沒遇到什麼困難;
第二天就把一些UI給加載到場景中,並且添加了一些動畫;
首先是炮臺與Bar以及+ - 按鈕的顯示,都和加載圖片一樣;
這天主要還是炮臺的切換;
我是把炮臺和+ - 按鈕的點擊事件在同一個類裏面創建的;
先是給按鈕點擊事件賦值;
auto ss = (MenuItemFont*)pSender;
int sss = ss->getTag();
if (sss == 1){
if (type == 1)
{
type = 7;
}
else{
type -= 1;
}
}
else if (sss == 2){
if (type == 7)
{
type = 1;
}
else{
type += 1;
}
}
selectType(type);
假定有七個炮臺的情況;
selectType(type)這是加載炮臺的方法,根據type的值去切換炮臺;
void Battery::selectType(int type){
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
if (battery1)
{
battery1->removeFromParent();
battery1 = NULL;
}
if (type == 1 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("1-1.png");
if (type == 2 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("2-1.png");
if (type == 3 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("3-1.png");
if (type == 4 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("4-1.png");
if (type == 5 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("5-1.png");
if (type == 6 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("6-1.png");
if (type == 7 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("7-1.png");
battery1->setPosition(Vec2(origin.x + visibleSize.width / 2 + 40, origin.y + battery1->getContentSize().height / 2 - 5));
this->addChild(battery1,5);
battery1->setRotation(rotation);
}
這就是炮臺的創建,在之前有加載過plist文件;
這就實現了炮臺的轉換了;
還有一個比較簡單的就是給炮臺增加旋轉;
這隻要找到API賦值一些代碼就行了;
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(Battery::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(Battery::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
這四句調用點擊場景事件;
bool Battery::onTouchBegan(Touch* touch, Event *event)
{
return true;
}
void Battery::onTouchEnded(Touch* touch, Event *event)
{
auto location = touch->getLocation();
auto radian = atan2(location.y - 21.6f, location.x - 550.0f);
auto inclination = radian * 180 / 3.14;
auto kil = -(inclination)+90;
if (kil <= 70 && kil >= -70) {
rotation = kil;
battery1->setRotation(rotation);
}
}
這就把炮臺的旋轉可以實現了;
需要切換炮臺的角度不變,把這角度在生成炮臺地方調用就好了battery1就是生成的炮臺;
battery1->setRotation(rotation); 只要一句就好了;
第三天把魚的出現給進行一些調整;
並且可以發射子彈,跟隨炮臺的轉動而轉動;
void Battery::shutBullet(int type)
{
if (type == 1)
{
bullet1 = Sprite::create("bullet/wepen1.png");
}
if (type == 2)
{
bullet1 = Sprite::create("bullet/wepen2.png");
}
if (type == 3)
{
bullet1 = Sprite::create("bullet/wepen3.png");
}
if (type == 4)
{
bullet1 = Sprite::create("bullet/wepen4.png");
}
if (type == 5)
{
bullet1 = Sprite::create("bullet/wepen5.png");
}
if (type == 6)
{
bullet1 = Sprite::create("bullet/wepen6.png");
}
if (type == 7)
{
bullet1 = Sprite::create("bullet/wepen7.png");
}
bullet1->setPosition(Vec2(battery1->getPositionX(), battery1->getPositionY()));
this->addChild(bullet1,0);
bullet1->setRotation(rotation);
int s = type;
}
首先根據不同的炮臺生成不同的子彈;
然後再點擊事件裏面給實現;
if (kil <= 70 && kil >= -70) {
rotation = kil;
battery1->setRotation(rotation);
shutBullet(type);
auto moveto = MoveBy::create(20.0f, Vec2((location.x - battery1->getPositionX()) * 1000, (location.y - battery1->getPositionY())*1000));
bullet1->runAction(moveto);
fenshu -= type;
}
這if判斷語句就是在炮臺旋轉時候設定的點擊事件;那麼就肯定要跟隨的;
之後又把魚給實現了;
在創建魚的時候我是每種魚給他一個方法;
在根據一個隨機數來判定哪種魚出現的頻率;
void Fish::creatfish()
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
fish1->setPosition(Vec2(visibleSize.width + fish1->getContentSize().width / 2, rand() % 640 + 100));
int ss = rand() % 640 + 100;
moves = rand() % 8 + 3;
auto move = MoveTo::create(moves, Vec2(-fish1->getContentSize().width / 2 , ss));
auto radian = atan2( - visibleSize.width , - fish1->getPositionY() + ss);
auto inclination = radian * 180 / 3.14;
auto rotation = (inclination)+90;
fish1->setRotation(rotation);
this->addChild(fish1);
fish1->runAction(move);
pget.pushBack(fish1);
}
void Fish::creatfish1()
{
fish1 = Sprite::createWithSpriteFrameName("GMarlinsFish_actor_001.png");
creatfish();
Animation* animation = Animation::create();
animation->setDelayPerUnit(moves / MOVE);
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_002.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_003.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_004.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_005.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_006.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_007.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_008.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_009.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_010.png"));
Animate* animate = Animate::create(animation);
fish1->runAction(RepeatForever::create(animate));
fishadd = 10;
}
上面是plist文件裏面的圖片;
這是其中的一個創建魚遊動的動畫的方法;
我還有這樣的方法六個 ;
由於代碼太多就複製一個;
void Fish::update(float dt)
{
type = rand() % 99 + 1;
if (type >= 1 && type < 5)
{
creatfish1();//金鯊魚
fishshu = 1;
}
if (type >= 5 && type < 30)
{
creatfish2();//花魚(小)
fishshu = 2;
}
if (type >= 30 && type < 35)
{
creatfish3();//藍鯊魚
fishshu = 3;
}
if (type >= 35 && type < 45)
{
creatfish4();//烏龜
fishshu = 4;
}
if (type >= 45 && type < 70)
{
creatfish5();//金魚(小)
fishshu = 5;
}
if (type >= 70 && type < 95)
{
creatfish6();//紅魚(小)
fishshu = 6;
}
if (type >= 95 && type <= 100)
{
creatfish7();//大魚(大)
fishshu = 7;
}
}
然後就是用一個計時器把魚出現的頻率給調整一下;
今天把所有創建的場景以及碰撞之間的關係給確定了一下;
最主要的是把魚與子彈碰撞的動畫給實現了;
其他的修飾修飾就好了;
先是在子彈類與魚類裏面的魚與子彈各自創建一個數組;
在Gamescene裏面調用;
通過計時器把魚與子彈的超出邊界給刪除;
for (int i = 0; i < fish1.size(); i++)
{
if (fish1.at(i)->getPositionX() <= - fish1.at(i)->getContentSize().width / 2)
{
fish->remove(fish1.at(i));
break;
}
}
for (int i = 0; i < bullet.size(); i++)
{
if (bullet.at(i)->getPositionX() <= - bullet.at(i)->getContentSize().width / 2||
bullet.at(i)->getPositionX() >= visibleSize.width + bullet.at(i)->getContentSize().width / 2||
bullet.at(i)->getPositionY() >= visibleSize.height + bullet.at(i)->getContentSize().height / 2)
{
battery->remove(bullet.at(i));
break;
}
}
再把碰撞的部分給完善;
for (int i = 0; i < fish1.size(); i++)
{
for (int j = 0; j < bullet.size(); j++)
{
if (fish1.at(i)->getBoundingBox().intersectsRect(bullet.at(j)->getBoundingBox())){
battery->remove(bullet.at(j));
bom(bullet.at(j));
//fish->remove(fish1.at(i));
if (bl == true)
{
fenshu += types * 10 * addfish;
fish->remove(fish1.at(i));
}
return;
}
}
bool bl 是碰撞隨機隨機死亡的一個函數,主要是增加遊戲的樂趣;
bool Fish::dispatch()
{
int xuan = rand() % 99 + 1;
if (fishshu == 1)
{
if (xuan <= 0.5*10*types)
{
return true;
}
}
if (fishshu == 2)
{
if (xuan <= 1.2*10*types)
{
return true;
}
}
if (fishshu == 3)
{
if (xuan <= 0.5*10 *types)
{
return true;
}
}
if (fishshu == 4)
{
if (xuan <= 0.8*10 *types)
{
return true;
}
}
if (fishshu == 5)
{
if (xuan <= 1.2*10 *types)
{
return true;
}
}
if (fishshu == 6)
{
if (xuan <= 1.2*10 *types)
{
return true;
}
}
if (fishshu == 7)
{
if (xuan <= 0.5*10*types)
{
return true;
}
}
}
fishshu指每種魚類的編號;
xuan也就給定的隨機數;
types是炮臺的等級,綜合以上的幾種情況給定概率死亡;
今天還有一個功能是把分數給實現了;
先給定一個初始分數;
每發射一發子彈減少相對應的分數;
這是在點擊onTouchEnded的時候減的;
fenshu -= type;
每捕捉到魚類也增加相應的分數;
fenshu += types * 10 * addfish;
addfish表示魚類增加的分數除以十,在魚類裏面每生成一次,給定一次;
char str[20];
sprintf(str, "%d", fenshu);
auto label2 = (Label*)getChildByTag(3);
label2->setString(str);
文本數組在場景中顯示,可實現分數的變化;可以在構造函數裏面先申明一下;
auto label = Label::createWithTTF( "","fonts/arial.ttf", 32);
label->setPosition(Vec2(origin.x + visibleSize.width/5 + 15,origin.y + label->getContentSize().height/2 +15));
this->addChild(label, 3 ,3);
label->setColor(Color3B::BLUE);
做到現在還差的就是魚的死亡動畫了;
其他擴展的就慢慢來吧,趁着週末好好的溫習一下;
下星期要接觸RPG類的遊戲了,希望可以很好的掌握。