Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSSprite.cpp

Go to the documentation of this file.
00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004 
00005 #include "CSSprite.h"
00006 
00007 #include "SDLMain.h"
00008 #include "CSTileMap.h"
00009 #include "CSXMLHelper.h"
00010 #include "CSNavigator.h"
00011 
00012 CSSpriteLoader CSSpriteLoader::INSTANCE;
00013 const char *CSSprite::CLASS = "CSSprite";
00014 
00015 CSSprite::CSSprite(const std::string &filename)
00016 {
00017     static char *functionName="CSSprite";
00018     LOG_ENTER 
00019     CSSpriteData data;
00020     loadSpriteData(filename, data);
00021     mFilename = filename;
00022     initialize(data);
00023     LOG_EXIT
00024 }
00025 
00026 // not done! TODO
00027 // not listener added as original!
00028 CSSprite::CSSprite(const CSSprite &sprite)
00029 {
00030     static char *functionName="CSSprite";
00031     LOG_ENTER 
00032     initialize();
00033     mId = strdup(sprite.mId);
00034     mFilename = sprite.mFilename;
00035 
00036     LOG_EXIT
00037 }
00038 
00039 void CSSprite::initialize(void)
00040 {
00041     static char *functionName="initialize";
00042     LOG_ENTER 
00043     mActive = false;
00044     mDefaultBundle = 0;
00045     mNavigator = 0;
00046     layer_position = 0;
00047     y_position = 0;
00048     mWidth = 0;
00049     mHeight = 0;
00050     mId = 0;
00051     mType = 0;
00052     mSubtype = 0;
00053     MESSAGE_SPRITE_ACTION_CHANGE.setSubtype(SPRITE_ACTION_CHANGE_MESSAGE);
00054     LOG_EXIT
00055 }
00056 
00057 // data used to initialize sprite
00058 // is not used as itself, everything needed
00059 // is instantiated fresh or copied...
00060 // that meens data can be reused to build another sprite!
00061 void CSSprite::initialize(const CSSpriteData &data)
00062 {
00063     static char *functionName="initialize";
00064     LOG_ENTER 
00065     unsigned int maxX = 0, maxY = 0;
00066     unsigned int x, y;
00067     initialize();
00068 
00069     layer_position = data.layer_position;
00070     y_position = data.y_position;
00071     mDefaultBundle = data.defaultBundle;
00072     for (int i=0; i < data.stateDatas.size(); i++)
00073     {
00074         StateData *stateData = data.stateDatas.at(i);
00075         ActionBundle *bundle = new  ActionBundle();
00076         bundle->stateId = stateData->stateId;
00077         // in this vector all of "my" actions will be stored!
00078         bundle->mActions = new CSActions();
00079 
00080         // create all actions (with ini - filename)
00081         for (StringVector::iterator iter = stateData->actionNames.begin(); iter != stateData->actionNames.end(); iter++)
00082         {
00083             char *help = (char *) *iter; 
00084             if (help == NULL)
00085             {
00086                 LOG_EXIT
00087                 SDLMain::shutdown((std::string)"Char Pointer == 0 Sprite Loading: " + SDL_GetError(), 1);
00088             }
00089             CSAction *action = CSActionLoader::INSTANCE.load((char *)(help));
00090             x = action->getMaxX(); if (maxX < x) maxX =x;
00091             y = action->getMaxY(); if (maxY < y) maxY =y;
00092 
00093             bundle->mActions->push_back(action);
00094         } 
00095         if ((stateData->defaultActionName == NULL) || (strlen(stateData->defaultActionName) == 0))
00096         {
00097             LOG_EXIT
00098             SDLMain::shutdown((std::string)"No default action given! Sprite Loading: " + SDL_GetError(), 1);
00099         }
00100 
00101         // create default action
00102         CSAction *action = CSActionLoader::INSTANCE.load((char *)stateData->defaultActionName);
00103         x = action->getMaxX(); if (maxX < x) maxX =x;
00104         y = action->getMaxY(); if (maxY < y) maxY =y;
00105         bundle->mActions->push_back(action);
00106         // pointer to the default action will allways be available at once!
00107         bundle->mDefaultAction = action;
00108 
00109         actionMap.insert(ActionBundleMap::value_type(bundle->stateId, bundle));
00110     }
00111     
00112     mWidth = maxX;
00113     mHeight = maxY;
00114     mId = strdup(data.id);
00115     mType = data.type;
00116     mSubtype = data.subtype;
00117 
00118     mState = buildState();
00119     LOG_EXIT
00120 }
00121 
00122 CSSprite::~CSSprite()
00123 {
00124     static char *functionName="~CSSprite";
00125     LOG_ENTER 
00126     ActionBundleMap::iterator iter = actionMap.begin();
00127     while (iter != actionMap.end())
00128     {
00129         delete iter->second;
00130         iter++;
00131     }
00132     actionMap.clear();
00133 
00134     if (mId != 0)
00135     {
00136         free(mId);
00137     }
00138     LOG_EXIT
00139 }
00140 
00141 void CSSprite::setSecPerFrame(float secPerFrame)
00142 {
00143     static char *functionName="setSecPerFrame";
00144     LOG_ENTER 
00145     for (ActionBundleMap::iterator iter2 = actionMap.begin(); iter2 !=actionMap.end(); iter2++)
00146     {
00147         for (CSActions::iterator iter = iter2->second->mActions->begin(); iter != iter2->second->mActions->end(); iter++)
00148         {
00149             CSAction *action = *iter;
00150             action->setSecPerFrame(secPerFrame);
00151         }
00152     }
00153     LOG_EXIT
00154 }
00155 
00156 void CSSprite::setAlpha(int alpha)
00157 {
00158     static char *functionName="setAlpha";
00159     LOG_ENTER 
00160     for (ActionBundleMap::iterator iter2 = actionMap.begin(); iter2 !=actionMap.end(); iter2++)
00161     {
00162         for (CSActions::iterator iter = iter2->second->mActions->begin(); iter != iter2->second->mActions->end(); iter++)
00163         {
00164             CSAction *action = *iter;
00165             action->setAlpha(alpha);
00166         }
00167     }
00168     LOG_EXIT
00169 }
00170 
00171 bool CSSprite::changeStateTo(int state)
00172 {
00173     static char *functionName="changeStateTo";
00174     ActionBundleMap::iterator iter = actionMap.find(state);
00175 
00176     if (iter != actionMap.end())
00177     {
00178         mState.mCurrentBundleId = state;
00179         mState.mCurrentBundle = (iter->second);
00180         
00181         for (CSActions::iterator iter = mState.mCurrentBundle->mActions->begin(); iter != mState.mCurrentBundle->mActions->end(); iter++)
00182         {
00183             CSAction *action = *iter;
00184             if (action->getEnvoker() == mState.mCurrentAction->getEnvoker())
00185             {
00186 
00187                 mState.mCurrentAction = action;
00188                 // next display NEXT round
00189                 // since we are in eventHandling now!
00190                 //wrong time to start drawing!
00191                 mState.mCurrentAction->startNextAction(mState.mActionState);
00192                 return true;
00193             }
00194         }
00195         mState.mCurrentAction = mState.mCurrentBundle->mDefaultAction;
00196         mState.mCurrentAction->startNextAction(mState.mActionState);
00197         return true;
00198     }
00199     return false;
00200 }
00201 
00202 
00203 // build an initial state for this sprite, sets variables to defaults
00204 SpriteState CSSprite::buildState()
00205 {
00206     static char *functionName="buildState";
00207     SpriteState state;
00208     state.mCurrentBundleId = mDefaultBundle;
00209 
00210     ActionBundleMap::iterator iter = actionMap.find(state.mCurrentBundleId);
00211     if (iter != actionMap.end())
00212     {
00213         state.mCurrentBundle = (iter->second);
00214         state.mCurrentAction = state.mCurrentBundle->mDefaultAction;
00215     }
00216     else
00217     {
00218         state.mCurrentBundle = 0;
00219         state.mCurrentAction = 0;
00220     }
00221             
00222     if (state.mCurrentAction)
00223     {
00224         state.mActionState = state.mCurrentAction->buildState();
00225     }
00226     return state;
00227 }
00228 
00229 // resets a state to default values
00230 // doesn't  update mDisplayParams! 
00231 // (this position and mDisplayPicture do not change!)
00232 void CSSprite::resetState(SpriteState &state)
00233 {
00234     static char *functionName="resetState";
00235     state.mCurrentBundleId = mDefaultBundle;
00236     ActionBundleMap::iterator iter = actionMap.find(state.mCurrentBundleId);
00237     if (iter != actionMap.end())
00238     {
00239         state.mCurrentBundle = iter->second;
00240         state.mCurrentAction = state.mCurrentBundle->mDefaultAction;
00241     }
00242     else
00243     {
00244         state.mCurrentBundle = 0;
00245         state.mCurrentAction = 0;
00246     }
00247     if (state.mCurrentAction)
00248     {
00249         state.mCurrentAction->resetState(state.mActionState);
00250     }
00251 }
00252 void CSSprite::resetNavigator() 
00253 {
00254     static char *functionName="resetNavigator";
00255     if (mNavigator!=0) 
00256     {
00257         mNavigator->reset();
00258     }
00259 }
00260 
00261 // does not display anything, but prepares (update) for next displaying
00262 // calls right at the beginning navigateor->navigate() if set.
00263 void CSSprite::next()
00264 {
00265     static char *functionName="next";
00266     if (mNavigator != 0)
00267     {
00268         mNavigator->navigate(&(mState.mActionState.mAnimationState.mDisplayParams));
00269     }
00270 
00271     if (!mActive)
00272     {
00273         return;
00274     }
00275 
00276     if (mState.mCurrentAction == 0)
00277     {
00278         return;
00279     }
00280 
00281     if (!mState.mCurrentAction->next(mState.mActionState))
00282     {
00283         sendMessage(MESSAGE_SPRITE_ACTION_CHANGE);
00284         if (mState.mCurrentAction->getDefaultAction() != 0)
00285         {
00286             for (CSActions::iterator iter = mState.mCurrentBundle->mActions->begin(); iter != mState.mCurrentBundle->mActions->end(); iter++)
00287             {
00288                 CSAction *action = *iter;
00289                 if (action->isAction(mState.mCurrentAction->getDefaultAction()))
00290                 {
00291                     mState.mCurrentAction = action;
00292                     mState.mCurrentAction->startAction(mState.mActionState);
00293                     next();// next action invoked at once
00294                     return;
00295                 }
00296             }
00297         }
00298         mState.mCurrentAction = mState.mCurrentBundle->mDefaultAction;
00299         mState.mCurrentAction->startAction(mState.mActionState);
00300         next(); 
00301     }
00302 }
00303 
00304 // display sprite with current display values (changed by next())
00305 void CSSprite::display()
00306 {
00307     static char *functionName="display";
00308     if (!mActive)
00309     {
00310         return;
00311     }
00312     if (mState.mCurrentAction == 0)
00313     {
00314         return;
00315     }
00316     mState.mCurrentAction->display(mState.mActionState);
00317 }
00318 
00319 // where on the screen is 0,0 of our displaying 
00320 // called from CSWorld
00321 void CSSprite::setDisplayOffset(int xOffset, int yOffset)
00322 {
00323     static char *functionName="setDisplayOffset";
00324     mState.mActionState.mAnimationState.mDisplayParams.mXDisplayStart = xOffset;
00325     mState.mActionState.mAnimationState.mDisplayParams.mYDisplayStart = yOffset;
00326 }
00327 
00328 // where in the world will we start drawing the screen
00329 // called from CSWorld
00330 void CSSprite::setWorldPosition(int x, int y)
00331 {
00332     static char *functionName="setWorldPosition";
00333     mState.mActionState.mAnimationState.mDisplayParams.mXWorldStart = x;
00334     mState.mActionState.mAnimationState.mDisplayParams.mYWorldStart = y;
00335 }
00336 
00337 void CSSprite::setNavigator(CSNavigator *navigator)
00338 {
00339     static char *functionName="setNavigator";
00340     mNavigator = navigator;
00341     navigator->setSprite(this);
00342 }
00343 // overrides values in animation
00344 void CSSprite::setSpeedY(int speed)
00345 {
00346     static char *functionName="setSpeedY";
00347     mState.mActionState.mAnimation->setSpeedY(speed,mState.mActionState.mAnimationState);
00348 }
00349 
00350 // overrides values in animation
00351 void CSSprite::setSpeedX(int speed)
00352 {
00353     static char *functionName="setSpeedX";
00354     mState.mActionState.mAnimation->setSpeedX(speed,mState.mActionState.mAnimationState);   
00355 }
00356 
00357 // overrides values in animation
00358 void CSSprite::adjustSpeed(int speed)
00359 {
00360     static char *functionName="adjustSpeed";
00361     mState.mActionState.mAnimation->adjustSpeed(speed,mState.mActionState.mAnimationState);
00362 }
00363 
00364 // returns to speed values of animation (default)
00365 void CSSprite::resetSpeed() 
00366 {
00367     static char *functionName="resetSpeed";
00368     mState.mActionState.mAnimation->resetSpeed(mState.mActionState.mAnimationState);
00369 }
00370 
00371 void CSSprite::setPosition(int x, int y, unsigned int z)
00372 {
00373     static char *functionName="setPosition";
00374     mWorldPos = z;
00375     mState.mActionState.mAnimationState.mDisplayParams.mXPos = x;
00376     mState.mActionState.mAnimationState.mDisplayParams.mYPos = y;
00377     mState.mActionState.mAnimationState.mXPos = x;
00378     mState.mActionState.mAnimationState.mYPos = y;
00379 }
00380 
00381 unsigned int CSSprite::checkCollisionPixels(CSSprite *other)
00382 {
00383     static char *functionName="checkCollisionPixels";
00384     // values of this
00385     int myX, myY, myW,myH;
00386     CSPicture *myPicture;
00387     
00388     // values of other
00389     int oX,oY, oW,oH;
00390     CSPicture *oPicture;
00391 
00392     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00393     if (myPicture == 0) 
00394     {
00395         return 0; // sprite was never displayed!
00396     }
00397     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00398     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00399     myW = myPicture->getMaxX();
00400     myH = myPicture->getMaxY();
00401 
00402     oPicture = other->mState.mActionState.mAnimationState.mDisplayPicture;
00403     if (oPicture == 0) 
00404     {
00405         return 0; // sprite was never displayed!
00406     }
00407     oX = other->mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00408     oY = other->mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00409     oW = oPicture->getMaxX();
00410     oH = oPicture->getMaxY();
00411 
00412     if ((myX < oX) && (myX + myW < oX)) 
00413     {
00414         return 0;   // i am x smaller
00415     }
00416     if ((myX > oX) && (myX > oX + oW)) 
00417     {
00418         return 0;   // i am x greater
00419     }
00420     if ((myY < oY) && (myY + myH < oY)) 
00421     {
00422         return 0;   // i am y smaller
00423     }
00424     if ((myY > oY) && (myY > oY + oH)) 
00425     {
00426         return 0;   // i am y greater
00427     }
00428 
00429     if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00430     {
00431         return 0;
00432     }
00433 
00434     // sprites overlap in some way - now count the pixels
00435     // use pixel projection of current displayPicture(s)
00436     unsigned char **myProjection = myPicture->getProjection();
00437     unsigned char **oProjection = oPicture->getProjection();
00438 
00439     // now get the "rectangle" where the to sprites overlap
00440     // nad check only there!
00441     int xStart, xEnd;
00442     int yStart, yEnd;
00443     int offsetOx;
00444     int offsetOy;
00445     unsigned int count = 0;
00446     if (myX < oX) xStart = oX-myX;
00447     else xStart = 0;
00448     if (myX+myW > oX+oW) xEnd = myW - ((myX+myW) - (oX+oW));
00449     else xEnd = myW;
00450 
00451     if (myY < oY) yStart = oY-myY;
00452     else yStart = 0;
00453     if (myY+myH > oY+oH) yEnd = myH - ((myY+myH) - (oY+oH));
00454     else yEnd = myH;
00455 
00456     offsetOx = myX-oX;
00457     offsetOy = myY-oY;
00458 
00459 
00460     /*
00461     printf("\nyStart: %i", yStart);
00462     printf("\nxStart: %i", xStart);
00463     printf("\nyEnd: %i", yEnd);
00464     printf("\nxEnd: %i", xEnd);
00465     printf("\noffsetOy: %i", offsetOy);
00466     printf("\noffsetOx: %i", offsetOx);
00467     */
00468 
00469     for (int y = yStart; y < yEnd; y++)
00470     {
00471         for (int x = xStart; x < xEnd; x++)
00472         {
00473             if ((myProjection[y][x] == 1) && (oProjection[y+offsetOy][x+offsetOx] == 1))
00474             {
00475                 count++;
00476             }
00477         }
00478     }
00479 /*
00480     printf("\n");
00481     for (y = yStart; y < yEnd; y++)
00482     {
00483         for (int x = xStart; x < xEnd; x++)
00484         {
00485             if (myProjection[y][x] == 1) 
00486                 printf("1");
00487             else
00488                 printf("0");
00489         }
00490         printf("\n");
00491     }
00492 
00493     printf("\n");
00494     for (y = yStart; y < yEnd; y++)
00495     {
00496         for (int x = xStart; x < xEnd; x++)
00497         {
00498             if (oProjection[y+offsetOy][x+offsetOx] == 1) 
00499                 printf("1");
00500             else
00501                 printf("0");
00502         }
00503         printf("\n");
00504     }
00505 */
00506     return count;
00507 }
00508 
00509 unsigned int CSSprite::checkCollisionPixels(CSTileMap *map)
00510 {
00511     static char *functionName="checkCollisionPixels";
00512     // first get a list of all tiles, that are touched by the sprite
00513     int count = 0;
00514     int myX, myY, myW,myH;
00515     CSPicture *myPicture;
00516     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00517     if (myPicture == 0) 
00518     {
00519         return 0; // sprite was never displayed!
00520     }
00521     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00522     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00523     myW = myPicture->getMaxX();
00524     myH = myPicture->getMaxY();
00525 
00526     CSTiles tiles = map->getTouchingTiles(myX,myY,myW,myH);
00527     for (CSTiles::iterator iter = tiles.begin(); iter != tiles.end(); iter++)
00528     {
00529     // than check them one by one
00530         count += checkCollisionPixels(*iter);
00531     }
00532     return count;
00533 }
00534 
00535 unsigned int CSSprite::checkCollisionPixels(CSTile *tile)
00536 {
00537     static char *functionName="checkCollisionPixels";
00538     unsigned int count = 0;
00539 
00540     // values of this
00541     int myX, myY, myW,myH;
00542     CSPicture *myPicture;
00543     
00544     // values of tile
00545     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00546     if (myPicture == 0) 
00547     {
00548         return 0; // sprite was never displayed!
00549     }
00550     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00551     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00552     myW = myPicture->getMaxX();
00553     myH = myPicture->getMaxY();
00554 
00555     int oX,oY, oW,oH;
00556     CSPicture *oPicture;
00557     oPicture = tile->getAnimationState()->mPicture;
00558     if (oPicture == 0) 
00559     {
00560         return 0; // sprite was never displayed!
00561     }
00562     oY = tile->getY();
00563     oH = tile->getHeight();
00564     oX = tile->getX();
00565     oW = tile->getWitdh();
00566 
00567     if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00568     {
00569         return 0;
00570     }
00571 
00572     // pictures overlap in some way - now count the pixels
00573     // use pixel projection of current displayPicture(s)
00574     unsigned char **myProjection = myPicture->getProjection();
00575     unsigned char **oProjection = oPicture->getProjection();
00576 
00577     // now get the "rectangle" where the to pictures overlap
00578     // and check only there!
00579     int xStart, xEnd;
00580     int yStart, yEnd;
00581     int offsetOx;
00582     int offsetOy;
00583     if (myX < oX) xStart = oX-myX;
00584     else xStart = 0;
00585     if (myX+myW > oX+oW) xEnd = myW - ((myX+myW) - (oX+oW));
00586     else xEnd = myW;
00587 
00588     if (myY < oY) yStart = oY-myY;
00589     else yStart = 0;
00590     if (myY+myH > oY+oH) yEnd = myH - ((myY+myH) - (oY+oH));
00591     else yEnd = myH;
00592 
00593     offsetOx = myX-oX;
00594     offsetOy = myY-oY;
00595     /*
00596     printf("\nyStart: %i", yStart);
00597     printf("\nxStart: %i", xStart);
00598     printf("\nyEnd: %i", yEnd);
00599     printf("\nxEnd: %i", xEnd);
00600     printf("\noffsetOy: %i", offsetOy);
00601     printf("\noffsetOx: %i", offsetOx);
00602     */
00603 
00604     for (int y = yStart; y < yEnd; y++)
00605     {
00606         for (int x = xStart; x < xEnd; x++)
00607         {
00608             if ((myProjection[y][x] == 1) && (oProjection[y+offsetOy][x+offsetOx] == 1))
00609             {
00610                 count++;
00611             }
00612         }
00613     }
00614 /*
00615     printf("\n");
00616     for (y = yStart; y < yEnd; y++)
00617     {
00618         for (int x = xStart; x < xEnd; x++)
00619         {
00620             if (myProjection[y][x] == 1) 
00621                 printf("1");
00622             else
00623                 printf("0");
00624         }
00625         printf("\n");
00626     }
00627 
00628     printf("\n");
00629     for (y = yStart; y < yEnd; y++)
00630     {
00631         for (int x = xStart; x < xEnd; x++)
00632         {
00633             if (oProjection[y+offsetOy][x+offsetOx] == 1) 
00634                 printf("1");
00635             else
00636                 printf("0");
00637         }
00638         printf("\n");
00639     }
00640 */ 
00641     return count;
00642 }
00643 
00644 bool CSSprite::checkCollision(CSSprite *other)
00645 {
00646     static char *functionName="checkCollision";
00647     // values of this
00648     int myX, myY, myW,myH;
00649     CSPicture *myPicture;
00650 
00651     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00652     if (myPicture == 0) return 0; 
00653     {
00654         return 0; // sprite was never displayed!
00655     }
00656     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00657     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00658     myW = myPicture->getMaxX();
00659     myH = myPicture->getMaxY();
00660 
00661     // values of other
00662     int oX,oY, oW,oH;
00663     CSPicture *oPicture;
00664     oPicture = other->mState.mActionState.mAnimationState.mDisplayPicture;
00665     if (oPicture == 0) 
00666     {
00667         return 0; // sprite was never displayed!
00668     }
00669     oX = other->mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00670     oY = other->mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00671     oW = oPicture->getMaxX();
00672     oH = oPicture->getMaxY();
00673 
00674     if ((myX < oX) && (myX + myW < oX)) 
00675     {
00676         return 0;   // i am x smaller
00677     }
00678     if ((myX > oX) && (myX > oX + oW)) 
00679     {
00680         return 0;   // i am x greater
00681     }
00682     if ((myY < oY) && (myY + myH < oY)) 
00683     {
00684         return 0;   // i am y smaller
00685     }
00686     if ((myY > oY) && (myY > oY + oH)) 
00687     {
00688         return 0;   // i am y greater
00689     }
00690 
00691     if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00692     {
00693         return false;
00694     }
00695 
00696     // sprites overlap in some way - check if collide
00697     // use pixel projection of current displayPicture(s)
00698     unsigned char **myProjection = myPicture->getProjection();
00699     unsigned char **oProjection = oPicture->getProjection();
00700 
00701     // now get the "rectangle" where the to sprites overlap
00702     // and check only there!
00703     int xStart, xEnd;
00704     int yStart, yEnd;
00705     int offsetOx;
00706     int offsetOy;
00707     if (myX < oX) xStart = oX-myX;
00708     else xStart = 0;
00709     if (myX+myW > oX+oW) xEnd = myW - ((myX+myW) - (oX+oW));
00710     else xEnd = myW;
00711 
00712     if (myY < oY) yStart = oY-myY;
00713     else yStart = 0;
00714     if (myY+myH > oY+oH) yEnd = myH - ((myY+myH) - (oY+oH));
00715     else yEnd = myH;
00716 
00717     offsetOx = myX-oX;
00718     offsetOy = myY-oY;
00719 
00720     for (int y = yStart; y < yEnd; y++)
00721     {
00722         for (int x = xStart; x < xEnd; x++)
00723         {
00724             if ((myProjection[y][x] == 1) && (oProjection[y+offsetOy][x+offsetOx] == 1))
00725             {
00726                 return true;
00727             }
00728         }
00729     }
00730     return false;
00731 }
00732 
00733 bool CSSprite::checkCollision(CSTileMap *map)
00734 {
00735     static char *functionName="checkCollision";
00736     // first get a list of all tiles, that are touched by the sprite
00737     int myX, myY, myW,myH;
00738     CSPicture *myPicture;
00739     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00740     if (myPicture == 0) 
00741     {
00742         return 0; // sprite was never displayed!
00743     }
00744     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00745     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00746     myW = myPicture->getMaxX();
00747     myH = myPicture->getMaxY();
00748 
00749     CSTiles tiles = map->getTouchingTiles(myX,myY,myW,myH);
00750     for (CSTiles::iterator iter = tiles.begin(); iter != tiles.end(); iter++)
00751     {
00752         if (checkCollision(*iter))
00753         {
00754             return true;
00755         }
00756     }
00757     return false;
00758 }
00759 
00760 bool CSSprite::checkCollision(CSTile *tile)
00761 {
00762     static char *functionName="checkCollision";
00763     // values of this
00764     CSPicture *myPicture;
00765     int myX, myY, myW,myH;
00766     
00767     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00768     if (myPicture == 0) 
00769     {
00770         return 0; // sprite was never displayed!
00771     }
00772     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00773     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00774     myW = myPicture->getMaxX();
00775     myH = myPicture->getMaxY();
00776 
00777     // values of tile
00778     CSPicture *oPicture;
00779     int oX,oY, oW,oH;
00780     oPicture = tile->getAnimationState()->mPicture;
00781     if (oPicture == 0) 
00782     {
00783         return 0; // sprite was never displayed!
00784     }
00785     oY = tile->getY();
00786     oH = tile->getHeight();
00787     oX = tile->getX();
00788     oW = tile->getWitdh();
00789 
00790     if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00791     {
00792         return false;
00793     }
00794 
00795     // sprites overlap in some way - check if collide
00796     // use pixel projection of current displayPicture(s)
00797     unsigned char **myProjection = myPicture->getProjection();
00798     unsigned char **oProjection = oPicture->getProjection();
00799 
00800     // now get the "rectangle" where the to sprites overlap
00801     // and check only there!
00802     int xStart, xEnd;
00803     int yStart, yEnd;
00804     int offsetOx;
00805     int offsetOy;
00806     if (myX < oX) xStart = oX-myX;
00807     else xStart = 0;
00808     if (myX+myW > oX+oW) xEnd = myW - ((myX+myW) - (oX+oW));
00809     else xEnd = myW;
00810 
00811     if (myY < oY) yStart = oY-myY;
00812     else yStart = 0;
00813     if (myY+myH > oY+oH) yEnd = myH - ((myY+myH) - (oY+oH));
00814     else yEnd = myH;
00815 
00816     offsetOx = myX-oX;
00817     offsetOy = myY-oY;
00818 
00819     for (int y = yStart; y < yEnd; y++)
00820     {
00821         for (int x = xStart; x < xEnd; x++)
00822         {
00823             if ((myProjection[y][x] == 1) && (oProjection[y+offsetOy][x+offsetOx] == 1))
00824             {
00825                 return true;
00826             }
00827         }
00828     }
00829     return false;
00830 }
00831 
00832 CSTiles CSSprite::getCollidingTiles(CSTileMap *map)
00833 {
00834     static char *functionName="getCollidingTiles";
00835     // first get a list of all tiles, that are touched by the sprite
00836     int myX, myY, myW,myH;
00837     CSPicture *myPicture;
00838     myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00839     if (myPicture == 0) 
00840     {
00841         return 0; // sprite was never displayed!
00842     }
00843     myX = mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00844     myY = mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00845     myW = myPicture->getMaxX();
00846     myH = myPicture->getMaxY();
00847 
00848     CSTiles tiles = map->getTouchingTiles(myX,myY,myW,myH);
00849     CSTiles::iterator iter = tiles.begin();
00850     while (iter != tiles.end())
00851     {
00852         if (!checkCollision(*iter))
00853         {
00854             iter = tiles.erase(iter);
00855         }
00856         else
00857         {
00858             iter++;
00859         }
00860     }
00861     return tiles;
00862 }
00863         
00864 void CSSprite::reactOnMessage(CSMessage *message)
00865 {
00866     static char *functionName="reactOnMessage";
00867     switch (message->getType())
00868     {
00869         case SPRITE_MESSAGE:
00870         {
00871             if (message->getSubtype() == SPRITE_STATE_CHANGE_MESSAGE)
00872             {
00873                 SpriteMessage *sMessage = (SpriteMessage *) message;
00874                 sMessage->setSuccess(changeStateTo(sMessage->state));
00875             }
00876 
00877             break;
00878         }
00879         case ACTION_MESSAGE:
00880         {
00881             // look for an action that
00882             // has as its envoker the subtype of the message!
00883             if (message->getSubtype() == DEFAULT_MESSAGE)
00884             {
00885                 if (mState.mCurrentAction->getDefaultAction() != 0)
00886                 {
00887                     for (CSActions::iterator iter = mState.mCurrentBundle->mActions->begin(); iter != mState.mCurrentBundle->mActions->end(); iter++)
00888                     {
00889                         CSAction *action = *iter;
00890                         if (action->isAction(mState.mCurrentAction->getDefaultAction()))
00891                         {
00892                             // next display NEXT round
00893                             // since we are in eventHandling now!
00894                             // wrong time to start drawing!
00895                             mState.mCurrentAction = action;
00896                             mState.mCurrentAction->startNextAction(mState.mActionState);
00897                             return;
00898                         }
00899                     }
00900                 }
00901                 return;
00902             }
00903             if (mState.mCurrentAction->isBreakable(mState.mActionState))
00904             {
00905                 for (CSActions::iterator iter = mState.mCurrentBundle->mActions->begin(); iter != mState.mCurrentBundle->mActions->end(); iter++)
00906                 {
00907                     CSAction *action = *iter;
00908                     if (action->getEnvoker() == message->getSubtype())
00909                     {
00910                         if (action->isAction(mState.mCurrentAction->getId()))
00911                         {
00912                             return;
00913                         }
00914                         mState.mCurrentAction = action;
00915                         // next display NEXT round
00916                         // since we are in eventHandling now!
00917                         //wrong time to start drawing!
00918                         mState.mCurrentAction->startNextAction(mState.mActionState);
00919                         return;
00920                     }
00921                 }
00922             }
00923         }
00924     }
00925 }
00926 
00927 void CSSprite::loadSpriteData(const std::string &filename, CSSpriteData &data)
00928 {
00929     static char *functionName="loadSpriteData";
00930     LOG_ENTER 
00931     char tmp[10];
00932     char tmp2[10];
00933     int i=-1,j=-1;
00934     
00935     CSXMLHelper xmlSupport(filename, "SPRITE");
00936     try
00937     {
00938         if (xmlSupport.getError())
00939         {
00940             LOG_EXIT
00941             throw "error";
00942         }
00943 
00944         data.id = strdup(xmlSupport.getString("ID").c_str());
00945         data.defaultBundle = xmlSupport.getInt("/SPRITE/DEFAULT_STATE");
00946         data.layer_position = xmlSupport.getInt("/SPRITE/LAYER_POSITION");
00947         data.y_position = xmlSupport.getInt("/SPRITE/Y_POSITION");
00948 
00949         data.type = xmlSupport.getInt("/SPRITE/TYPE");
00950         data.subtype = xmlSupport.getInt("/SPRITE/SUBTYPE");
00951         
00952     
00953         int stateCount = xmlSupport.getInt("count(/SPRITE/STATE)");
00954         for (i=0; i<stateCount; i++)
00955         {
00956             StateData *stateData = new StateData();
00957             // i+1, predicates in xpath start with 1
00958             itoa(i+1,tmp,10);
00959             stateData->stateId = xmlSupport.getInt((std::string)"/SPRITE/STATE["+tmp+"]/STATE_ID");
00960             stateData->defaultActionName = strdup(xmlSupport.getString((std::string)"/SPRITE/STATE["+tmp+"]/DEFAULT_ACTION").c_str());
00961 
00962             int actionCount = xmlSupport.getInt((std::string)"count(/SPRITE/STATE["+tmp+"]/ACTION)");
00963 
00964             for (j=0; j<actionCount; j++)
00965             {
00966                 // j+1, predicates in xpath start with 1
00967                 itoa(j+1,tmp2,10);
00968                 std::string t = (std::string)"/SPRITE/STATE["+tmp+"]/ACTION["+tmp2+"]";
00969                 std::string a = xmlSupport.getString(t);
00970                 stateData->actionNames.push_back(strdup(a.c_str()));
00971             }
00972 
00973             data.stateDatas.push_back(stateData);
00974         }
00975     }
00976     catch(...)
00977     {
00978         char tmp3[100];
00979         sprintf(tmp3,"i=%i, j=%i",i,j);
00980         
00981         LOG_EXIT
00982         SDLMain::shutdown((std::string)"XML error \"" + filename + "\": "+tmp3 + xmlSupport.getErrorMessage().c_str(), 1);
00983     }
00984     LOG_EXIT
00985 }
00986 

Generated on Wed Jul 14 00:43:42 2004 for CSLib by doxygen 1.3.6