使用Cocos2d-x-3.0游戏引擎。编写一个瓦片地图游戏 part05

上一篇地址:http://www.cocoachina.com/bbs/read.php?tid=197159

  1. The Shout

    吼,你也可以称之为杀敌技能。就像上古卷轴5里的龙裔。现在我们添加一个新的按钮在转换移动和吼叫模式。

添加这些代码删除那些已经移动出瓦片地图外的吼叫。

In the ‘HelloWorldScene.h’:

void projectileMoveFinished(cocos2d::Object *pSender);
```

In the ‘HelloWorldScene.cpp’:
void HelloWorld::projectileMoveFinished(Object *pSender)
{
    Sprite *sprite = (Sprite *)pSender;
    this->removeChild(sprite);
}


void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event)
{
if (_mode == 0) {
``````
// the original code we have typed 
``````
} else {
 auto touchLocation = touch->getLocation();
 touchLocation = this->convertToNodeSpace(touchLocation);


 auto projectile = Sprite::create("bullet.png");
 projectile->setPosition(_player->getPosition());
 projectile->setScale(0.25);
 this->addChild(projectile);


 int realX;


 auto diff = touchLocation - _player->getPosition();
 if (diff.x > 0)
 {
 realX = (_tileMap->getMapSize().width * _tileMap->getTileSize().width) + 
 (projectile->getContentSize().width / 2);
 }
 else {
 realX = -(_tileMap->getMapSize().width * _tileMap->getTileSize().width) -
 (projectile->getContentSize().width / 2);
 }
 float ratio = (float)diff.y / (float)diff.x;
 int realY = ((realX - projectile->getPosition().x) * ratio) +projectile->getPosition().y;
 auto realDest = Point(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; // 480pixels/1sec
 float realMoveDuration = length / velocity;


 auto actionMoveDone =CallFuncN::create(CC_CALLBACK_1(HelloWorld::projectileMoveFinished, this));
   projectile->runAction(Sequence::create(MoveTo::create(realMoveDuration,realDest), actionMoveDone, NULL))


 _projectiles.pushBack(projectile);
 }
}

```


首先我们获得手指碰触的地点。并且创建吼叫的图片精灵。之后,我们决定应该方向,放行时间。


现在我们实现了我们想要的功能:转换的按钮和吼叫。但是我们也能看到问题:即使我们的攻击技能吼叫碰触到了敌人,我们的敌人也没有受损。
   
The button & Shout



12. Collision detect
碰撞检测
In the ‘HelloWorldScene.h’:
cocos2d::Vector _enemies;
cocos2d::Vector _projectiles;
```

In the ‘HelloWorldScene.cpp’:
Add those codes at the end of the launch projectiles section of ‘onTouchEnded’:
_projectiles.pushBack(projectile);
```



Add those codes at the end of the ‘projectileMoveFinished’:
_projectiles.eraseObject(sprite);
```



Add those codes at the end of the ‘addEnemyAtPos’:
_enemies.pushBack(enemy);
```





void HelloWorld::testCollisions(float dt)
{
    Vector projectilesToDelete;


    for (Sprite *projectile : _projectiles) {
        auto projectileRect = Rect(
            projectile->getPositionX() - projectile->getContentSize().width / 2,
            projectile->getPositionY() - projectile->getContentSize().height / 2,
            projectile->getContentSize().width,
            projectile->getContentSize().height);


        Vector targetsToDelete;


        for (Sprite *target : _enemies) {
            auto targetRect = Rect(
                target->getPositionX() - target->getContentSize().width / 2,
                target->getPositionY() - target->getContentSize().height / 2,
                target->getContentSize().width,
                target->getContentSize().height);


            if (projectileRect.intersectsRect(targetRect)) {
                targetsToDelete.pushBack(target);
            }
        }


 
        for (Sprite *target : targetsToDelete) {
            _enemies.eraseObject(target);
            this->removeChild(target);
        }


        if (targetsToDelete.size() > 0) {
            // add the projectile to the list of ones to remove
            projectilesToDelete.pushBack(projectile);
        }
        targetsToDelete.clear();
    }


 
    for (Sprite *projectile : projectilesToDelete) {
        _projectiles.eraseObject(projectile);
        this->removeChild(projectile);
    }
    projectilesToDelete.clear();
}

```


Finally, we type these code in the 
bool HelloWorld::init()
{
``````
this->schedule(schedule_selector(HelloWorld::testCollisions));
return true;
}
我们首先获得吼叫图片和敌人图片的大小,然后确认这些图片时候碰撞到了对方。如果碰触到了,就将其加入数组,并将其在这些数组种的对象删除。




Now it should working like this:
  

 
Only one left


完~

感谢楼主分享!

:5:依然是我:4:

·····················
谢谢支持·····

完整啊,和RPG Maker很像啊。

一直跟着楼主教程,在自己的做好了第一款游戏。不过最后实现刷怪和移动有冲突啊,不知道楼主有没方法可以改变这种状况呢

你是说:需要按按钮才能切换移动和攻击么?因为这个引擎主要是开发手机触屏游戏。触屏的输入比较单一,所以大多数游戏都会创建一个按钮实现功能切换。
你也可以再做个按钮专门实现移动,触屏全改为攻击

没有做地图滚动吗,这才是难点

你是指用“listener->setSwallowTouches(true);” 然后鼠标点住地图某一点然后拖动整个屏幕?

感谢楼主分享

MARK&&DAY DAY UP!:2:

对tiled map工具使用不熟悉,希望楼主做个此工具的详细教程!
同时,能给出可运行的代码不!谢谢

五篇教程中给出的代码就是全部可运行的代码。教程一里面的下载资源里就有做好的Tile地图可供参考。关于Tile Map Editor 工具的教程我会考虑的。:2:

我没表达清楚,因为需要Tiled编辑生成tmx文件,因对工具不熟悉,操作细节未知,生成不完整的tmx,程序在使用报null,找不到相关的对象,能提供下最终的tmx文件,我看了其他资源文件都在,你也说了,背景音乐,自己去找个喜欢的

“报null,找不到相关的对象”!你是不是用了中文?还是后缀名没加上?还是旧代码没删除?

我已经给过一天的练习,已经会操作tiled工具了,对于加不同的按钮来解决是移动还是攻击,有什么好的建议,就是比较详细的说明,或有可参考的文章等,谢谢

终于敲完了~~~~:7:
几个小问题

为毛我赶脚楼主是在翻译!!!!!:5:

vector的push、erase和array的add、remove是一样的吧?

得到子弹和怪物的边框可以getBoundingBox啊~~

卤煮的子弹和边框检测的代码是借鉴demo里面的那个小游戏啊,那个小游戏写的很蛋疼的:9:,又带坏小朋友~~~

卤煮的backGround还是没用到啊~~我觉得可以做成遮挡效果的,

关于攻击和移动的模式可以做成屏幕左半部分移动, 右半部分攻击,当然中心点不再用_player,貌似要开多点触控,多点模拟器貌似测试不出来:3:

最后,卤煮辛苦了!感谢ing:14:

谢谢楼主的精彩教程,受益非浅

谢谢楼主分享

感谢楼主:14::14::14: