nes
кстати твой базовый класс сильно напоминает базовый класс иррлихта
http://irrlicht.sourceforge.net/docu/classirr_1_1_i_reference_counted.html
Pushkoff
> > Возможно когда-нить захочу интегрировать поддержку фашистского D3D )
> но до того времени ты будешь юзать 2 класса вместо 1, что согласись не очень
> удобно
ты будешь юзать 1 интерфейс - что очень удобно
PagaN
> Покажешь свой?
я люблю когда гора классов на каждый чих. ну и темплейты чтоб не копипастить, ну и чтоб все было просто и наглядно.
innuendo
> ты будешь юзать 1 интерфейс - что очень удобно
это если рендеров все таки станет 2
а пока он один и очень динамично меняется то лучше заложить статическую типизацию чем интерфейс, ибо все правки будут в 1 месте
AvrDragon
Хах, изобретаю очередной иррлихт получается )
Вот он, мой шедевр
public abstract class GameObject { // TODO: No Animations in Constuctor in hierarchie. Only Flyweights! ICANN make anim by myself with def contsrucktor. // TODO: Constructor chain // TODO: ToString() // TODO: if class is often to inherite, then it must not require many ovberload and have good default behavior // Used in methode draw as sprite color. White is neutral color. // TODO: This class provides some funktionalität and muss konfigurierbar sein. So wie: IsDiyngOnScrollDown, IsDrawnigParicles, IsPlyingDeathAnim etc. Es ist wichtig fgute default und moeglichkeiten störende sachen abschaklten, da viele muessen es doch vererben. public Color drawColor = Color.White; public Vector2 pos; protected Vector2 speed; public Rectangle bounds; // TODO: Redundanz! Def Value from Texture! Particle emmiter has no bounds! protected float moveSpeedPro100Ms; // TODO: kill this prop! why? Not all can move? Couz it redundant to vector2 speed! Why int, not float, if pos is float vector2? protected List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>(); private bool collisible = true; Timer timer; public Color blinkColor = Color.Gray; public static int BLINK_TIME = 27; // public coz i wanna add routes from extern public Ai ai; public int hp; // TODO Design Error, TODO: Interval public Animation baseAnim; // TODO: Design Error? public bool isTilesExtractionDone; // TODO: Design error -> Icomposite protected Explosion explosion; public GameObject( Vector2 pos, float moveSpeedPro100Ms, Rectangle Bounds, int hp) { this.pos = pos; this.moveSpeedPro100Ms = moveSpeedPro100Ms; this.bounds = Bounds; this.hp = hp; speed = new Vector2( ); ai = new Ai( this); } // TODO: Abstract methode DoUpdate! public virtual void Update( GameTime gameTime) { Animation anim = GetCurrentAnim( ); if ( anim != null) { anim.Update( gameTime); } foreach ( ParticleEmitter pe in particleEmitters) { pe.Update( gameTime); pe.SetPos( pos); } ai.Update( gameTime); } // TODO: Why draw have not defalut impl with something like draw(currentAnim) and abstr methode DoDraw()? public virtual void Draw( Camera camera) { if ( Misc.dbgDraw != Misc.DbgDraw.ONLYPOLY) { Animation anim = GetCurrentAnim( ); if ( anim != null) { camera.Draw( anim, GetCenter( ), _rotation, drawColor); } foreach ( ParticleEmitter pe in particleEmitters) { pe.Draw( camera); } } DrawDbgInfo( camera); } protected void DrawDbgInfo( Camera camera) { if ( Misc.dbgDraw == Misc.DbgDraw.NONE) { } else if ( Misc.dbgDraw == Misc.DbgDraw.POLY || Misc.dbgDraw == Misc.DbgDraw.ONLYPOLY) { DbgDrawPoly( camera, Misc.dbgDrawColor); } else if ( Misc.dbgDraw == Misc.DbgDraw.AABB) { DbgDrawAABB( camera); DbgDrawCenterAABB( camera); } else if ( Misc.dbgDraw == Misc.DbgDraw.POLYANDAABB) { DbgDrawPoly( camera, Misc.dbgDrawColor); DbgDrawAABB( camera); DbgDrawCenterAABB( camera); } if ( Misc.dbgDraw != Misc.DbgDraw.NONE) { ai.DrawDbgInfo( camera); } } protected void CheckBounds( ) { CheckBoundsX( ); CheckBoundsY( ); } protected void CheckBoundsX( ) { if ( pos.X < Misc.titleSafeArea.X) pos.X = Misc.titleSafeArea.X; float max_right = Misc.titleSafeArea.X + Misc.titleSafeArea.Width - GetAABB( ).Width; if ( pos.X > max_right) pos.X = max_right; } protected void CheckBoundsY( ) { if ( pos.Y < 0) pos.Y = 0; if ( pos.Y + bounds.Height > Misc.screenHeight) pos.Y = Misc.screenHeight - bounds.Height; } // Objcet gilt as out of game zone if it is totaly out of game zone. Any object that just not fully in is not out of game zone. public bool IsOutOfGameZone( ) { if ( pos.X + bounds.Width < 0) return true; if ( pos.X > Misc.worldWidth) return true; if ( pos.Y + bounds.Height < 0) return true; if ( pos.Y > Misc.screenHeight) return true; return false; } public bool IsOutOfGameZoneTotally( ) { if ( pos.X < -1000) return true; if ( pos.X > Misc.worldWidth + 1000) return true; if ( pos.Y < -2500) return true; if ( pos.Y > Misc.screenHeight + 1000) return true; return false; } public bool IsScrolledDown( int offset) { return pos.Y + bounds.Height > Misc.screenHeight + offset; } public bool IsScrolledDown( ) { return IsScrolledDown( bounds.Height); } // TODO: Design Error: If object can be NOT collisible, so why he must implement this methode? public abstract void OnCollision( GameObject go); // Some class specific actions on death. For example music switch or explosion. public virtual void OnDeath( ) { if ( explosion != null) { Vector2 centerGo = new Vector2( GetCenter( ).X - explosion.GetWidth( ) / 2, GetCenter( ).Y - explosion.GetHeight( ) / 2); explosion.pos = centerGo; StarGame.sceneManager.Add( explosion); explosion = null; // Bringt was=)? R: Tja, falls OnDeath 2 mal aufgerufen wird schon... } } public void SetExplosion( Explosion explosion) { this.explosion = explosion; } // TODO: return IsOutOfGameZone();? // TODO: thre is no way to force trash, if overloaded, use "template method" inst3@d public abstract bool IsTrash( ); protected virtual Animation GetCurrentAnim( ) { return baseAnim; } public void Blink( ) { // TODO: but u must update timer per hand in derived class - its doof und öde drawColor = blinkColor; GetTimer( ).ScheduleAction( ( ) => drawColor = Color.White, BLINK_TIME); } public void AddParticleEmitter( ParticleEmitter pe) { particleEmitters.Add( pe); } public bool IsCollisible( ) { return collisible; } public void SetCollisible( bool value) { collisible = value; } protected float GetMoveOffsetForTime( GameTime gameTime) { return Misc.GetOffsetPro100Ms( gameTime, moveSpeedPro100Ms); } public virtual Memento GetMemento( ) { return new Memento( hp); } public virtual void SetMemento( Memento memento) { hp = memento.hp; } public Vector2 GetSpeed( ) { return speed; } public void DrawBB( Camera camera) { DrawBB( camera, Color.Yellow); } public void DrawBB( Camera camera, Color color) { camera.Draw( StarGame.textureManager.whitePixel, new Rectangle( ( int)pos.X, ( int)pos.Y, bounds.Width, bounds.Height), color); } public Timer GetTimer( ) { if ( timer == null) timer = new Timer( ); return timer; } protected void ScrollDownAsBg( GameTime gameTime) { pos.Y += Misc.GetOffsetPro100Ms( gameTime, StarGame.GetScene( ).GetBgScrollSpeed( )); } //================================ // ADDED FOR COLL DETECT //================================ public float _rotation = 0; // Topology of collisionBody. Has no info about position and rotation. // TODO: private public CollisionBody collisionBodyModel = new CollisionBody( ); public CollisionDetector.CollisionType GetCollisionType( ) { return collisionBodyModel.collisionType; } public void SetCollisionType( CollisionDetector.CollisionType value) { collisionBodyModel.collisionType = value; } public void SetCollisionRadius( float value) { collisionBodyModel.collisionRadius = value; } public List<List<Vector2>> GetCollisionPolygons( ) { return collisionBodyModel.GetTransformedInstance( pos, _rotation, GetCenterOffset( )); } public void AddCollisionPolygon( List<Vector2> poly) { // i think here is safe make copy, not ref, couz man kann zuerst poly setzen und dann pflötzlich es modifizieren collisionBodyModel.Add( poly); } public Vector2 GetCenterAABB( ) { Point center = GetAABB( ).Center; return new Vector2( center.X, center.Y); } // ADDED MISC public static Rectangle makeBoundsFromTexture( Texture2D img) { return new Rectangle( 0, 0, img.Width, img.Height); } public Vector2 GetCenterOffset( ) { return GetCenter( ) - pos; } public void DbgDrawPoly( Camera camera, Color color) { if ( GetCollisionType( ) == CollisionDetector.CollisionType.DIST) { PrimitivePainter.DrawCircle( camera, GetCenter( ), collisionBodyModel.collisionRadius, color); } else { collisionBodyModel.Draw( camera, pos, _rotation, GetCenterOffset( ), color); } } public Rectangle cachedAABB; // use it if u sure it is up to date public Rectangle GetAABB( ) { Rectangle aabb; if ( GetCollisionType( ) == CollisionDetector.CollisionType.DIST) aabb = GetAABB( collisionBodyModel.collisionRadius); else aabb = GetAABB( collisionBodyModel); cachedAABB = aabb; return aabb; } Rectangle GetAABB( float radius) { return new Rectangle( ( int)( GetCenter( ).X - radius), ( int)( GetCenter( ).Y - radius), ( int)( radius * 2), ( int)( radius * 2)); } Rectangle GetAABB( CollisionBody collisionPolygon) { return collisionPolygon.GetAABB( pos, _rotation, GetCenterOffset( )); } public void DbgDrawAABB( Camera sb) { PrimitivePainter.drawingColor = Color.LightCoral; Rectangle aabb = GetAABB( ); aabb.X--; aabb.Y--; aabb.Width += 2; aabb.Height += 2; // 1 pix more size, couse many have eq poly PrimitivePainter.DrawRect( sb, aabb); PrimitivePainter.drawingColor = Color.Red; } public void DbgDrawCenterAABB( Camera sb) { ... } public virtual Vector2 GetCenter( ) { return pos + new Vector2( bounds.Width / 2, bounds.Height / 2); } public void SetCenterIn( Vector2 v) { pos = v - GetCenterOffset( ); } protected void MoveAsBg( GameTime gameTime) { pos.Y += Misc.GetOffsetPro100Ms( gameTime, StarGame.GetScene( ).GetBgScrollSpeed( )); } // call itin Update to freeze object in vertikal center of screen public void dbg_freeze_in_center( ) { // if i wanna freeze to debug if ( pos.Y + GetAABB( ).Height / 2 > Misc.screenHeight / 2) pos.Y = Misc.screenHeight / 2 - GetAABB( ).Height / 2; } }
AvrDragon
иногда кажется что я видел абсолютный говнокод, но вот сегодня твой код расширил границу абсолютного
причем заметь, анимации ты вынес в отдельную сущность, а вот с детектом коллизий, для которого в объекте нужен то всего один меш и функция которая его возвращает, ты не догадался
Pushkoff
Иногда мне кажется, что люди пишущие про говнокод, должны показывать свой код.
Не холивар :)
PagaN
я уже написал что не люблю базовые классы и я сторонник компонентных систем.
nes
> Если объект был удален а другой объект после смерти первого пытается к нему
> обратиться, как тут поможет сборщик мусора?
Чуток поясню ответ г-на Pushkoff'а:
Сборщик мусора (говорю за .NET) может удалить объект лишь только в том случае, когда на него нет ссылок. Типичная ошибка низкоалертных программистов в том, что подписывая на событие объекта другие объекты, этот объект формально будет всегда жив, поскольку ссылка на его событие есть в других объектах.
AvrDragon
покажи плз что такое Memento
Pushkoff
> иногда кажется что я видел абсолютный говнокод, но вот сегодня твой код
> расширил границу абсолютного
thanks to XNA and dear Microsoft.
Со своей идеей «начните моментально писать игры!» они форсируют к подобным высерам.
Pushkoff
> покажи плз что такое Memento
http://www.imdb.com/title/tt0209144/
Pushkoff
Так никто же не просит базовый класс.
Просто покажи какой-нибудь код, узнаешь о нем много нового :)
ЗЫ. Не от меня, мне просто скучно.
mrt
ну дословно memento это вроде как сюрприз
Тема в архиве.