标签:
本章节实现武器设计:hand枪每次一发,机枪可以连续发射。武器旋转到任何一个方向发射子弹。
首先添加武器类:
//武器基类
class arm :public cocos2d::Sprite
{
public:
//初始化子弹
virtual bool initbullet() = 0;
//发射
virtual void fire() = 0;
//停止发射 用于自动机枪
virtual void stopfire() = 0;
//获取子弹点火位置
Vec2 getBeginfirePos()const;
//获取子弹点火离开武器位置
Vec2 getEndfirePos()const;
//获取武器旋转点
Vec2 getRotationPos();
//设置点火位置
void setBeginfirePos(Vec2& _firePos);
//设置子弹发射位置
void setEndfirePos(Vec2& _gunPoint);
ssize_t getbulletCount()const;
protected:
// _beginfire和_endfire 一起用来计算子弹的平面向量
Sprite* _beginfire;
Sprite* _endfire;
Sprite* _rotation;
//最多携带子弹数
ssize_t _bulletMaxCount;
//子弹
std::vector<bullet*> _bullet;
};
///handgun的 实现基类的虚函数
class handGun :public arm
{
public:
virtual bool init()override;
virtual bool initbullet();
virtual void fire();
virtual void stopfire();
CREATE_FUNC(handGun);
};
///机枪 实现基类的虚函数
class machineGun :public arm{
public:
virtual bool init()override;
virtual bool initbullet();
virtual void fire();
virtual void stopfire();
//多一个自动发射函数 这里由定时器调用
void autofire(float);
CREATE_FUNC(machineGun);
private:
};
//cpp
#include "arm.h"
#include "bullet.h"
Vec2 arm::getBeginfirePos()const
{
return _beginfire->getPosition();
}
Vec2 arm::getEndfirePos()const
{
return _endfire->getPosition();
}
Vec2 arm::getRotationPos()
{
//转换世界坐标 在鼠标点击的时候也是转换成世界坐标
return convertToWorldSpace(_rotation->getPosition());
}
void arm::setBeginfirePos(Vec2& _firePos)
{
_beginfire->setPosition(_firePos);
}
void arm::setEndfirePos(Vec2& _endPos)
{
_endfire->setPosition(_endPos);
}
ssize_t arm::getbulletCount()const
{
return _bullet.size();
}
bool handGun::init()
{
_beginfire = Sprite::create();
_endfire = Sprite::create();
_rotation = Sprite::create();
addChild(_beginfire);
addChild(_endfire);
addChild(_rotation);
_bulletMaxCount = 10;
return true;
}
bool handGun::initbullet()
{
auto count = _bullet.size();
for (; count != _bulletMaxCount; count++){
auto handbullet = bullet::create();
handbullet->initWithFile("arm1.png");
handbullet->setSpeed(5);
handbullet->setVisible(false);
_bullet.push_back(handbullet);
addChild(handbullet);
}
//设置旋转中心
_rotation->setPosition(getPosition() + getContentSize() / 2);
return !!_bullet.size();
}
void handGun::fire()
{
if (_bullet.size() < 1){
initbullet();
}
auto handbullet = _bullet.back();
_bullet.erase(_bullet.end() - 1);
//计算方向
auto direction = convertToWorldSpace(getEndfirePos()) - convertToWorldSpace(getBeginfirePos());
handbullet->setDirection(direction);
auto pos = convertToWorldSpace(getEndfirePos());
pos += handbullet->getContentSize() / 2;
handbullet->setPosition(pos);
handbullet->setName("bullet");
auto Parent = getParent();
handbullet->retain();
removeChild(handbullet,false);
Parent->addChild(handbullet, true);
handbullet->release();
handbullet->setVisible(true);
}
void handGun::stopfire()
{
}
bool machineGun::init()
{
_beginfire = Sprite::create();
_endfire = Sprite::create();
_rotation = Sprite::create();
addChild(_beginfire);
addChild(_endfire);
addChild(_rotation);
_bulletMaxCount = 100;
return true;
}
bool machineGun::initbullet()
{
auto count = _bullet.size();
for (; count != _bulletMaxCount; count++){
auto handbullet = bullet::create();
handbullet->initWithFile("arm1.png");
handbullet->setSpeed(10);
handbullet->setVisible(false);
_bullet.push_back(handbullet);
addChild(handbullet);
}
_rotation->setPosition(getPosition() + getContentSize() / 2);
return !!_bullet.size();
}
void machineGun::fire()
{
//设置定时器 0.1s调用一次
schedule(schedule_selector(machineGun::autofire), 0.1f);
}
void machineGun::stopfire()
{
//停止定时器
this->unschedule(schedule_selector(machineGun::autofire));
}
void machineGun::autofire(float)
{
if (_bullet.size() < 1){
initbullet();
}
auto handbullet = _bullet.back();
_bullet.erase(_bullet.end() - 1);
auto direction = convertToWorldSpace(getEndfirePos()) - convertToWorldSpace(getBeginfirePos());
handbullet->setDirection(direction);
auto pos = convertToWorldSpace(getEndfirePos());
pos += handbullet->getContentSize() / 2;
handbullet->setPosition(pos);
handbullet->setName("bullet");
auto Parent = getParent();
handbullet->retain();
removeChild(handbullet, false);
Parent->addChild(handbullet, true);
handbullet->release();
handbullet->setVisible(true);
}
//子弹类
class bullet:public Sprite
{
public:
int getSpeed()const;
Vec2 getDirection()const;
void setSpeed(int _speed);
void setDirection(Vec2& _direction);
//子弹移动
virtual void move();
CREATE_FUNC(bullet);
private:
int _speed;
Vec2 _direction;
};
//cpp 自动实现方法
int bullet::getSpeed()const
{
return _speed;
}
Vec2 bullet::getDirection()const
{
return _direction;
}
void bullet::setSpeed(int _speed)
{
this->_speed = _speed;
}
void bullet::setDirection(Vec2& _direction)
{
this->_direction = _direction;
}
void bullet::move()
{
float degree = 0;
int dirx = 1; //X 轴方向
int diry = 1; //Y 轴方向
_direction.normalize();
if (_direction.x < 0){
dirx = -1;
}
if (_direction.y < 0){
diry = -1;
}
//计算弧度 [0 pi/2)
degree = atan(fabs(_direction.y / _direction.x));
Vec2 location = getPosition();
location.x += cos(degree)*_speed*dirx;
location.y += sin(degree)*_speed*diry;
setPosition(location);
}
//Scene
fireScene::init()
{
.
.
.
auto handgun = handGun::create();
handgun->initWithFile("fire/handgun.png");
handgun->setPosition(origin + Vec2(visibleSize) / 2);
handgun->setBeginfirePos(Vec2(125, 170));
handgun->setEndfirePos(Vec2(225, 170));
handgun->setName("handgun");
this->addChild(handgun, 1);
handgun->initbullet();
auto machinegun = machineGun::create();
machinegun->setBeginfirePos(Vec2(110, 146));
machinegun->setEndfirePos(Vec2(255, 146));
machinegun->initWithFile("fire/machinegun.png");
machinegun->setName("machinegun");
machinegun->setPosition(origin + Vec2(visibleSize) - Vec2(100, 100) - Vec2(label->getContentSize() / 2));
this->addChild(machinegun, 1);
machinegun->initbullet();
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = [](Touch* touch, Event* event){
auto tarter = event->getCurrentTarget();
auto s = tarter->getContentSize();
auto locationNode = tarter->convertToNodeSpace(touch->getLocation());
Rect rect = Rect{ 0, 0, s.width, s.height };
if (rect.containsPoint(locationNode)){
auto gunarm = static_cast<arm*>(tarter);
gunarm->fire();
return true;
}
return false;
};
listener->onTouchMoved = [this](Touch* touch, Event* event){
auto pNode = event->getCurrentTarget();
auto gun = static_cast<arm*>(pNode);
auto rotationpos = gun->getRotationPos();
Vec2 v = (convertToWorldSpace(touch->getLocation()) - rotationpos) - (convertToWorldSpace(touch->getPreviousLocation()) - rotationpos);
v.normalize();
if (v.x >= -0.00001 && v.x <= 0.00001 || v.y >= -0.00001 && v.y <= 0.00001)
{
return;
}
auto degree = CC_RADIANS_TO_DEGREES(atan2(v.x, v.y));
pNode->setRotation(degree);
};
listener->onTouchEnded = [](Touch* touch, Event* event){
auto pNode = event->getCurrentTarget();
if (strcmp(pNode->getName().c_str(), "machinegun") == 0){
static_cast<machineGun*>(pNode)->stopfire();
}
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, handgun);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), machinegun);
return true;
}
来一张机枪发射图片 不要在意图片外观。。。

标签:
原文地址:http://www.cnblogs.com/beat/p/4907225.html