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

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