// $Revision: 1.16 $ //------------------------------------------------------------------------------ // // Copyright (C) 1994 Taligent, Inc. All rights reserved. // // Project: ConcurrentActors // File: GameSubsystem.h // Build/Version: 1.0.0 // // Description: The Game subsystem defines the characteristics of an // asteroid-shooting game: The actors, asteroids, bullets, and // a space ship are game-specific derivations of the Universe // subsystem's TAbstractActor. Derived classes of the Collision // subsystem's TCollisionBehavior allow for custom interactions // (exploding and bouncing off the boundaries of the simulation // space). TSimulationLevel creates the universe, populates it // with actors, and tells it to initiate the program's threads. // TSimulationLevel also has ongoing roles in updating the // view with refresh information and channeling keypresses // from the view to actors. // //------------------------------------------------------------------------------ #ifndef TaligentSamples_GAMESUBSYSTEM #define TaligentSamples_GAMESUBSYSTEM class TExplodingActor; class TAsteroid; class TSmallAsteroid; class TMediumAsteroid; class TLargeAsteroid; class TBullet; class TShip; class TBoundingBoxBehavior; class TExplosionBehavior; class TSimulationRefreshNotification; class TSimulationLevel; class TGrafPort; //The TGrafPort class can be found in GrafPort.h. class MGraphic; //The MGraphic class can be found in Graphics.h. class TImage; //The TImage class can be found in GraphicImage.h. class TModifiableImage; //The TModifiableImage class can be found in GraphicImage.h. #ifndef Taligent_COREPRIMITIVECLASSES #include #endif #ifndef Taligent_CLOCK #include #endif #ifndef Taligent_BASEGEOMETRY #include #endif #ifndef Taligent_KEYBOARDINPUT #include #endif #ifndef Taligent_COLLECTIONS #include #endif #ifndef Taligent_NOTIFICATION #include #endif #ifndef TaligentSamples_COLLISIONSUBSYSTEM #include "CollisionSubsystem.h" #endif #ifndef TaligentSamples_UNIVERSESUBSYSTEM #include "UniverseSubsystem.h" #endif //============================================================================== // TSimulationBackground class TSimulationBackground : public MRefreshable { public: TaligentTypeExtensionDeclarationsMacro(TSimulationBackground) public: TSimulationBackground(); TSimulationBackground(const TSimulationBackground& source); virtual ~TSimulationBackground(); TSimulationBackground& operator=(const TSimulationBackground& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual void Draw(TGrafPort& port) const; virtual TGRect GetBounds() const; protected: virtual const MGraphic& GetGraphic() const; private: enum {kOriginalVersion}; }; //============================================================================== // TExplodingActor class TExplodingActor : public TAbstractActor { public: TaligentTypeExtensionDeclarationsMacro_Abstract(TExplodingActor) public: TExplodingActor(); TExplodingActor(const TGPoint& initialPosition, const TGPoint& velocity = TGPoint::kOrigin); TExplodingActor(const TExplodingActor& source); virtual ~TExplodingActor(); TExplodingActor& operator=(const TExplodingActor& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Move(const TTime& interval); virtual void Draw(TGrafPort& port) const; TGPoint GetPosition() const; virtual void SetPosition(const TGPoint& newPosition); TGPoint GetVelocity() const; virtual void SetVelocity(const TGPoint& newVelocity); virtual TGRect GetBounds() const; virtual void Explode() = 0; protected: virtual const MGraphic& GetGraphic() const = 0; private: enum {kOriginalVersion}; TGPoint fPosition; TGPoint fVelocity; }; //============================================================================== // TAsteroid class TAsteroid : public TExplodingActor { public: TaligentTypeExtensionDeclarationsMacro_Abstract(TAsteroid) public: TAsteroid(const TGPoint& initialPosition, const GCoordinate& speed); TAsteroid(const TAsteroid& source); virtual ~TAsteroid(); TAsteroid& operator=(const TAsteroid& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; protected: TAsteroid(); private: TGPoint CalcRandomDirection(const GCoordinate& length) const; enum {kOriginalVersion}; }; //============================================================================== // TSmallAsteroid class TSmallAsteroid : public TAsteroid { public: TaligentTypeExtensionDeclarationsMacro(TSmallAsteroid) public: static const GCoordinate& kDefaultSpeed; TSmallAsteroid(const TGPoint& initialPosition, const GCoordinate& speed = kDefaultSpeed); TSmallAsteroid(const TSmallAsteroid& source); virtual ~TSmallAsteroid(); TSmallAsteroid& operator=(const TSmallAsteroid& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Explode(); protected: TSmallAsteroid(); virtual const MGraphic& GetGraphic() const; private: enum {kOriginalVersion}; }; //============================================================================== // TMediumAsteroid class TMediumAsteroid : public TAsteroid { public: TaligentTypeExtensionDeclarationsMacro(TMediumAsteroid) public: static const GCoordinate& kDefaultSpeed; TMediumAsteroid(const TGPoint& initialPosition, const GCoordinate& speed = kDefaultSpeed); TMediumAsteroid(const TMediumAsteroid& source); virtual ~TMediumAsteroid(); TMediumAsteroid& operator=(const TMediumAsteroid& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Explode(); protected: TMediumAsteroid(); virtual const MGraphic& GetGraphic() const; virtual long GetDefaultDivision() const; private: enum {kOriginalVersion}; }; //============================================================================== // TLargeAsteroid class TLargeAsteroid : public TAsteroid { public: TaligentTypeExtensionDeclarationsMacro(TLargeAsteroid) public: static const GCoordinate& kDefaultSpeed; TLargeAsteroid(const TGPoint& initialPosition, const GCoordinate& speed = kDefaultSpeed); TLargeAsteroid(const TLargeAsteroid& source); virtual ~TLargeAsteroid(); TLargeAsteroid& operator=(const TLargeAsteroid& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Explode(); protected: TLargeAsteroid(); virtual const MGraphic& GetGraphic() const; virtual long GetDefaultDivision() const; private: enum {kOriginalVersion}; }; //============================================================================== // TBullet class TBullet : public TExplodingActor { public: TaligentTypeExtensionDeclarationsMacro(TBullet) public: static const TTime& kDefaultLifeSpan; TBullet(); TBullet( const TGPoint& initialPosition, const TGPoint& velocity, const TTime& lifeSpan = kDefaultLifeSpan); TBullet(const TBullet& source); virtual ~TBullet(); TBullet& operator=(const TBullet& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Move(const TTime& interval); protected: virtual void Explode(); virtual const MGraphic& GetGraphic() const; private: enum {kOriginalVersion}; TSeconds fLifeSpan; }; //============================================================================== // TShip class TShip : public TExplodingActor { public: TaligentTypeExtensionDeclarationsMacro(TShip) public: TShip(const TGPoint& initialPosition, UniChar thrust, UniChar fire, UniChar left, UniChar right); TShip(const TShip& source); virtual ~TShip(); TShip& operator=(const TShip& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual bool IsA(const TType& type) const; virtual void Draw(TGrafPort& port) const; virtual void PreMove(const TTime& interval); virtual TGRect GetBounds() const; virtual void Explode(); virtual UniChar GetThrustChar() const; virtual UniChar GetFireChar() const; virtual UniChar GetLeftChar() const; virtual UniChar GetRightChar() const; virtual void Fire(); virtual void ThrustBegin(); virtual void ThrustEnd(); enum ERotation {kCounterClockWise = -1, kNoRotation, kClockWise}; virtual void RotateBegin(TShip::ERotation direction); virtual void RotateEnd(); protected: TShip(); virtual const MGraphic& GetGraphic() const; virtual void HandleBulletDied(const TNotification& note); private: static const unsigned long GetDefaultMaxBullets(); static const GCoordinate& GetDefaultMaxThrust(); static const GCoordinate& GetDefaultAcceleration(); static const GCoordinate& GetDefaultRotationSpeed(); enum {kOriginalVersion}; GDegrees fRotation; UniChar fThrust; UniChar fFire; UniChar fLeft; UniChar fRight; TStopwatch fRotationWatch; short fRotationDirection; TStopwatch fThrustWatch; unsigned long fBulletsAvailable; TMemberFunctionConnectionTo fBulletConnection; }; //============================================================================== // TBoundingBoxBehavior class TBoundingBoxBehavior : public TCollisionBehavior { public: TaligentTypeExtensionDeclarationsMacro(TBoundingBoxBehavior) public: TBoundingBoxBehavior(); TBoundingBoxBehavior(const TGRect& bounds); TBoundingBoxBehavior(const TBoundingBoxBehavior& source); virtual ~TBoundingBoxBehavior(); TBoundingBoxBehavior& operator=(const TBoundingBoxBehavior& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual TGRect GetBounds() const; virtual void SetBounds(const TGRect& bounds); virtual void ConnectTo(MColliding* colliding); virtual void DisconnectFrom(MColliding& colliding); private: virtual void HandleCollisionPossible(const TNotification& note); enum {kOriginalVersion}; TGRect fBounds; TMemberFunctionConnectionTo fConnection; }; //============================================================================== // TExplosionBehavior class TExplosionBehavior : public TCollisionBehavior { public: TaligentTypeExtensionDeclarationsMacro(TExplosionBehavior) public: TExplosionBehavior(); TExplosionBehavior( const TType& us, const TType& them); TExplosionBehavior( const TExplosionBehavior& source); virtual ~TExplosionBehavior(); TExplosionBehavior& operator=(const TExplosionBehavior& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual void ConnectTo(MColliding* colliding); virtual void DisconnectFrom(MColliding& colliding); protected: virtual void HandleUsCollisionPossible(const TNotification& note); virtual void DoPossibleCollision(TExplodingActor* cause, TDequeOf& affected); private: enum {kOriginalVersion}; TType fUsType; TType fThemType; TDequeOf fUs; TDequeOf fThem; TMemberFunctionConnectionTo fUsConnection; }; //============================================================================== // TSimulationRefreshNotification class TSimulationRefreshNotification : public TNotification { public: MCollectibleDeclarationsMacro(TSimulationRefreshNotification); public: TSimulationRefreshNotification( const TInterest& interest, const TGRect& area, const TImage* image); TSimulationRefreshNotification( TInterest* interestToAdopt, const TGRect& area, const TImage* image); TSimulationRefreshNotification( const TSimulationRefreshNotification& source); virtual ~TSimulationRefreshNotification(); TSimulationRefreshNotification& operator=(const TSimulationRefreshNotification& source); virtual bool IsEqual(const MCollectible* other) const; virtual long Hash() const; virtual const TImage* GetImage() const; virtual TGRect GetRefreshArea() const; private: enum {kOriginalVersion}; TSimulationRefreshNotification(); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); TGRect fRefreshArea; const TImage* fImage; }; //============================================================================== // TSimulationLevel class TSimulationLevel { public: TaligentTypeExtensionDeclarationsMacro(TSimulationLevel) public: TSimulationLevel(); TSimulationLevel(const TSimulationLevel& source); virtual ~TSimulationLevel(); TSimulationLevel& operator=(const TSimulationLevel& source); virtual TStream& operator>>=(TStream& toStream) const; virtual TStream& operator<<=(TStream& fromStream); virtual TGRect GetBounds() const; virtual void Restart(); virtual void Start(const TGRect& bounds, unsigned long smallAsteroids, unsigned long mediumAsteroids, unsigned long largeAsteroids, unsigned long ships); virtual void Stop(); virtual bool IsRunning() const; virtual const TModifiableImage* UseImage() const; virtual void DoneWithImage() const; virtual TInterest* CreateRefreshInterest(); virtual TInterest* CreateLevelEndedInterest(); virtual bool KeyDown(TKeyDownEvent& event); virtual bool KeyUp(TKeyUpEvent& event); protected: virtual TExplodingActor* PlacedAtRandomLocation(const TGRect& safeArea, TExplodingActor* actor) const; virtual TSimulationBackground* CreateBackground() const; virtual void AddBehaviors(TDequeOf&) const; virtual TShip* CreateShip(unsigned long ndx, unsigned long count, TGRect& safeArea) const; virtual TAbstractActor* CreateSmallAsteroid(const TGRect& safeArea) const; virtual TAbstractActor* CreateMediumAsteroid(const TGRect& safeArea) const; virtual TAbstractActor* CreateLargeAsteroid(const TGRect& safeArea) const; virtual void HandleRefresh(const TNotification& note); virtual void HandleDeath(const TNotification& note); virtual void HandleLife(const TNotification& note); private: void PrivateStop(); void ClearSimulation(); void CopyInternalState(const TSimulationLevel& sourceSimulation); void SyncToNewInternalState(); enum {kOriginalVersion}; TDequeOf fActors; TDequeOf fBehaviors; TSimulationBackground* fBackground; TGRect fBounds; unsigned long fLivingAsteroids; unsigned long fLivingShips; unsigned long fLivingBullets; TDequeOf fShips; TUniverse* fUniverse; TModifiableImage* fUpdateBuffer; TMemberFunctionConnectionTo fRefreshConnection; TMemberFunctionConnectionTo fLifeConnection; TMemberFunctionConnectionTo fDeathConnection; TNotifier fRefreshNotifier; TAsynchronousNotifier fLevelEndedNotifier; }; #endif