zoukankan      html  css  js  c++  java
  • 切换发射使用TileMap制作游戏,在cocos2dx中使用(三)

    查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!

        

    本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/8881664

        游戏么,得有胜负、朋友。

        地图编辑的一些方法,传送门:http://www.cnblogs.com/andyque/archive/2011/05/07/2039481.html

        上面入加朋友:

    void HelloWorld::addEnemy(int x,int y)
    {
    	CCSprite* enemy = CCSprite::create("enemy1.png");
    	enemy->setPosition(ccp(x,y));
    	addChild(enemy);
    	//moveEnemy(enemy);
    	m_enemies->addObject(enemy);
    }

        接下来使朋友动移,这里跟官方的不太一样。我用采的是在屏幕上表现的怪能动移。

        做出来的有点小问题:isRunning数函乎似有问题,不能用。嫌费事自己没写类。

        所以有个小Bug,有兴致的读者可以改改,自己写个子类,然后设置个动没动的标记。

    void HelloWorld::moveEnemy(CCSprite* enemy)
    { 
    	CCPoint diff = ccpSub(m_player->getPosition(),enemy->getPosition());
    	float angleRadians = atanf((float)diff.y / (float)diff.x);
    	float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
    	float cocosAngle =-1* angleDegrees;
    	if (diff.x <0) {
    		cocosAngle +=180;
    	}
    	enemy->setRotation(cocosAngle);	
    
    	int x = m_player->getPosition().x;
    	int y = m_player->getPosition().y;
    	CCActionInterval* move = CCMoveBy::create(3.0f, ccpSub(m_player->getPosition(),enemy->getPosition()));
    	enemy->runAction(CCSequence::create(move,
    		CCCallFuncN::create(this,callfuncN_selector(HelloWorld::enemyMoveFinished)),NULL));
    }

        

        环循的调回是要必的,因为玩家的置位会改更,目标标坐会变改。

    //此处如此计划因为玩家置位会发生变化,须要复重获得
    void HelloWorld::enemyMoveFinished(CCNode* node)
    {
    	CCSprite* enemy = (CCSprite*)node;
    	moveEnemy(enemy);
    }
    void HelloWorld::checkMoveEnemy(CCPoint center)
    {
    	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    	center = convertToNodeSpace(center);
    	CCRect screen = CCRectMake(center.x-winSize.width/2,center.y-winSize.height/2,winSize.width,winSize.height);
    	CCObject* e = NULL;
    	CCARRAY_FOREACH(m_enemies,e)
    	{
    		CCSprite* enemy =  dynamic_cast<CCSprite*>(e);
    		CCPoint temp = enemy->getPosition();
    		CCPoint pos = convertToNodeSpace(temp);  
    
    		if(screen.containsPoint(pos))
    		{
    			//此处会有复重调用的问题,即对已动移的怪调用runAction
    			//if(enemy->isRunning()) //这个数函不能用?
    			moveEnemy(enemy);
    		}
    	}
    }

        有怪了就得打,接下来是发射飞镖。

        因为是触控,没法用键盘那么高端,这里用采切换模式的方法,即动移和发射飞镖两种模式切换。

        切换的表现要用CCMenuItemToggle来做,把它放在CCMenu中,再放在ScoreLayer中。

        发射飞镖就用之前那个最易简的忍者游戏的代码就行。

    void HelloWorld::sendProjectile(CCSprite* projectile,CCPoint pos)
    {
    
    	int realX;
    
    	CCPoint diff = ccpSub(pos, m_player->getPosition());
    	if (diff.x >0)
    	{
    		realX = (m_tileMap->getContentSize().width) +
    			(projectile->getContentSize().width/2);
    	} 
    	else {
    		realX =-(m_tileMap->getContentSize().width) -
    			(projectile->getContentSize().width/2);
    	}
    	float ratio = (float) diff.y / (float) diff.x;
    	int realY = ((realX - projectile->getPositionX()) * ratio) + projectile->getPositionY();
    	CCPoint realDest = ccp(realX, realY);
    
    	// Determine the length of how far we're shooting
    	int offRealX = realX - projectile->getPositionX();
    	int offRealY = realY - projectile->getPositionY();
    	float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY));
    	float velocity =480/1; // 480pixels/1sec
    	float realMoveDuration = length/velocity;
    
    	CCActionInterval* throwProjectile = CCMoveTo::create(realMoveDuration,realDest);
    	projectile->runAction(CCSequence::create(throwProjectile,
    		CCCallFuncN::create(this,callfuncN_selector(HelloWorld::projectileMoveFinished)),NULL));
    
    }
        每日一道理
    自己把自己说服了,是一种理智的胜利;自己被自己感动了,是一种心灵的升华;自己把自己征服了,是一种人生的成功。

        

    void HelloWorld::projectileMoveFinished(CCNode* object)
    {
    	CCSprite* p = (CCSprite* )object;
    	if(p)
    	{
    		removeChild(p,true);
    		m_projectiles->removeObject(p);
    	}
    }

        碰撞检测也一样,查检飞镖与朋友否是相遇,另外要入加朋友与玩家相遇的逻辑。

    void HelloWorld::checkHit(float dt)
    {
    	CCArray* projectilesToDelete = new CCArray;
    	CCArray* targetToDelete = new CCArray;
    	CCObject* it = NULL;
    	CCObject* jt = NULL;
    	CCRect playerRect = CCRectMake(
    				m_player->getPositionX() - m_player->getContentSize().width/2,
    				m_player->getPositionY() - m_player->getContentSize().height/2,
    				m_player->getContentSize().width,
    				m_player->getContentSize().height);
    
    	CCARRAY_FOREACH(m_projectiles,it)
    	{
    		CCSprite * projectile = dynamic_cast<CCSprite*>(it);
    		CCRect projectileRect = CCRectMake(
    			projectile->getPositionX() - projectile->getContentSize().width/2,
    			projectile->getPositionY() - projectile->getContentSize().height/2,
    			projectile->getContentSize().width,
    			projectile->getContentSize().height);
    		CCARRAY_FOREACH(m_enemies,jt)
    		{
    			CCSprite* target = dynamic_cast<CCSprite*>(jt);
    			CCRect targetRect = CCRectMake(
    				target->getPositionX() - target->getContentSize().width/2,
    				target->getPositionY() - target->getContentSize().height/2,
    				target->getContentSize().width,
    				target->getContentSize().height);
    			if(projectileRect.intersectsRect(targetRect))
    			{
    				targetToDelete->addObject(target);
    			}
    			
    		}
    		CCARRAY_FOREACH(targetToDelete,jt)
    		{
    			CCSprite* delTarget = dynamic_cast<CCSprite*>(jt);
    			m_enemies->removeObject(delTarget,true);
    			this->removeChild(delTarget,true);
    		}
    		if(targetToDelete->count() >0)
    		{
    			projectilesToDelete->addObject(projectile);
    		}
    		targetToDelete->removeAllObjects();
    	}
    	CCARRAY_FOREACH(projectilesToDelete,it)
    	{
    		CCSprite* delProject = dynamic_cast<CCSprite*>(it);
    		m_projectiles->removeObject(delProject);
    		this->removeChild(delProject,true);
    	}
    	CCARRAY_FOREACH(m_enemies,jt)
    	{
    		CCSprite* target = dynamic_cast<CCSprite*>(jt);
    		CCRect targetRect = CCRectMake(
    				target->getPositionX() - target->getContentSize().width/2,
    				target->getPositionY() - target->getContentSize().height/2,
    				target->getContentSize().width,
    				target->getContentSize().height);
    
    		if(playerRect.intersectsRect(targetRect))
    		{
    			GameOverSecne *gameOverScene = GameOverSecne::create();
    			gameOverScene->getLayer()->getLabel()->setString("You Lose!");
    			CCDirector::sharedDirector()->replaceScene(gameOverScene);
    		}
    	}
    	targetToDelete->release();
    	projectilesToDelete->release();
    }

        最后加上胜负界面:吃掉西瓜就赢,遇到怪物就输。

        用的之前易简忍者游戏的那个GameOverScene。体具可以看我的码源。

        编译运行吧,少年。

        我觉感我这版游戏,关卡计划还是有点难的,打了半天才赢...

        

        等过CSDN审核,上码源:

        

        

        

    文章结束给大家分享下程序员的一些笑话语录: 看到有人回帖“不顶不是中国人”,他的本意是想让帖子沉了。

  • 相关阅读:
    给webstorm换个背景图
    css遮罩 mask属性
    svg图标
    BFC原理
    轮播图与图片查看器
    超大分辨率屏幕适配方案
    移动端适配-动态计算rem
    [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. 报错
    由于ie浏览器ajax缓存 导致layui table表格重载失败的解决办法
    实现线程操作的三种方法
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3060174.html
Copyright © 2011-2022 走看看