Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GameSource/MissileSprite.c
#include "ZAM.h" |
#include "GameAEvents.h" |
#include "MissileSprite.h" |
#include "SpriteFrameRates.h" |
#include "TankSprite.h" |
#include "GameSounds.h" |
#include "ZAMProtos.h" |
spriteLayerPtr MissileLayer; |
spriteLayerPtr RemoteMissileLayer; |
frameSetPtr MissileFrameSetList; |
spritePtr MissileSpriteList[kMaxMissiles]; |
spritePtr RemoteMissileSpriteList[kMaxMissiles]; |
typedef struct { |
short flags; |
fixPt loc; |
fixPt vel; |
} aeMissileInfo; |
OSErr AppendMissilePositions(AppleEvent *ae) |
{ |
OSErr err = 0; |
short index; |
aeMissileInfo missilePosList[kMaxMissiles]; |
for(index = 0; index < kMaxMissiles; index++) { |
if(MissileSpriteList[index]->spriteFlags & kRemoteSpawn) { |
MissileSpriteList[index]->spriteFlags &= ~kRemoteSpawn; |
missilePosList[index].flags = 1; |
} else if( MissileSpriteList[index]->spriteFlags & kRemoteDead ) { |
MissileSpriteList[index]->spriteFlags &= ~kRemoteDead; |
missilePosList[index].flags = 2; |
MissileSpriteList[index]->inUse = false; |
} else if(MissileSpriteList[index]->spriteFlags & kRemoteKilled) { |
MissileSpriteList[index]->spriteFlags &= ~kRemoteKilled; |
missilePosList[index].flags = 3; |
} else { |
missilePosList[index].flags = 0; |
} |
missilePosList[index].loc = MissileSpriteList[index]->loc; |
missilePosList[index].vel = MissileSpriteList[index]->vel; |
} |
if(err == noErr) { |
AEPutParamPtr(ae, keyMissilePos, typefixPtList, |
&missilePosList, sizeof(missilePosList)); |
if(err != noErr) { |
ErrMsgCode("\p Failure: AppendMissilePositions AEPutParamPtr",err); |
} |
} |
return err; |
} |
OSErr ProcessMissilePositions(AppleEvent *ae) |
{ |
OSErr err= 0; |
short index; |
aeMissileInfo missilePosList[kMaxMissiles]; |
long len; |
DescType actualType; |
err = AEGetParamPtr(ae, keyMissilePos, typefixPtList, &actualType, |
&missilePosList, sizeof(missilePosList), &len); |
if(err != noErr) { |
ErrMsgCode("\p Failed: AEMoveRemoteMissile keyDir, typeShortInteger",err); |
} |
if(err == noErr) { |
for(index = 0; index < kMaxMissiles; index++) { |
if(missilePosList[index].flags == 1) { |
FireMissileVelocity(&missilePosList[index].vel, |
missilePosList[index].loc.h, missilePosList[index].loc.v, |
true, index); |
} else if(missilePosList[index].flags == 2) { |
RemoteMissileSpriteList[index]->inUse = false; |
RemoteMissileSpriteList[index]->visible = false; |
RemoteMissileSpriteList[index]->spriteFlags |= kNeedsToBeErased; |
RemoteMissileSpriteList[index]->ownerLayer->layerFlags |= kLayerDirty; |
RemoteMissileSpriteList[index]->inUse = false; |
StartExplosionHere(gGame, missilePosList[index].loc.h, missilePosList[index].loc.v); |
} else if(missilePosList[index].flags == 3) { |
StopAllSounds(); |
SoundDisable(); |
gDead = true; |
gDeadTime = TickCount(); |
} else if(RemoteMissileSpriteList[index]->inUse) { |
RemoteMissileSpriteList[index]->moveTask.taskFlag = true; |
RemoteMissileSpriteList[index]->remoteLoc = missilePosList[index].loc; |
} |
} |
} |
return err; |
} |
void CheckMissileColissions(gamePtr game) |
{ |
if(MissileLayer->activeCount) |
CollideSpriteLayer( MissileLayer, gTankLayer[game->remoteTankIndex]); |
} |
void MissileColissionHandler( spritePtr spr, spritePtr obj, Rect *colArea) |
{ |
if( (RECT_WD(*colArea) >= kCollThresh) && (RECT_HT(*colArea) >= kCollThresh) ) { |
spr->visible = false; |
spr->spriteFlags |= kNeedsToBeErased; |
spr->ownerLayer->layerFlags |= kLayerDirty; |
StartExplosionHere(gGame, spr->loc.h, spr->loc.v); |
SetSpriteFrameCallback(spr,GetNextSpriteFrameIndex(spr),HaltMissileFrameTask); |
spr->spriteFlags |= kRemoteDead; |
} |
} |
Boolean HaltMissileFrameTask(spritePtr spr) |
{ |
SetSpriteFrameCallback(spr,spr->frameList->finfo.frameIndex,nil); |
spr->visible = false; |
spr->ownerLayer->activeCount--; |
return false; |
} |
Boolean MissileMoveFilter(spritePtr spr) |
{ |
Rect junk; |
gamePtr game; |
Boolean result = true; |
game = (gamePtr)spr->refCon; |
spr->data--; |
/* should also check if the sprite has left the screen and then kill it */ |
if(!spr->data ) { |
spr->visible = false; |
spr->spriteFlags |= kNeedsToBeErased | kRemoteDead; |
spr->ownerLayer->layerFlags |= kLayerDirty; |
SetSpriteFrameCallback(spr,GetNextSpriteFrameIndex(spr),HaltMissileFrameTask); |
StartExplosionHere(gGame, spr->loc.h, spr->loc.v); |
spr->spriteFlags |= kRemoteDead; |
result = false; |
} |
return result; |
} |
void LoadMissileSprites(gamePtr game) |
{ |
OSErr err; |
short ref; |
short i,iconID; |
frameSetPtr missileFrameSet; |
short numMissileFrames; |
ref = OpenResFile("\pFireBallFrames.rsrc"); |
if(err = ResError()) { |
ErrMsgCode("\pCould Not Open MissileFrames file!.",err); |
ExitToShell(); |
} |
numMissileFrames = Count1Resources('cicn'); |
if(err == noErr) { |
if(err == noErr) { |
err = CreatePICTIconFrameSet(&MissileFrameSetList, 128, numMissileFrames); |
if(err != noErr) { |
ErrMsgCode("\pCreateColorIconFrameSet failed.",err); |
} |
/* |
Setting the ctseed to the same as the other color tables, |
so that no colors will be mapped. |
*/ |
if(err == noErr) |
SetFrameSetCTSeed(MissileFrameSetList,game->gameCTSeed); |
} |
} |
CloseResFile(ref); |
err = CreateSpriteLayer(&MissileLayer, game->tween,game->backdrop, game->gameWind); |
if(err != noErr) { |
ErrMsgCode("\pCreateSpriteLayer failed.",err); |
ExitToShell(); |
} |
for(i = 0; i < kMaxMissiles; i++) { |
if(err == noErr) { |
err = CreateEmptySprite(MissileLayer, |
&MissileSpriteList[i], /* returned sprite here */ |
kDefaultFrameAdvance, |
kMissileMoveTime, /* time between movement */ |
kMissileFrameTime, /* time between frame change */ |
(long)game); |
if(err != noErr) { |
ErrMsgCode("\pCreateEmptySprite failed.",err); |
} else { |
err = CreateEmptyFrameSet(&MissileSpriteList[i]->frameList,numMissileFrames); |
} |
MissileSpriteList[i]->moveHandler = MissileMoveFilter; |
MissileSpriteList[i]->spriteID = i; |
MissileSpriteList[i]->inUse = false; |
MissileSpriteList[i]->collideHandler = (collisionProc)MissileColissionHandler; |
} |
} |
err = CreateSpriteLayer(&RemoteMissileLayer, game->tween, game->backdrop, game->gameWind); |
if(err != noErr) { |
ErrMsgCode("\pCreateSpriteLayer failed.",err); |
ExitToShell(); |
} |
/* now build remote missiles */ |
for(i = 0; i < kMaxMissiles; i++) { |
if(err == noErr) { |
err = CreateEmptySprite(RemoteMissileLayer, |
&RemoteMissileSpriteList[i], /* returned sprite here */ |
kRemoteSprite | kDefaultFrameAdvance | kRemoteUpdate, |
// kDefaultFrameAdvance , |
kMissileFrameTime, /* time between frame change */ |
kMissileMoveTime, /* time between movement */ |
(long)game); |
if(err != noErr) { |
ErrMsgCode("\pCreateEmptySprite failed.",err); |
} else { |
err = CreateEmptyFrameSet(&RemoteMissileSpriteList[i]->frameList,numMissileFrames); |
} |
RemoteMissileSpriteList[i]->spriteID = i; |
RemoteMissileSpriteList[i]->moveHandler = MissileMoveFilter; |
} |
} |
} |
spritePtr GetMissileSprite(Boolean network) |
{ |
short i; |
for(i = 0; i < kMaxMissiles; i++) |
if(MissileSpriteList[i]->inUse == false) { |
MissileSpriteList[i]->inUse = true; |
MissileSpriteList[i]->ownerLayer->activeCount++; |
return MissileSpriteList[i]; |
} |
return nil; |
} |
void FireMissileVelocity(fixPt *vel, Fixed h, Fixed v, Boolean network, short missileNum) |
{ |
FireMissile(VelocityToDirection(vel),h,v,network,missileNum); |
} |
void FireMissile( short dir, Fixed h, Fixed v, Boolean network, short missileNum) |
{ |
fixPt vel; |
spritePtr missile; |
if(network == false) |
missile = GetMissileSprite(network); |
else { |
missile = RemoteMissileSpriteList[missileNum]; |
missile->ownerLayer->activeCount++; |
missile->inUse = true; |
missile->remoteLoc.h = h; |
missile->remoteLoc.v = v; |
} |
if(missile) { |
(void)PlaySndAsynchChannel( kFireSnd, kShotChan, kStdPriority); |
// |
// taking out because adding kRemoteSpawn bit |
// if(network == false) |
// NetworkFireMissile(gGame, dir, h, v, missile->spriteID); |
if(network == false) |
missile->spriteFlags |= kRemoteSpawn; |
missile->data = kMissileLife; |
if( ((missile->frameTask.timer.qType & TaskActiveFlag) != 0) |
|| ((missile->moveTask.timer.qType & TaskActiveFlag) != 0)) { |
HideSprite(missile); |
StopSpriteAction(missile); |
} |
SetSpriteFrameSet(missile,MissileFrameSetList); |
DirectionToVelocity( dir, &vel); |
vel.h = FixMul(vel.h,ff(12)); |
vel.v = FixMul(vel.v,ff(12)); |
SetSpriteVelocity(missile, vel.h , vel.v); |
SetSpriteLoc(missile, h, v); |
missile->visible = true; |
if(network) { |
StartRemoteSpriteAction(missile); |
} else { |
StartSpriteAction(missile); |
} |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14