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

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