实现一个从空中飞来各种武器:飞镖,菜刀,斧头、刀子,还有各种蔬菜水果作为障碍物,所有东西飞向屏幕中央,主角站在正中心去躲避武器,武器打到身上会受到伤害,蔬菜水果不会,代码实现如下:
.cpp文件
.h文件
#ifndef __SCATTER_H__
#define __SCATTER_H__
#include "cocos2d.h"
#include "Box2D/Box2D.h"
#include "Characters/Hero.h"
#include "Characters/Hero2.h"
#include "Characters/Hero3.h"
#include "Characters/Hero4.h"
#include "global.h"
class GameScene;
#include "Scene/GameScene.h"
USING_NS_CC;
class SmritiShadow:public CCNode
{
public:
~SmritiShadow();
void draw();
CREATE_FUNC(SmritiShadow)
bool init();
void onDraw();
static void reset();
void setTarget(CCSprite* spr,CCTexture2D* tex);
static CCGLProgram * pg;
CCSprite* target;
CCTexture2D *texture2d;
Vertex *Vertices;
long pretime;
int arrcount;
GLuint vertexBuffer;
GLuint indexBuffer;
};
class BodyDef;
class b2Body;
namespace cocos2d {
class GB2ShapeCache {
public:
// Static interface
static GB2ShapeCache* sharedGB2ShapeCache(void);
public:
bool init();
void addShapesWithFile(const std::string &plist);
void addFixturesToBody(b2Body *body, const std::string &shape);
cocos2d::CCPoint anchorPointForShape(const std::string &shape);
void reset();
float getPtmRatio() { return ptmRatio; }
~GB2ShapeCache() {}
private:
std::map<std::string, BodyDef *> shapeObjects;
GB2ShapeCache(void) {}
float ptmRatio;
};
}
class ContactListener : public b2ContactListener
{
public:
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
};
class Scatter:public CCNode
{
public:
~Scatter();
static Scatter* gthis;
virtual void draw();
void onDraw();
CREATE_FUNC(Scatter)
bool init();
void addNewSpriteWithCoords(CCPoint p);
void addBullet(int dr);
void update(float dt);
void porr();
void setdifficulty(float df);
void touchhandle(CCPoint curpt);
void attackhandle(b2Body* b);
void reset();
void delayremove(CCNode* node,void* param);
void setHitct(int ct);
void setOverListener(CCObject* pSelectorTarget,SEL_CallFunc win,SEL_CallFunc fail);
CCObject* m_pSelector;
ContactListener* contactListener;
CCTexture2D *texture2d;
SEL_CallFunc m_wsc,m_fsc;
b2World *m_world;
std::vector<b2Body*> m_bodies;
void setoff(float x);
Hero *hero;
float m_level,m_levelf;
long pretime,pretimef;
float attackdelay;
CCPoint attackpoint;
int m_curhitcount,m_hitct;
int isover,ispause,status;
float speed;
float xoff;
float mindis;
void actionOver(CCObject* node,void* param);
std::map<CCSprite*,CCNode*> m_tars;
long m_killemenynum; //杀敌数目
long m_levelscore;//关卡分数
long m_herohurttimes;//主角受伤次数
long m_goldNum;
long m_combomnum;
long m_maxcombom;
long m_perfectnum;
long m_greatenum;
GameScene *m_s;
int hurts[7];
void UpdateLevelData();//更新关卡分数和敌人数目
void PlayEffects();
};
#endif
.cpp文件
#include "Scatter.h"
#include "Scene/GameLayer.h"
#include "Common/GameSound.h"
#include "Common/Defines.h"
#include "Common/Game.h"
#include "Common/EnterStageDataExchange.h"
#include "Modules/Archive.h"
#include "SuckBlood.h"
#include "GameLogic/GameLogic.h"
class FixtureDef {
public:
FixtureDef()
: next(NULL) {}
~FixtureDef() {
delete next;
delete fixture.shape;
}
FixtureDef *next;
b2FixtureDef fixture;
int callbackData;
};
class BodyDef {
public:
BodyDef()
: fixtures(NULL) {}
~BodyDef() {
if (fixtures)
delete fixtures;
}
FixtureDef *fixtures;
CCPoint anchorPoint;
};
static GB2ShapeCache *_sharedGB2ShapeCache = NULL;
GB2ShapeCache* GB2ShapeCache::sharedGB2ShapeCache(void) {
if (!_sharedGB2ShapeCache) {
_sharedGB2ShapeCache = new GB2ShapeCache();
_sharedGB2ShapeCache->init();
}
return _sharedGB2ShapeCache;
}
bool GB2ShapeCache::init() {
return true;
}
void GB2ShapeCache::reset() {
std::map<std::string, BodyDef *>::iterator iter;
for (iter = shapeObjects.begin() ; iter != shapeObjects.end() ; ++iter) {
delete iter->second;
}
shapeObjects.clear();
}
void GB2ShapeCache::addFixturesToBody(b2Body *body, const std::string &shape) {
std::map<std::string, BodyDef *>::iterator pos = shapeObjects.find(shape);
assert(pos != shapeObjects.end());
BodyDef *so = (*pos).second;
FixtureDef *fix = so->fixtures;
while (fix) {
body->CreateFixture(&fix->fixture);
fix = fix->next;
}
}
cocos2d::CCPoint GB2ShapeCache::anchorPointForShape(const std::string &shape) {
std::map<std::string, BodyDef *>::iterator pos = shapeObjects.find(shape);
assert(pos != shapeObjects.end());
BodyDef *bd = (*pos).second;
return bd->anchorPoint;
}
void GB2ShapeCache::addShapesWithFile(const std::string &plist) {
//const char *fullName = CCFileUtils::sharedFileUtils()->fullPathForFilename(plist.c_str()).c_str();
CCDictionary *dict = CCDictionary::createWithContentsOfFile(plist.c_str());
// not triggered - cocos2dx delivers empty dict if non was found
CCAssert(dict != NULL, "Shape-file not found");
CCAssert(dict->count() != 0, "plist file empty or not existing");
CCDictionary *metadataDict = (CCDictionary *)dict->objectForKey("metadata");
int format = static_cast<CCString *>(metadataDict->objectForKey("format"))->intValue();
ptmRatio = static_cast<CCString *>(metadataDict->objectForKey("ptm_ratio"))->floatValue();
CCLOG("ptmRatio = %f",ptmRatio);
CCAssert(format == 1, "Format not supported");
CCDictionary *bodyDict = (CCDictionary *)dict->objectForKey("bodies");
b2Vec2 vertices[b2_maxPolygonVertices];
CCDictElement *dictElem;
std::string bodyName;
CCDictionary *bodyData;
//iterate body list
CCDICT_FOREACH(bodyDict,dictElem )
{
bodyData = (CCDictionary*)dictElem->getObject();
bodyName = dictElem->getStrKey();
BodyDef *bodyDef = new BodyDef();
bodyDef->anchorPoint = CCPointFromString(static_cast<CCString *>(bodyData->objectForKey("anchorpoint"))->getCString());
CCArray *fixtureList = (CCArray*)(bodyData->objectForKey("fixtures"));
FixtureDef **nextFixtureDef = &(bodyDef->fixtures);
//iterate fixture list
CCObject *arrayElem;
CCARRAY_FOREACH(fixtureList, arrayElem)
{
b2FixtureDef basicData;
CCDictionary* fixtureData = (CCDictionary*)arrayElem;
basicData.filter.categoryBits = static_cast<CCString *>(fixtureData->objectForKey("filter_categoryBits"))->intValue();
basicData.filter.maskBits = static_cast<CCString *>(fixtureData->objectForKey("filter_maskBits"))->intValue();
basicData.filter.groupIndex = static_cast<CCString *>(fixtureData->objectForKey("filter_groupIndex"))->intValue();
basicData.friction = static_cast<CCString *>(fixtureData->objectForKey("friction"))->floatValue();
basicData.density = static_cast<CCString *>(fixtureData->objectForKey("density"))->floatValue();
basicData.restitution = static_cast<CCString *>(fixtureData->objectForKey("restitution"))->floatValue();
basicData.isSensor = (bool)static_cast<CCString *>(fixtureData->objectForKey("isSensor"))->intValue();
CCString *cb = static_cast<CCString *>(fixtureData->objectForKey("userdataCbValue"));
int callbackData = 0;
if (cb)
callbackData = cb->intValue();
std::string fixtureType = static_cast<CCString *>(fixtureData->objectForKey("fixture_type"))->m_sString;
if (fixtureType == "POLYGON") {
CCArray *polygonsArray = (CCArray *)(fixtureData->objectForKey("polygons"));
CCObject *dicArrayElem;
CCARRAY_FOREACH(polygonsArray, dicArrayElem)
{
FixtureDef *fix = new FixtureDef();
fix->fixture = basicData; // copy basic data
fix->callbackData = callbackData;
b2PolygonShape *polyshape = new b2PolygonShape();
int vindex = 0;
CCArray *polygonArray = (CCArray*)dicArrayElem;
assert(polygonArray->count() <= b2_maxPolygonVertices);
CCObject *piter;
CCARRAY_FOREACH(polygonArray, piter)
{
CCString *verStr = (CCString*)piter;
CCPoint offset = CCPointFromString(verStr->getCString());
vertices[vindex].x = (offset.x / ptmRatio) ;
vertices[vindex].y = (offset.y / ptmRatio) ;
vindex++;
}
polyshape->Set(vertices, vindex);
fix->fixture.shape = polyshape;
// create a list
*nextFixtureDef = fix;
nextFixtureDef = &(fix->next);
}
}
else if (fixtureType == "CIRCLE") {
FixtureDef *fix = new FixtureDef();
fix->fixture = basicData; // copy basic data
fix->callbackData = callbackData;
CCDictionary *circleData = (CCDictionary *)fixtureData->objectForKey("circle");
b2CircleShape *circleShape = new b2CircleShape();
circleShape->m_radius = static_cast<CCString *>(circleData->objectForKey("radius"))->floatValue() / ptmRatio;
CCPoint p = CCPointFromString(static_cast<CCString *>(circleData->objectForKey("position"))->getCString());
circleShape->m_p = b2Vec2(p.x / ptmRatio, p.y / ptmRatio);
fix->fixture.shape = circleShape;
// create a list
*nextFixtureDef = fix;
nextFixtureDef = &(fix->next);
}
else {
CCAssert(0, "Unknown fixtureType");
}
}
// add the body element to the hash
shapeObjects[bodyName] = bodyDef;
}
}
const char* vertshader="\
attribute vec4 a_position;\
attribute vec2 a_texCoord;\
attribute vec4 a_color;\
varying vec4 v_fragmentColor;\
varying vec2 v_texCoord;\
void main()\
{\
gl_Position = CC_MVPMatrix * a_position;\
v_fragmentColor = a_color;\
v_texCoord = a_texCoord;\
}";
const char* fragshader="\
varying vec4 v_fragmentColor;\
varying vec2 v_texCoord;\
uniform sampler2D CC_Texture0;\
void main()\
{ \
vec4 color=texture2D(CC_Texture0,v_texCoord);\
gl_FragColor =color*v_fragmentColor.a;\
}";
CCGLProgram * SmritiShadow::pg=0;
void SmritiShadow::draw()
{
onDraw();
CCNode::draw();
}
void SmritiShadow::onDraw()
{
struct timeval tv;
gettimeofday(&tv,NULL);
long ct=tv.tv_sec*1000000+tv.tv_usec;
if(ct-pretime>50000)
{
pretime=ct;
arrcount=0;
for(int i=0;i<20;i+=4)
{
Vertices[i].Position[0]=Vertices[i+4].Position[0];
Vertices[i].Position[1]=Vertices[i+4].Position[1];
Vertices[i+1].Position[0]=Vertices[i+5].Position[0];
Vertices[i+1].Position[1]=Vertices[i+5].Position[1];
Vertices[i+2].Position[0]=Vertices[i+6].Position[0];
Vertices[i+2].Position[1]=Vertices[i+6].Position[1];
Vertices[i+3].Position[0]=Vertices[i+7].Position[0];
Vertices[i+3].Position[1]=Vertices[i+7].Position[1];
}
CCSize sz=texture2d->getContentSize();
CCPoint pos=target->getPosition();
CCPoint midp=pos;
CCSize sz1=target->getContentSize();
bool bfx=target->isFlipX();
bool bfy=target->isFlipY();
CCPoint ap=target->getAnchorPoint();
float rad=CC_DEGREES_TO_RADIANS(target->getRotation());
pos.x-=sz1.width*ap.x;
pos.y-=sz1.height*ap.y;
float s=sin(-rad);
float c=cos(-rad);
Vertices[20].Position[0]=c*pos.x-s*pos.y+(1-c)*midp.x+s*midp.y;
Vertices[20].Position[1]=s*pos.x+c*pos.y-s*midp.x+(1-c)*midp.y;
Vertices[21].Position[0]=c*(pos.x+sz.width)-s*pos.y+(1-c)*midp.x+s*midp.y;
Vertices[21].Position[1]=s*(pos.x+sz.width)+c*pos.y-s*midp.x+(1-c)*midp.y;
Vertices[22].Position[0]=c*pos.x-s*(pos.y+sz.height)+(1-c)*midp.x+s*midp.y;
Vertices[22].Position[1]=s*pos.x+c*(pos.y+sz.height)-s*midp.x+(1-c)*midp.y;
Vertices[23].Position[0]=c*(pos.x+sz.width)-s*(pos.y+sz.height)+(1-c)*midp.x+s*midp.y;
Vertices[23].Position[1]=s*(pos.x+sz.width)+c*(pos.y+sz.height)-s*midp.x+(1-c)*midp.y;
float tempx=0,tempy=0;
if(bfx)
{
tempx=Vertices[20].Position[0];
tempy=Vertices[20].Position[1];
Vertices[20].Position[0]=Vertices[21].Position[0];
Vertices[20].Position[1]=Vertices[21].Position[1];
Vertices[21].Position[0]=tempx;
Vertices[21].Position[1]=tempy;
tempx=Vertices[22].Position[0];
tempy=Vertices[22].Position[1];
Vertices[22].Position[0]=Vertices[23].Position[0];
Vertices[22].Position[1]=Vertices[23].Position[1];
Vertices[23].Position[0]=tempx;
Vertices[23].Position[1]=tempy;
}
if(bfy)
{
tempx=Vertices[20].Position[0];
tempy=Vertices[20].Position[1];
Vertices[20].Position[0]=Vertices[22].Position[0];
Vertices[20].Position[1]=Vertices[22].Position[1];
Vertices[22].Position[0]=tempx;
Vertices[22].Position[1]=tempy;
tempx=Vertices[21].Position[0];
tempy=Vertices[21].Position[1];
Vertices[21].Position[0]=Vertices[23].Position[0];
Vertices[21].Position[1]=Vertices[23].Position[1];
Vertices[23].Position[0]=tempx;
Vertices[23].Position[1]=tempy;
}
for(int i=16;i>=0;i-=4)
{
if(Vertices[i].Position[0]==Vertices[20].Position[0])
{
arrcount+=1;
}
}
}
float dst=771,src=1;
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
pg->use();
pg->setUniformsForBuiltins();
GLushort iarr[]={0,1,2,1,2,3,
0+4,1+4,2+4,1+4,2+4,3+4,
0+8,1+8,2+8,1+8,2+8,3+8,
0+12,1+12,2+12,1+12,2+12,3+12,
0+16,1+16,2+16,1+16,2+16,3+16};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*20,Vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iarr),iarr,GL_STATIC_DRAW);
GLint _positionLocation = glGetAttribLocation(pg->getProgram(), "a_position");
GLint _colorLocation = glGetAttribLocation(pg->getProgram(), "a_color");
GLint _textureLocation = glGetAttribLocation(pg->getProgram(), "a_texCoord");
GLint _textureUniform = glGetUniformLocation(pg->getProgram(), "CC_Texture0");
glEnableVertexAttribArray(_positionLocation);
glEnableVertexAttribArray(_colorLocation);
glEnableVertexAttribArray(_textureLocation);
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));
glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));
glVertexAttribPointer(_textureLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid*)offsetof(Vertex, TexCoord));
ccGLBindTexture2DN(0,texture2d->getName());
glUniform1i(_textureUniform, 0);
glDrawElements(GL_TRIANGLES,sizeof(iarr)/sizeof(GLushort)-arrcount*6, GL_UNSIGNED_SHORT, 0);
glDisable(GL_DEPTH_TEST);
glBlendFunc(src, dst);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
SmritiShadow::~SmritiShadow()
{
glDeleteBuffers(1, &vertexBuffer);
glDeleteBuffers(1, &indexBuffer);
delete[] Vertices;
}
void SmritiShadow::setTarget(CCSprite* spr,CCTexture2D* tex)
{
target=spr;
texture2d=tex;
CCSize sz=tex->getContentSize();
CCSize sz1=spr->getContentSize();
CCPoint pos=spr->getPosition();
CCPoint ap=target->getAnchorPoint();
pos.x-=sz1.width*ap.x;
pos.y-=sz1.height*ap.y;
for(int i=0;i<24;i+=4)
{
Vertices[i].Position[0]=pos.x;
Vertices[i].Position[1]=pos.y;
Vertices[i].Position[2]=0;
Vertices[i+1].Position[0]=pos.x+sz.width;
Vertices[i+1].Position[1]=pos.y;
Vertices[i+1].Position[2]=0;
Vertices[i+2].Position[0]=pos.x;
Vertices[i+2].Position[1]=pos.y+sz.height;
Vertices[i+2].Position[2]=0;
Vertices[i+3].Position[0]=pos.x+sz.width;
Vertices[i+3].Position[1]=pos.y+sz.height;
Vertices[i+3].Position[2]=0;
}
}
void SmritiShadow::reset()
{
if(pg)
{
pg->reset();
pg->initWithVertexShaderByteArray(vertshader,fragshader);
pg->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
pg->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
pg->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
pg->link();
pg->updateUniforms();
}
}
bool SmritiShadow::init()
{
struct timeval tv;
gettimeofday(&tv,NULL);
long ct=tv.tv_sec*1000000+tv.tv_usec;
pretime=ct;
arrcount=0;
Vertices=new Vertex[4*6];
for(int i=0;i<24;i+=4)
{
Vertices[i].Color[3]=0.2*(i/4+1);
Vertices[i].TexCoord[0]=0;
Vertices[i].TexCoord[1]=1;
Vertices[i+1].Color[3]=0.2*(i/4+1);
Vertices[i+1].TexCoord[0]=1;
Vertices[i+1].TexCoord[1]=1;
Vertices[i+2].Color[3]=0.2*(i/4+1);
Vertices[i+2].TexCoord[0]=0;
Vertices[i+2].TexCoord[1]=0;
Vertices[i+3].Color[3]=0.2*(i/4+1);
Vertices[i+3].TexCoord[0]=1;
Vertices[i+3].TexCoord[1]=0;
}
glGenBuffers( 1, &vertexBuffer );
glGenBuffers( 1, &indexBuffer );
texture2d=0;
target=0;
if(pg==0)
{
pg=new CCGLProgram();
pg->initWithVertexShaderByteArray(vertshader,fragshader);
pg->link();
pg->updateUniforms();
}
return true;
}
void ContactListener::BeginContact(b2Contact* contact)
{
b2Body* bodyA = contact->GetFixtureA()->GetBody();
b2Body* bodyB = contact->GetFixtureB()->GetBody();
CCSprite* spriteA = (CCSprite*)bodyA->GetUserData();
CCSprite* spriteB = (CCSprite*)bodyB->GetUserData();
if((int)spriteA==1)
{
int tag=spriteB->getTag()-500;
int tag1=spriteB->getTag()-600;
if((tag>=2&&tag<=4)||(tag1>=1&&tag1<=7))
{
std::vector<b2Body*>::iterator iter=std::find(Scatter::gthis->m_bodies.begin(),Scatter::gthis->m_bodies.end(),bodyB);
if(iter==Scatter::gthis->m_bodies.end())
Scatter::gthis->m_bodies.push_back(bodyB);
}
}
if((int)spriteB==1)
{
int tag=spriteA->getTag()-500;
int tag1=spriteA->getTag()-600;
if((tag>=2&&tag<=4)||(tag1>=1&&tag1<=7))
{
std::vector<b2Body*>::iterator iter=std::find(Scatter::gthis->m_bodies.begin(),Scatter::gthis->m_bodies.end(),bodyA);
if(iter==Scatter::gthis->m_bodies.end())
Scatter::gthis->m_bodies.push_back(bodyA);
}
}
}
void ContactListener::EndContact(b2Contact* contact)
{
}
Scatter* Scatter::gthis=0;
void Scatter::draw()
{
CCNode::draw();
onDraw();
}
void Scatter::onDraw()
{
}
void Scatter::addNewSpriteWithCoords(CCPoint p)
{
std::string name;
char sname[32];
int rd=rand()%4+1;
sprintf(sname,"fruit%d",rd);
name=sname;
CCSprite *sprite = CCSprite::create((name+".png").c_str());
p.x+=xoff;
sprite->setPosition(p);
sprite->setTag(500+rd);
addChild(sprite);
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/32.0, p.y/32.0);
bodyDef.userData = sprite;
b2Body *body = m_world->CreateBody(&bodyDef);
GB2ShapeCache *sc = GB2ShapeCache::sharedGB2ShapeCache();
sc->addFixturesToBody(body,sname);
sprite->setAnchorPoint(sc->anchorPointForShape(sname));
b2Vec2 wd=body->GetWorldCenter();
body->SetAngularDamping(1.5);
int dr=1;
dr=p.x<480+xoff?1:-1;
body->ApplyLinearImpulse(b2Vec2(dr*(10*m_level+rand()%10),2+rand()%10),b2Vec2(wd.x-0.1,wd.y+0.2));
}
void Scatter::addBullet(int dr)
{
char sname[32];
int rd=rand()%6+1;
sprintf(sname,"tool%d",rd);
std::string name=sname;
name=name+".png";
CCSprite *sprite = CCSprite::create(name.c_str());
float x=0,px=0;
if(dr==1)
{
x=-140;
px=20*m_level;
sprite->setFlipX(true);
}
else
{
x=1100;
px=-20*m_level;
}
float vh=10+rand()%290;
if(rd==6||rd==7)
{
vh=0;
}
sprite->setTag(600+rd);
CCPoint p=ccp(x,250+vh);
sprite->setPosition(p);
addChild(sprite,1);
SmritiShadow* pp=SmritiShadow::create();
char tname[32];
sprintf(tname,"tool%d_s.png",rd);
pp->setTarget(sprite,CCTextureCache::sharedTextureCache()->textureForKey(tname));
pp->setTag(10);
addChild(pp);
m_tars.insert(std::map<CCSprite*,CCNode*>::value_type(sprite,pp));
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set((p.x+xoff)/32.0, p.y/32.0);
bodyDef.userData = sprite;
b2Body *body = m_world->CreateBody(&bodyDef);
GB2ShapeCache *sc = GB2ShapeCache::sharedGB2ShapeCache();
sc->addFixturesToBody(body,sname);
sprite->setAnchorPoint(sc->anchorPointForShape(sname));
b2Fixture* bf=body->GetFixtureList();
while(bf)
{
bf->SetSensor(true);
bf=bf->GetNext();
}
px*=body->GetMass();
b2Vec2 wd=body->GetWorldCenter();
body->SetGravityScale(0);
body->SetAngularDamping(1.0);
body->ApplyLinearImpulse(b2Vec2(px,-(vh/570.0)*abs(px)),b2Vec2(wd.x-0.2,wd.y+0.2));
}
void Scatter::setdifficulty(float df)
{
m_level=df;
}
void Scatter::actionOver(CCObject* node,void* param)
{
CCNode* snode=(CCNode*)node;
snode->removeFromParentAndCleanup(true);
}
void Scatter::porr()
{
if(ispause==0)
{
unscheduleUpdate();
ispause=1;
}
else
{
scheduleUpdate();
ispause=0;
}
}
void Scatter::setHitct(int ct)
{
m_hitct=ct;
}
void Scatter::attackhandle(b2Body* b)
{
CCSprite* myActor = (CCSprite*)b->GetUserData();
int tag=myActor->getTag();
float ax=myActor->getPositionX();
CCRect rc1=myActor->boundingBox();
CCRect rc2 =hero->boundingBox();
rc2=CCRect(rc2.origin.x-rc2.size.width/3,rc2.origin.y,rc2.size.width*(1.0+2.0/3.0),rc2.size.height);
//int dis=ccpDistance(hero->getPosition(),myActor->getPosition());
if(((attackpoint.x>480&&b->GetLinearVelocity().x<0)||(attackpoint.x<480&&b->GetLinearVelocity().x>0))&&((tag>600))&&rc1.intersectsRect(rc2))
{
status=2;
b->SetGravityScale(5);
b2Vec2 wd=b->GetWorldCenter();
struct timeval now;
gettimeofday(&now, NULL);
srand(now.tv_sec*1000000+now.tv_usec);
b2Vec2 bm=b->GetLinearVelocity();
int dr=1;
if(bm.x>0) dr=-1;
b->ApplyLinearImpulse(b2Vec2(dr*(80+rand()%20),20+rand()%70),b2Vec2(wd.x-0.2,wd.y+0.2));
b2Fixture* bf=b->GetFixtureList();
while(bf)
{
bf->SetSensor(false);
bf=bf->GetNext();
}
tag=tag-600;
if(tag>3)
myActor->setTag(0);
attackdelay=0;
GameSound::getGameSound()->PlaySoundsEffect(sound_hero_hero_hit1);
char effectname[100];
if(EnterStageDataExchange::getInstance()->m_chaID==1)
{
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("export/robot_hurt_effects/gx20.png","export/robot_hurt_effects/gx20.plist","export/robot_hurt_effects/gx2.ExportJson");
sprintf(effectname,"gx2");
}
else if(EnterStageDataExchange::getInstance()->m_chaID==2)
{
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("export/kaka_effects/gx100.png","export/kaka_effects/gx100.plist","export/kaka_effects/gx10.ExportJson");
sprintf(effectname,"gx10");
}
else if(EnterStageDataExchange::getInstance()->m_chaID==3)
{
sprintf(effectname,"gx2");
}
else if(EnterStageDataExchange::getInstance()->m_chaID==4)
{
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("export/bruece_effects/ef070.png","export/bruece_effects/ef070.plist","export/bruece_effects/ef07.ExportJson");
sprintf(effectname,"ef07");
}
// CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("export/robot_hurt_effects/gx20.png","export/robot_hurt_effects/gx20.plist","export/robot_hurt_effects/gx2.ExportJson");
cocos2d::extension::CCArmature *armature = NULL;
armature = cocos2d::extension::CCArmature::create(effectname);
armature->getAnimation()->playByIndex(0);
ccBlendFunc blend1;
blend1.src = GL_ONE; //GL_ONE, GL_DST_ALPHA;GL_ONE_MINUS_DST_ALPHA
blend1.dst = GL_ONE;//GL_ZERO;//GL_ONE_MINUS_SRC_ALPHA;
armature->setBlendFunc(blend1);
armature->setPosition(ccp(hero->getPositionX()+70,hero->getPositionY()+100));
if(EnterStageDataExchange::getInstance()->m_chaID!=4)
{
armature->setScale(2.0);
}
else
{
armature->setScale(1.0);
}
long rate_tag=10;
switch(tag)
{
case 1:
rate_tag=10;
break;
case 2:
rate_tag=10;
break;
case 3:
rate_tag=15;
break;
case 4:
rate_tag=10;
break;
case 5:
rate_tag=10;
break;
case 6:
rate_tag=20;
break;
default:
rate_tag=10;
break;
}
bool Is_addblood=GameLogic::getGameLogic()->GetRandRate(rate_tag);
CCPoint skpos;
SuckBlood* suck=NULL;
if(Is_addblood)
{
suck=SuckBlood::create(this);
skpos=ccp(480+60,hero->getPositionY()+110);
suck->runAction(CCSequence::create(CCDelayTime::create(1),CCRemoveSelf::create(true),0));
long addblood=random_range(5,15);
long curhp=hero->GetHeroHP()+addblood;
if(curhp>m_s->m_hero_HP)
{
curhp=m_s->m_hero_HP;
}
hero->SetHeroHP(curhp);
}
if(attackpoint.x<480)
{
skpos.x=480-60;
if(EnterStageDataExchange::getInstance()->m_chaID!=4)
{
armature->setScale(-2.0);
}
else
{
armature->setScale(-1.0);
}
armature->setRotation(120);
armature->setPosition(ccp(hero->getPositionX()-70,hero->getPositionY()+100));
// armature->setScale(-2.0);
}
this->addChild(armature,25);
if(Is_addblood)
suck->PlaySuck(skpos,ccp(480,230));
armature->getAnimation()->setMovementEventCallFunc(getParent(),movementEvent_selector(GameLayer::CCArmatureEndEventCall));
++m_curhitcount;
++m_combomnum;
UpdateLevelData();//更新关卡数据
if(m_curhitcount>=m_hitct&&isover==0)
{
isover=1;
if(m_wsc)
((m_pSelector->*m_wsc))();
}
}
}
void Scatter::touchhandle(CCPoint curpt)
{
if(isover||ispause||status==1)
return ;
status=1;
attackdelay=0.3;
attackpoint=curpt;
hero->AttackType();
if(curpt.x<480)
{
hero->setFlipX(true);
}
else
hero->setFlipX(false);
}
void Scatter::setOverListener(CCObject* pSelectorTarget,SEL_CallFunc win,SEL_CallFunc fail)
{
m_pSelector=pSelectorTarget;
m_wsc=win;
m_fsc=fail;
}
void Scatter::setoff(float x)
{
xoff+=x;
}
void Scatter::update(float dt)
{
struct timeval now;
gettimeofday(&now, NULL);
long curtime=now.tv_sec*1000000+now.tv_usec;
if(isover==0&&curtime-pretime>700000*(1.0/m_level))
{
if(rand()%2)
{
if(rand()%50>25)
addBullet(1);
}
else
{
if(rand()%50>25)
addBullet(3);
}
pretime=curtime;
}
if(isover==0&&curtime-pretimef>500000*(1.0/m_levelf))
{
if(rand()%3==1)
{
addNewSpriteWithCoords(CCPoint(rand()%200-200,400));
}
else if(rand()%3==2)
{
addNewSpriteWithCoords(CCPoint(rand()%200+960,400));
}
pretimef=curtime;
}
m_world->Step(0.0166670084,8,1);//0.0166670084
mindis=10000;
if(attackdelay>0)
{
attackdelay-=dt;
if(attackdelay<=0)
status=0;
}
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite* myActor = (CCSprite*)b->GetUserData();
if((int)myActor==1) continue;
if(attackdelay>0.1)
{
attackhandle(b);
}
myActor->setPosition( CCPointMake( b->GetPosition().x * 32.0-xoff, b->GetPosition().y * 32.0) );
if(b->GetLinearVelocity().x!=0)
{
float ang=-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) ;
myActor->setRotation(ang);
}
int tag=myActor->getTag();
float ax=myActor->getPositionX();
if((tag>600))
{
float temp=abs(myActor->getPositionX()-480);
if(temp<abs(mindis))
{
mindis=myActor->getPositionX()-480;
}
//float dis=ccpDistance(hero->getPosition(),myActor->getPosition());
CCRect rc=hero->boundingBox();
rc=CCRect(rc.origin.x+rc.size.width*2.0/5.0,rc.origin.y,rc.size.width*(1.0-4.0/5.0),rc.size.height);
CCRect rc1=myActor->boundingBox();
float gscale=b->GetGravityScale();
if(gscale!=5&&rc.intersectsRect(rc1))
{
std::vector<b2Body*>::iterator iter=std::find(Scatter::gthis->m_bodies.begin(),Scatter::gthis->m_bodies.end(),b);
if(iter==Scatter::gthis->m_bodies.end())
{
cocos2d::extension::CCArmature *armature = NULL;
armature = cocos2d::extension::CCArmature::create("djgx");
armature->getAnimation()->playByIndex(0);
ccBlendFunc blend1;
blend1.src = GL_ONE; //GL_ONE, GL_DST_ALPHA;GL_ONE_MINUS_DST_ALPHA
blend1.dst = GL_ONE;//GL_ZERO;//GL_ONE_MINUS_SRC_ALPHA;
armature->setBlendFunc(blend1);
armature->setRotation(-80);
armature->getAnimation()->setMovementEventCallFunc(this,movementEvent_selector(GameLayer::CCArmatureEndEventCall));
this->addChild(armature);
if(b->GetLinearVelocity().x>0)//左边
{
hero->setFlipX(true);
armature->setPosition(ccp(hero->getPositionX()+20,hero->getPositionY()+70));
m_herohurttimes++;//主角受伤次数
}
else if(b->GetLinearVelocity().x<0)//右边
{
hero->setFlipX(false);
armature->setPosition(ccp(hero->getPositionX()+60,hero->getPositionY()+70));
m_herohurttimes++;//主角受伤次数
}
//受击
myActor->setTag(0);
m_bodies.push_back(b);
if(isover==0)
{
if(m_combomnum>m_maxcombom)
{
m_maxcombom=m_combomnum;
}
m_combomnum=0;
int tid=tag-600;
hero->hurtWithDamage(hurts[tid-1],3,3);
float sct=((float)hero->GetHeroHP())/((float)m_s->m_hero_HP);
m_s->_gameLayer->m_st->m_rate=sct;
if(hero->GetHeroHP()<=0)//失败
{
isover=1;
if(m_fsc)
((m_pSelector->*m_fsc))();
}
}
}
}
}
float acty=myActor->getPositionY();
if(b->IsAwake()==false||acty<-100)
{
std::vector<b2Body*>::iterator iter=std::find(Scatter::gthis->m_bodies.begin(),Scatter::gthis->m_bodies.end(),b);
if(iter==Scatter::gthis->m_bodies.end())
m_bodies.push_back(b);
}
}
}
std::vector<b2Body*>::iterator iter=m_bodies.begin();
for(;iter!=m_bodies.end();iter++)
{
CCSprite* myActor = (CCSprite*)(*iter)->GetUserData();
std::map<CCSprite*,CCNode*>::iterator siter=m_tars.find(myActor);
if(siter!=m_tars.end())
{
siter->second->removeFromParentAndCleanup(true);
m_tars.erase(siter);
}
int tag=myActor->getTag()-500;
int tag1=myActor->getTag()-600;
if(((tag>=2&&tag<=4)||(tag1>=1&&tag1<=3)))
{
if((*iter)->GetLinearVelocity().x!=0)
{
char name[32];
if(myActor->getTag()>600)
{
sprintf(name,"tool%d_1.png",tag1);
}
else
sprintf(name,"fruit%d_1.png",tag);
(*iter)->SetGravityScale(0);
(*iter)->SetLinearVelocity(b2Vec2(0,0));
(*iter)->SetAngularVelocity(0);
b2Fixture* bf=(*iter)->GetFixtureList();
while(bf)
{
bf->SetSensor(true);
bf=bf->GetNext();
}
CCTexture2D *tex=CCTextureCache::sharedTextureCache()->textureForKey(name);
CCSize sz=tex->getContentSize();
myActor->setTexture(tex);
myActor->setTextureRect(CCRect(0,0,sz.width,sz.height));
myActor->setRotation(0);
myActor->runAction(CCSequence::create(CCDelayTime::create(3.0),CCCallFuncND::create(this,callfuncND_selector(Scatter::delayremove),0),0));
}
}
else
{
m_world->DestroyBody(*iter);
myActor->removeFromParentAndCleanup(true);
}
}
m_bodies.clear();
}
void Scatter::delayremove(CCNode* node,void* param)
{
node->setTag(0);
//node->removeFromParentAndCleanup(true);
}
Scatter::~Scatter()
{
delete m_world;
delete contactListener;
}
void Scatter::reset()
{
isover=0;
hero->idle();
Hero_Property hero_Property;
long addblood=Game::GetInstance()->GetAddBloodNum();
hero_Property.m_nhero_HP=EnterStageDataExchange::getInstance()->m_hp+addblood; //读取数值表血量
//hero_Property.m_nhero_HP=10; //读取数值表血量
hero->SetHerProperty(hero_Property);
}
bool Scatter::init()
{
m_killemenynum=0;
m_levelscore=0;
m_herohurttimes=0;
m_goldNum=0;
m_maxcombom=m_combomnum=0;
m_perfectnum=0;
m_greatenum=0;
for(int i=0;i<7;++i)
{
hurts[i]=1;
}
gthis=this;
mindis=0;
status=0;
speed=0.5;
m_wsc=0;
attackdelay=0;
m_fsc=0;
m_levelf=m_level=1.0;
m_curhitcount=0;
m_hitct=10;
xoff=0;
isover=0;
ispause=0;
CCTextureCache::sharedTextureCache()->addImage("fruit2_1.png");
CCTextureCache::sharedTextureCache()->addImage("fruit3_1.png");
CCTextureCache::sharedTextureCache()->addImage("fruit4_1.png");
CCTextureCache::sharedTextureCache()->addImage("tool1_1.png");
CCTextureCache::sharedTextureCache()->addImage("tool2_1.png");
CCTextureCache::sharedTextureCache()->addImage("tool3_1.png");
char name[32];
for(int i=0;i<7;++i)
{
sprintf(name,"tool%d_s.png",i+1);
CCTextureCache::sharedTextureCache()->addImage(name);
}
long type=rand()%4;
//角色创建选择
switch(EnterStageDataExchange::getInstance()->m_chaID)
//switch(3)
{
case 1:
hero = Hero4::create(); //苏文
break;
case 2:
hero = Hero3::create(); //卡卡西
break;
case 3:
hero = Hero::create(); //女忍者
break;
case 4:
hero = Hero2::create(); //李小龙
break;
default:
hero = Hero::create();
break;
}
hero->setPosition(CCPoint(480,170));
hero->idle();
long daojuItemNum[10]={0};
for(int i=0;i<=4;i++)
{
daojuItemNum[i+1]=CArchive::GetInstance()->GetHeroNewV11PropertyInfo(i,1);
}
long skill_hp=0;
if(daojuItemNum[2]>=1)//获得30点血量
{
skill_hp=30;
}
Hero_Property hero_Property;
long addblood=Game::GetInstance()->GetAddBloodNum();
hero_Property.m_nhero_HP=EnterStageDataExchange::getInstance()->m_hp+addblood+skill_hp; //读取数值表血量
// hero_Property.m_nhero_HP=10; //读取数值表血量
hero->SetHerProperty(hero_Property);
addChild(hero,10);
struct timeval now;
gettimeofday(&now, NULL);
pretimef=pretime=now.tv_sec*1000000+now.tv_usec;
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
m_world = new b2World(gravity);
contactListener = new ContactListener;
m_world->SetContactListener(contactListener);
m_world->SetAllowSleeping(true);
m_world->SetContinuousPhysics(true);
{
b2BodyDef bd;
b2Body* m_ground = m_world->CreateBody(&bd);
m_ground->SetUserData((void*)1);
b2EdgeShape shape;
shape.Set(b2Vec2(-150000.0f/32.0, 170.0/32.0), b2Vec2((960.0f+150000.0)/32.0, 170.0/32.0));
m_ground->CreateFixture(&shape, 0.0f);
shape.Set(b2Vec2(-150000.0f/32.0,900.0/32.0), b2Vec2((960.0f+150000.0)/32.0, 900.0/32.0));
m_ground->CreateFixture(&shape, 0.0f);
/*
shape.Set(b2Vec2(-15000.0/32.0,0), b2Vec2(-15000.0/32.0, 900.0/32));
m_ground->CreateFixture(&shape, 0.0f);
shape.Set(b2Vec2((960.0+15000.0)/32, 0), b2Vec2((960.0+15000.0)/32, 900.0/32));
m_ground->CreateFixture(&shape, 0.0f);*/
}
scheduleUpdate();
GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithFile("sdefs.plist");
return true;
}
void Scatter::UpdateLevelData()//更新关卡分数和敌人数目
{
m_killemenynum=m_curhitcount;
m_levelscore+=1000;
m_goldNum+=100;
m_combomnum++;
PlayEffects();
}
void Scatter::PlayEffects()
{
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("export/enemy_kill_anim/perfect0.png","export/enemy_kill_anim/perfect0.plist","export/enemy_kill_anim/perfect.ExportJson");
CCSize winsize=CCDirector::sharedDirector()->getWinSize();
if(hero->isFlipX()==false)
{
cocos2d::extension::CCArmature *armature = NULL;
armature = cocos2d::extension::CCArmature::create("perfect");
armature->getAnimation()->playByIndex(0);
long rand1=random_range(1,2);
if(rand1==1)
{
m_perfectnum++;
armature->getAnimation()->play("Animation1");
}
else
{
m_greatenum++;
armature->getAnimation()->play("Animation2");
}
// armature->getAnimation()->play("Animation1");
long rand_posx=random_range(100,120);
long rand_posy=random_range(65,100);
armature->setPosition(ccp(winsize.width/2+rand_posx,winsize.height/2+rand_posy));
addChild(armature,25);
armature->getAnimation()->setMovementEventCallFunc(this,movementEvent_selector(GameLayer::CCArmatureEndEventCall));
}
else if(hero->isFlipX()==true)
{
cocos2d::extension::CCArmature *armature = NULL;
armature = cocos2d::extension::CCArmature::create("perfect");
armature->getAnimation()->playByIndex(0);
long rand1=random_range(1,2);
if(rand1==1)
{
m_perfectnum++;
armature->getAnimation()->play("Animation1");
}
else
{
m_greatenum++;
armature->getAnimation()->play("Animation2");
}
long rand_posx=random_range(100,120);
long rand_posy=random_range(65,100);
armature->setPosition(ccp(winsize.width/2-rand_posx,winsize.height/2+rand_posy));
addChild(armature,25);
armature->getAnimation()->setMovementEventCallFunc(this,movementEvent_selector(GameLayer::CCArmatureEndEventCall));
}
}