Jypeli 10
The simple game programming library
ChildObjects.cs
Siirry tämän tiedoston dokumentaatioon.
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen, Mikko Röyskö
28 */
29
30using System;
31using System.Collections.Generic;
32using System.Linq;
33using Microsoft.Xna.Framework;
34
35namespace Jypeli
36{
37 public partial class GameObject : GameObjectContainer
38 {
40 internal protected bool autoResizeChildObjects = true;
41
46 {
47 get { InitChildren(); return _childObjects; }
48 }
49
54 public int ObjectCount
55 {
56 get { return _childObjects == null ? 0 : _childObjects.Count; }
57 }
58
64 public IEnumerable<T> GetChildObjects<T>() where T : IGameObject
65 {
66 foreach ( IGameObject o in Objects )
67 {
68 if ( o is T )
69 yield return (T)o;
70 }
71 }
72
78 public IEnumerable<T> GetChildObjects<T>( Predicate<T> predicate ) where T : IGameObject
79 {
80 foreach ( IGameObject o in Objects )
81 {
82 if ( o is T && predicate( (T)o ) )
83 yield return (T)o;
84 }
85 }
86
91
98 public void Add(IGameObject childObject)
99 {
100 if (childObject == this)
101 throw new InvalidOperationException("Child cannot be same as parent");
102
103 if (this is PhysicsObject && childObject is PhysicsObject && PhysicsGameBase.Instance != null && PhysicsGameBase.Instance.FarseerGame)
104 {
105 PhysicsGameBase.Instance.Engine.ConnectBodies((PhysicsObject)this, (PhysicsObject)childObject);
106 }
107
108 if ( !( childObject is GameObject ) )
109 throw new ArgumentException( "Child object can not be a non-GameObject" );
110
111 Objects.Add( (GameObject)childObject );
112 childObject.Parent = this;
113 ((GameObject)childObject).InitialRelativePosition = childObject.RelativePositionToMainParent;
114 ((GameObject)childObject).InitialRelativeAngle = childObject.RelativeAngleToMainParent;
115 }
116
125 public void Remove( IGameObject childObject )
126 {
127 if ( !( childObject is GameObject ) )
128 throw new ArgumentException( "Child object can not be a non-GameObject" );
129
130 Objects.Remove( (GameObject)childObject );
131 childObject.Parent = null;
132 }
133
137 protected virtual void InitChildren()
138 {
139 if ( _childObjects != null ) return;
141 _childObjects.ItemAdded += this.OnChildAdded;
142 _childObjects.ItemRemoved += this.OnChildRemoved;
144
145 this.AddedToGame += () => _childObjects.ForEach(c => Game.OnAddObject(c));
146 this.Removed += () => _childObjects.ForEach(c => Game.OnRemoveObject(c));
147
148 // Objects list needs updating
149 IsUpdated = true;
150 }
151
152 private void OnChildAdded( GameObject child )
153 {
154 child.Parent = this;
155
156 // It is possible to add children to objects which themselves are not yet (or not at the moment)
157 // added to the game. This might not be obvious, since the _childObjects SynchronousList is
158 // naturally not updated when the parent is not in game ? but there exist functions that
159 // flush _childObjects' queued operations right away, and they may get called.
160 // Therefore we need to ensure that Game.OnAddObject is only called if the parent is in game.
161 if (this.IsAddedToGame)
162 Game.OnAddObject(child);
163 }
164
165 private void OnChildRemoved( GameObject child )
166 {
167 // In the same vein as in OnChildAdded, it is possible that a child is removed from
168 // _childObjects while not in game. This avoids multiple removal.
169 if (child.IsAddedToGame)
170 Game.OnRemoveObject(child);
171
172 // This 'if' ensures that nothing is broken if a child is transferred
173 // to another parent first and removed afterwards
174 if ( child.Parent == this )
175 child.Parent = null;
176 }
177
178 private void DestroyChildren()
179 {
180 if ( _childObjects == null ) return;
181
182 foreach ( GameObject child in _childObjects )
183 {
184 child.Destroy();
185 }
186 }
187
188 private void UpdateChildren( Time time )
189 {
190 Objects.Update( time );
191
192 Objects.ForEach(o => {
193 o.RelativePositionToMainParent = o.InitialRelativePosition;
194 o.RelativeAngleToMainParent = o.InitialRelativeAngle;
195 });
196 }
197
204 {
205 if (this.Parent is null) return this;
206 else return ((GameObject)Parent).GetMainParent();
207 }
208
209 private void UpdateChildSizes( Vector oldSize, Vector newSize )
210 {
211 if ( _childObjects == null ) return;
212
213 double xFactor = newSize.X / oldSize.X;
214 double yFactor = newSize.Y / oldSize.Y;
215
216 foreach ( var o in _childObjects )
217 {
218 Vector oldChildSize = o.Size;
219 o.Size = new Vector( oldChildSize.X * xFactor, oldChildSize.Y * yFactor );
220
221 // Vector direction = o.Position.Normalize();
222 // double distance = o.Position.Magnitude;
223 Vector oldChildPosition = o.Position;
224 o.Position = new Vector( oldChildPosition.X * xFactor, oldChildPosition.Y * yFactor );
225 }
226 }
227
228 private bool IsInsideChildren( Vector point )
229 {
230 if ( _childObjects == null ) return false;
231
232 for ( int i = 0; i < _childObjects.Count; i++ )
233 {
234 if ( _childObjects[i].IsInside( point ) ) return true;
235 }
236
237 return false;
238 }
239
243 public virtual void Clear()
244 {
245 _childObjects.Clear();
246 }
247 }
248}
static void OnRemoveObject(IGameObject obj)
Definition: Layers.cs:131
bool FarseerGame
Onko käytössä Farseer-fysiikkamoottori HUOM: Tämä saattaa poistua tulevaisuudessa jos/kun siitä tehdä...
Definition: Game.cs:113
static void OnAddObject(IGameObject obj)
Definition: Layers.cs:125
Pelialueella liikkuva olio. Käytä fysiikkapeleissä PhysicsObject-olioita.
Definition: Appearance.cs:34
void UpdateChildSizes(Vector oldSize, Vector newSize)
void NotifyParentAboutChangedSizingAttributes()
Should be called whenever properties that might affect layouts are changed.
Definition: Layout.cs:83
void UpdateChildren(Time time)
bool IsAddedToGame
Onko olio lisätty peliin.
SynchronousList< GameObject > Objects
Olion lapsioliot. Saa muuttaa.
Definition: ChildObjects.cs:46
SynchronousList< GameObject > GetChildObjectList
Palauttaa olion lapsioliot.
Definition: ChildObjects.cs:90
SynchronousList< GameObject > _childObjects
Definition: ChildObjects.cs:39
GameObject(double width, double height)
Alustaa uuden peliolion.
Definition: GameObject.cs:79
void OnChildRemoved(GameObject child)
bool IsInsideChildren(Vector point)
void Remove(IGameObject childObject)
Poistaa lapsiolion. Jos haluat tuhota olion, kutsu mielummin olion Destroy-metodia.
bool IsInside(Vector point)
Onko piste p tämän olion sisäpuolella.
Definition: Dimensions.cs:155
IEnumerable< T > GetChildObjects< T >()
Palauttaa olion lapsioliot.
Definition: ChildObjects.cs:64
virtual void InitChildren()
Alustaa lapsioliot
GameObject GetMainParent()
Antaa olion korkeimman tason isäntäolion. Eli vanhemman vanhemman...
virtual void Clear()
Poistaa kaikki lapsioliot.
void Add(IGameObject childObject)
Lisää annetun peliolion tämän olion lapseksi. Lapsiolio liikkuu tämän olion mukana.
Definition: ChildObjects.cs:98
int? ObjectCount
Olion lapsiolioiden lukumäärä. Kuten Objects.Count, mutta optimoitu.
Definition: ChildObjects.cs:55
void OnChildAdded(GameObject child)
bool autoResizeChildObjects
Definition: ChildObjects.cs:40
IGameObject Parent
Olio, jonka lapsiolio tämä olio on. Jos null, olio ei ole minkään olion lapsiolio.
Action AddedToGame
Tapahtuu, kun olio lisätään peliin.
Action Removed
Tapahtuu, kun olio poistetaan pelistä (tuhotaan tai ei).
bool IsUpdated
Tarvitseeko olio päivittämistä. Kun perit oman luokkasi tästä luokasta, aseta tämä arvoon true,...
Kantaluokka fysiikkapeleille.
static new PhysicsGameBase Instance
Käynnissä olevan fysiikkapelin pääolio.
Kappale joka noudattaa fysiikan lakeja, johon voi törmätä. Vaatii että käytössä on fysiikkapeli.
Definition: Collisions.cs:7
Synkroninen lista, eli lista joka päivittyy vasta kun sen Update-metodia kutsutaan....
Action Changed
Tapahtuu kun lista on muuttunut.
void ForEach(Action< T > action)
Suorittaa annetun toimenpiteen kaikille (nykyisille) listan alkioille.
Action< T > ItemRemoved
Tapahtuu kun elementti on poistettu listasta.
new Vector Size
Koko.
Definition: Dimensional.cs:72
Yhteinen rajapinta kaikille peliolioille.
Definition: IGameObject.cs:11
IGameObject Parent
Definition: IGameObject.cs:14
Vector RelativePositionToMainParent
Definition: IGameObject.cs:30
Angle RelativeAngleToMainParent
Definition: IGameObject.cs:31
new Vector Position
Paikka.
Definition: Positional.cs:32
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:14
2D-vektori.
Definition: Vector.cs:67
double Y
Vektorin Y-komponentti
Definition: Vector.cs:339
double X
Vektorin X-komponentti.
Definition: Vector.cs:334