source: 2013/30/DenisZ/CastleMaster/CastleMaster/CastleMaster/Entities/Entity.cs @ 4581

Revision 4581, 5.0 KB checked in by dezhidki, 10 years ago (diff)

Talletus.

Line 
1using CastleMaster.Graphics;
2using CastleMaster.Physics;
3using CastleMaster.World;
4using Microsoft.Xna.Framework;
5using System.Collections.Generic;
6using System;
7using CastleMaster.World.Tiles;
8
9namespace CastleMaster.Entities
10{
11    public class Entity : BoundingRectangleOwner
12    {
13        protected float x, z, width = 16.0F, depth = 16.0F;
14        protected Level level;
15        private BoundingRectangle boundingRect;
16        protected BoundingRectangle rectOffset;
17        protected Vector2 renderOffset, screenPos;
18        protected bool isSolid = true;
19        protected float moveSpeed = 0.0F;
20
21        public Entity(Level level)
22        {
23            this.level = level;
24            renderOffset = Vector2.Zero;
25            screenPos = Vector2.Zero;
26            Removed = false;
27            rectOffset = new BoundingRectangle(-width / 2, -depth / 2, width / 2, depth / 2, null);
28        }
29
30        public bool Removed { get; protected set; }
31
32        public float X
33        {
34            get { return x; }
35            set { x = value; }
36        }
37
38        public float Z
39        {
40            get { return z; }
41            set { z = value; }
42        }
43
44        public float Width { get { return width; } }
45
46        public float Depth { get { return depth; } }
47
48        public BoundingRectangle BoundingRectangle { get { return boundingRect; } }
49
50        public Vector2 RenderOffset { get { return renderOffset; } }
51
52        protected Vector2 ScreenPos { get { return screenPos * Viewport.ZOOM; } }
53
54        public virtual void Init()
55        {
56            screenPos.X = (x - z) * Viewport.X_SCALE - renderOffset.X;
57            screenPos.Y = (x + z) * Viewport.Y_SCALE - renderOffset.Y;
58
59            boundingRect = new BoundingRectangle(x, z, x, z, this).AddSelf(rectOffset);
60        }
61
62        public void AddBoundingRect(ref List<BoundingRectangle> list, Entity ent)
63        {
64            if (ent != this)
65                list.Add(BoundingRectangle);
66        }
67
68        public virtual bool IsSolidTo(Entity ent)
69        {
70            return isSolid;
71        }
72
73        public bool Blocks(Entity ent)
74        {
75            return isSolid && ent.isSolid && IsSolidTo(ent) && ent.IsSolidTo(this);
76        }
77
78        public bool Move(float xd, float zd)
79        {
80            if (BoundingRectangle.XRight + xd > level.Width * Viewport.TILESIZE) return false;
81            if (BoundingRectangle.XLeft + xd < 0.0F) return false;
82            if (BoundingRectangle.ZFar + zd < 0.0F) return false;
83            if (BoundingRectangle.ZNear + zd > level.Height * Viewport.TILESIZE) return false;
84
85            int moveSteps = (int)(Math.Sqrt(xd * xd + zd * zd) + 1);
86
87            bool hasMoved = false;
88            for (int i = 0; i < moveSteps; i++)
89            {
90                hasMoved |= MovePart(xd / moveSteps, 0);
91                hasMoved |= MovePart(0, zd / moveSteps);
92            }
93
94            if (hasMoved)
95            {
96                screenPos.X = (x - z) * Viewport.X_SCALE - renderOffset.X;
97                screenPos.Y = (x + z) * Viewport.Y_SCALE - renderOffset.Y;
98            }
99
100            return hasMoved;
101        }
102
103        private bool MovePart(float xd, float zd)
104        {
105            if (xd != 0 && zd != 0) return false;
106
107            List<BoundingRectangle> collidables = level.GetCollidables(this, BoundingRectangle + new Vector2(xd, zd));
108
109            foreach (BoundingRectangle collidable in collidables)
110            {
111                collidable.Owner.OnTouchedBy(this);
112                OnTouched(collidable.Owner);
113            }
114
115            collidables.RemoveAll(br => SkipCollisionCheck(br.Owner));
116
117            if (collidables.Count > 0)
118            {
119                foreach (BoundingRectangle collidable in collidables)
120                {
121                    OnCollidedWith(collidable.Owner);
122                    collidable.Owner.OnCollidedBy(this);
123                }
124
125                return false;
126            }
127
128            x += xd;
129            z += zd;
130
131            BoundingRectangle.Update(x, z, x, z).AddSelf(rectOffset);
132
133            return true;
134        }
135
136        private bool SkipCollisionCheck(BoundingRectangleOwner collidableOwner)
137        {
138            if (typeof(Entity).IsAssignableFrom(collidableOwner.GetType()))
139                return !((Entity)collidableOwner).Blocks(this);
140            if (typeof(Tile).IsAssignableFrom(collidableOwner.GetType()))
141                return false;
142            return true;
143        }
144
145        public virtual void Update() { }
146
147        public virtual void Render(RenderHelper renderer) { }
148
149        public virtual void OnTouched(BoundingRectangleOwner touching) { }
150
151        public virtual void OnTouchedBy(BoundingRectangleOwner toucher) { }
152
153        public virtual void OnCollidedWith(BoundingRectangleOwner colliding) { }
154
155        public virtual void OnCollidedBy(BoundingRectangleOwner collidable) { }
156
157        public virtual void OnRemoved() { }
158
159    }
160}
Note: See TracBrowser for help on using the repository browser.