This chapter implements the weapon design: each time the hand gun, the machine gun can be fired continuously. The weapon spins in either direction to launch bullets.
Download source code
First add the Weapon class:
Weapon base class arm:p ublic cocos2d::sprite{public: //init bullet virtual bool Initbullet () = 0; Launch virtual void fire () = 0; Stop launch for automatic machine gun virtual void stopfire () = 0; Get the bullet ignition position VEC2 getbeginfirepos () const; Get the bullet ignition away from the weapon position VEC2 Getendfirepos () const; Get weapon rotation point Vec2 getrotationpos (); Set ignition position void Setbeginfirepos (vec2& _firepos); Set the bullet launch position void Setendfirepos (vec2& _gunpoint); ssize_t Getbulletcount () const;protected: //_beginfire and _endfire are used to calculate the plane vector sprite* _beginfire of bullets; sprite* _endfire; sprite* _rotation; Maximum number of bullets ssize_t _bulletmaxcount; Bullets std::vector<bullet*> _bullet;};
Handgun implements the virtual function of the base class handgun:p ublic arm{public: virtual BOOL init () override; virtual bool Initbullet (); virtual void Fire (); virtual void Stopfire (); Create_func (handgun);};/ Machine gun implements the virtual function of the base class, class machinegun:p ublic arm{public: virtual BOOL init () override; virtual bool Initbullet (); virtual void Fire (); virtual void Stopfire (); One more auto-emitting function here called by the timer void autofire (float); Create_func (machinegun);p rivate:};
Cpp#include "arm.h" #include "bullet.h" Vec2 arm::getbeginfirepos () const{return _beginfire->getposition ();} VEC2 Arm::getendfirepos () const{return _endfire->getposition (); VEC2 Arm::getrotationpos () {//convert world coordinates when mouse clicks are also converted to world coordinates 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); }//Set Rotation center _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); Calculation direction 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 () {//Set timer 0.1s to call once Schedule (Schedule_selector (Machinegun::autofire), 0.1f);} void Machinegun::stopfire () {//Stop timer 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);}
Bullet class Bullet:public sprite{public: int getspeed () const; VEC2 getdirection () const; void setspeed (int _speed); void Setdirection (vec2& _direction); Bullet move virtual void move (); Create_func (bullet);p rivate: int _speed; VEC2 _direction;};
CPP Automatic Implementation method 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-axis direction int diry = 1; Y-axis Direction _direction.normalize (); if (_direction.x < 0) { DirX =-1; } if (_DIRECTION.Y < 0) { DirY =-1; } Calculate radians [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);}
Scenefirescene::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 (+)-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;}
Take a shot of a machine gun shoot pictures don't care about the appearance of the picture ...
Iii. weapon shooting and automatic shooting