Search code examples
androidcocoa-touchgame-enginecocos2d-android

How to make "projectile"(bullets) to fire up when tapped or touched on the tip of the cannon in cocos2d android


I'm Developing android game app using Cocos2d-android game engine, in my game there is a cannon, when the player taps on the gamelayer "projectile" fires out, but according to my requirements when tapped on the tip of cannon "projectile" should come out, this can be done by using setposition of the cannon but here the cannons are rotatable, so got stuck up in giving the setposition. Here's the code

public class GameL extends CCLayer{

protected LinkedList<CCSprite> _targets;
protected LinkedList<CCSprite> _projectiles;
protected int _projectilesDestroyed;
protected CCSprite _player;
protected CCSprite _nextProjectile;

public static CCScene scene()
{
    CCScene scene = CCScene.node();
    CCLayer layer = new GameL();

    scene.addChild(layer);  

    return scene;     
}


protected GameL()
{
  this.setIsTouchEnabled(true);

    _targets = new LinkedList<CCSprite>();
    _projectiles = new LinkedList<CCSprite>();
    _projectilesDestroyed = 0;

    CCSprite background = CCSprite.sprite("bg.png");
    background.setTag(1);
    background.setAnchorPoint(0, 0);
    addChild(background);

    Context context = CCDirector.sharedDirector().getActivity();

    CGSize winSize = CCDirector.sharedDirector().displaySize();
 _player = CCSprite.sprite("gun2.png");
_player.setPosition(CGPoint.ccp(65,120));
 // _player.setPosition(CGPoint.ccp(_player.getContentSize().width/2.0f, winSize.height/2.0f));
     addChild(_player);

    this.schedule("gameLogic", 1.0f);
    this.schedule("update");
 }


@Override
public boolean ccTouchesEnded(MotionEvent event)
{
    // Choose one of the touches to work with
    CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY()));

    // Set up initial location of projectile
    CGSize winSize = CCDirector.sharedDirector().displaySize();
CCSprite _nextProjectile = CCSprite.sprite("firebl.png");  

    //_nextProjectile.setPosition(20, winSize.height / 2.0f);
_nextProjectile.setPosition(CGPoint.ccp(65, 120));

    // Determine offset of location to projectile
    int offX = (int)(location.x - _nextProjectile.getPosition().x);
    int offY = (int)(location.y - _nextProjectile.getPosition().y);

    // Bail out if we are shooting down or backwards
    if (offX <= 0)
        return true;

    _nextProjectile.setTag(2);

    // Determine where we wish to shoot the projectile to
    int realX = (int)(winSize.width + (_nextProjectile.getContentSize().width / 2.0f));
    float ratio = (float)offY / (float)offX;
    int realY = (int)((realX * ratio) + _nextProjectile.getPosition().y);
    CGPoint realDest = CGPoint.ccp(realX, realY);

    // Determine the length of how far we're shooting
    int offRealX = (int)(realX - _nextProjectile.getPosition().x);
    int offRealY = (int)(realY - _nextProjectile.getPosition().y);
    float length = FloatMath.sqrt((offRealX * offRealX) + (offRealY * offRealY));
    float velocity = 480.0f / 1.0f; // 480 pixels / 1 sec
    float realMoveDuration = length / velocity;

    // Move projectile to actual endpoint
    _nextProjectile.runAction(CCSequence.actions(
            CCMoveTo.action(realMoveDuration, realDest),
            CCCallFuncN.action(this, "spriteMoveFinished")));

    // Determine angle to face
    double angleRadians = Math.atan((double)offRealY / (double)offRealX);
    double angleDegrees = Math.toDegrees(angleRadians);
    double cocosAngle = -1 * angleDegrees;
    double rotationSpeed = 0.5 / Math.PI;
    double rotationDuration = Math.abs(angleRadians * rotationSpeed);
    _player.runAction(CCSequence.actions(
            CCRotateTo.action((float)rotationDuration, (float)cocosAngle),
            CCCallFunc.action(this, "finishShoot")));

    // Pew!
    Context context = CCDirector.sharedDirector().getActivity();
    SoundEngine.sharedEngine().playEffect(context, R.raw.pew_pew_lei);

    return true;
}  

public void finishShoot()
{
    addChild(_nextProjectile);
    _projectiles.add(_nextProjectile);
}

public void gameLogic(float dt)  
{
    addTarget();
}

public void update(float dt)
{
    LinkedList<CCSprite> projectilesToDelete = new LinkedList<CCSprite>();

    for (CCSprite projectile : _projectiles)
    {
        CGRect projectileRect = CGRect.make(projectile.getPosition().x - (projectile.getContentSize().width / 2.0f),
                                            projectile.getPosition().y - (projectile.getContentSize().height / 2.0f),
                                            projectile.getContentSize().width,
                                            projectile.getContentSize().height);

        LinkedList<CCSprite> targetsToDelete = new LinkedList<CCSprite>();

        for (CCSprite target : _targets)
        {
            CGRect targetRect = CGRect.make(target.getPosition().x - (target.getContentSize().width),
                                            target.getPosition().y - (target.getContentSize().height),
                                            target.getContentSize().width,
                                            target.getContentSize().height);

            if (CGRect.intersects(projectileRect, targetRect))
                targetsToDelete.add(target);
        }

        for (CCSprite target : targetsToDelete)
        {
            _targets.remove(target);
            removeChild(target, true);
        }

        if (targetsToDelete.size() > 0)
            projectilesToDelete.add(projectile);
    }

    for (CCSprite projectile : projectilesToDelete)
    {
        _projectiles.remove(projectile);
        removeChild(projectile, true);

        if (++_projectilesDestroyed > 30)
        {
            _projectilesDestroyed = 0;
            CCDirector.sharedDirector().replaceScene(Gameoverlayer.scene("You Win!"));
        }
    }
}

Solution

  • Probably you have to add condition of the canon sprite and touch location replace the below code with touchBegan

        public boolean ccTouchesBegan(MotionEvent event)
        {
           CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY()));
    
            // Set up initial location of projectile
            CGSize winSize = CCDirector.sharedDirector().displaySize();
            _nextProjectile = CCSprite.sprite("fireball50.png");
    
            // _nextProjectile.setPosition(20, winSize.height / 2.0f);
            _nextProjectile.setPosition(CGPoint.ccp(65, 120));
    
    
            for (CCSprite target : targets)
                {
    
                    if (CGRect.containsPoint((target.getBoundingBox()), location))
                        {
    
                            // Determine offset of location to projectile
                            int offX = (int) (location.x - _nextProjectile.getPosition().x);
                            int offY = (int) (location.y - _nextProjectile.getPosition().y);
    
                            // Bail out if we are shooting down or backwards
    
                            _nextProjectile.setTag(3);   
                            // Determine where we wish to shoot the projectile
                            // to
                            int realX = (int) (winSize.width + (_nextProjectile.getContentSize().width / 2.0f));
                            float ratio = (float) offY / (float) offX;
                            int realY = (int) ((realX * ratio) + _nextProjectile.getPosition().y);
                            CGPoint realDest = CGPoint.ccp(realX, realY);
    
                            // Determine the length of how far we're shooting
                            int offRealX = (int) (realX - _nextProjectile.getPosition().x);
                            int offRealY = (int) (realY - _nextProjectile.getPosition().y);
                            float length = FloatMath.sqrt((offRealX * offRealX) + (offRealY * offRealY));
                            float velocity = 480.0f / 1.0f; // 480 pixels / 1
                                                            // sec
                            float realMoveDuration = length / velocity;
                            System.out.println(" - t tag!!!!!!!!!!!!!!!!!!!!! - ");
                            _nextProjectile.runAction(CCSequence.actions(CCMoveTo.action(realMoveDuration, realDest),
                                    CCCallFuncN.action(this, "spriteMoveFinished")));
                            double angleRadians = Math.atan((double) offRealY / (double) offRealX);
                            double angleDegrees = Math.toDegrees(angleRadians);
                            double cocosAngle = -1 * angleDegrees;
                            double rotationSpeed = 0.5 / Math.PI;
                            double rotationDuration = Math.abs(angleRadians * rotationSpeed);
    
                            target.runAction(CCSequence.actions(
                                    CCRotateTo.action((float) rotationDuration, (float) cocosAngle),
                                    CCCallFunc.action(this, "finishShoot")));
                            break;
                        }
                }
    
    
            return true;
        }