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

Revision 4646, 5.4 KB checked in by dezhidki, 6 years ago (diff)

Muokattu sotilaita viimeiseen muotoon.

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 virtual void OnTriedExitLevel() { }
87
88        public bool Move(float xd, float zd)
89        {
90            if (xd == 0.0F && zd == 0.0F) return false;
91
92            bool inLevel = true;
93
94            if (BoundingRectangle.XRight + xd > level.Width * Viewport.TILESIZE) inLevel = false;
95            else if (BoundingRectangle.XLeft + xd < 0.0F) inLevel = false;
96            else if (BoundingRectangle.ZFar + zd < 0.0F) inLevel = false;
97            else if (BoundingRectangle.ZNear + zd > level.Height * Viewport.TILESIZE) inLevel = false;
98
99            if (!inLevel)
100            {
101                OnTriedExitLevel();
102                return false;
103            }
104
105            int moveSteps = (int)(Math.Sqrt(xd * xd + zd * zd) + 1);
106
107            bool hasMoved = false;
108            for (int i = 0; i < moveSteps; i++)
109            {
110                hasMoved |= MovePart(xd / moveSteps, 0);
111                hasMoved |= MovePart(0, zd / moveSteps);
112            }
113
114            if (hasMoved)
115            {
116                screenPos.X = (x - z) * Viewport.X_SCALE - renderOffset.X;
117                screenPos.Y = (x + z) * Viewport.Y_SCALE - renderOffset.Y;
118            }
119
120            return hasMoved;
121        }
122
123        private bool MovePart(float xd, float zd)
124        {
125            if (xd != 0 && zd != 0) return false;
126
127            List<BoundingRectangle> collidables = level.GetCollidables(this, BoundingRectangle + new Vector2(xd, zd));
128
129            foreach (BoundingRectangle collidable in collidables)
130            {
131                collidable.Owner.OnTouchedBy(this);
132                OnTouched(collidable.Owner);
133            }
134
135            collidables.RemoveAll(br => SkipCollisionCheck(br.Owner));
136
137            if (collidables.Count > 0)
138            {
139                foreach (BoundingRectangle collidable in collidables)
140                {
141                    OnCollidedWith(collidable.Owner);
142                    collidable.Owner.OnCollidedBy(this);
143                }
144
145                return false;
146            }
147
148            x += xd;
149            z += zd;
150
151            BoundingRectangle.Update(x, z, x, z).AddSelf(rectOffset);
152
153            return true;
154        }
155
156        private bool SkipCollisionCheck(BoundingRectangleOwner collidableOwner)
157        {
158            if (typeof(Entity).IsAssignableFrom(collidableOwner.GetType()))
159                return !((Entity)collidableOwner).Blocks(this);
160            if (typeof(Tile).IsAssignableFrom(collidableOwner.GetType()))
161                return false;
162            return true;
163        }
164
165        public virtual void Update() { }
166
167        public virtual void Render(RenderHelper renderer) { }
168
169        public virtual void OnTouched(BoundingRectangleOwner touching) { }
170
171        public virtual void OnTouchedBy(BoundingRectangleOwner toucher) { }
172
173        public virtual void OnCollidedWith(BoundingRectangleOwner colliding) { }
174
175        public virtual void OnCollidedBy(BoundingRectangleOwner collidable) { }
176
177        public virtual void OnRemoved() { }
178
179    }
180}
Note: See TracBrowser for help on using the repository browser.