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
00027
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
00058
00059
00060
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
00078 bundle->mActions = new CSActions();
00079
00080
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
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
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
00189
00190
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
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
00230
00231
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
00262
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();
00294 return;
00295 }
00296 }
00297 }
00298 mState.mCurrentAction = mState.mCurrentBundle->mDefaultAction;
00299 mState.mCurrentAction->startAction(mState.mActionState);
00300 next();
00301 }
00302 }
00303
00304
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
00320
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
00329
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
00344 void CSSprite::setSpeedY(int speed)
00345 {
00346 static char *functionName="setSpeedY";
00347 mState.mActionState.mAnimation->setSpeedY(speed,mState.mActionState.mAnimationState);
00348 }
00349
00350
00351 void CSSprite::setSpeedX(int speed)
00352 {
00353 static char *functionName="setSpeedX";
00354 mState.mActionState.mAnimation->setSpeedX(speed,mState.mActionState.mAnimationState);
00355 }
00356
00357
00358 void CSSprite::adjustSpeed(int speed)
00359 {
00360 static char *functionName="adjustSpeed";
00361 mState.mActionState.mAnimation->adjustSpeed(speed,mState.mActionState.mAnimationState);
00362 }
00363
00364
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
00385 int myX, myY, myW,myH;
00386 CSPicture *myPicture;
00387
00388
00389 int oX,oY, oW,oH;
00390 CSPicture *oPicture;
00391
00392 myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00393 if (myPicture == 0)
00394 {
00395 return 0;
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;
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;
00415 }
00416 if ((myX > oX) && (myX > oX + oW))
00417 {
00418 return 0;
00419 }
00420 if ((myY < oY) && (myY + myH < oY))
00421 {
00422 return 0;
00423 }
00424 if ((myY > oY) && (myY > oY + oH))
00425 {
00426 return 0;
00427 }
00428
00429 if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00430 {
00431 return 0;
00432 }
00433
00434
00435
00436 unsigned char **myProjection = myPicture->getProjection();
00437 unsigned char **oProjection = oPicture->getProjection();
00438
00439
00440
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
00462
00463
00464
00465
00466
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
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 return count;
00507 }
00508
00509 unsigned int CSSprite::checkCollisionPixels(CSTileMap *map)
00510 {
00511 static char *functionName="checkCollisionPixels";
00512
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;
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
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
00541 int myX, myY, myW,myH;
00542 CSPicture *myPicture;
00543
00544
00545 myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00546 if (myPicture == 0)
00547 {
00548 return 0;
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;
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
00573
00574 unsigned char **myProjection = myPicture->getProjection();
00575 unsigned char **oProjection = oPicture->getProjection();
00576
00577
00578
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
00597
00598
00599
00600
00601
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
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 return count;
00642 }
00643
00644 bool CSSprite::checkCollision(CSSprite *other)
00645 {
00646 static char *functionName="checkCollision";
00647
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;
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
00662 int oX,oY, oW,oH;
00663 CSPicture *oPicture;
00664 oPicture = other->mState.mActionState.mAnimationState.mDisplayPicture;
00665 if (oPicture == 0)
00666 {
00667 return 0;
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;
00677 }
00678 if ((myX > oX) && (myX > oX + oW))
00679 {
00680 return 0;
00681 }
00682 if ((myY < oY) && (myY + myH < oY))
00683 {
00684 return 0;
00685 }
00686 if ((myY > oY) && (myY > oY + oH))
00687 {
00688 return 0;
00689 }
00690
00691 if ((myPicture->getPixelProjectionCount() == 0) || (oPicture->getPixelProjectionCount() == 0))
00692 {
00693 return false;
00694 }
00695
00696
00697
00698 unsigned char **myProjection = myPicture->getProjection();
00699 unsigned char **oProjection = oPicture->getProjection();
00700
00701
00702
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
00737 int myX, myY, myW,myH;
00738 CSPicture *myPicture;
00739 myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00740 if (myPicture == 0)
00741 {
00742 return 0;
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
00764 CSPicture *myPicture;
00765 int myX, myY, myW,myH;
00766
00767 myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00768 if (myPicture == 0)
00769 {
00770 return 0;
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
00778 CSPicture *oPicture;
00779 int oX,oY, oW,oH;
00780 oPicture = tile->getAnimationState()->mPicture;
00781 if (oPicture == 0)
00782 {
00783 return 0;
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
00796
00797 unsigned char **myProjection = myPicture->getProjection();
00798 unsigned char **oProjection = oPicture->getProjection();
00799
00800
00801
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
00836 int myX, myY, myW,myH;
00837 CSPicture *myPicture;
00838 myPicture = mState.mActionState.mAnimationState.mDisplayPicture;
00839 if (myPicture == 0)
00840 {
00841 return 0;
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
00882
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
00893
00894
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
00916
00917
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
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
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