Jypeli  5
The simple game programming library
MessageDisplay.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2009-2011 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.
28  */
29 
30 using System;
31 using System.ComponentModel;
32 using System.Collections.Generic;
33 using Microsoft.Xna.Framework.Graphics;
34 using Microsoft.Xna.Framework;
35 
36 using XnaRect = Microsoft.Xna.Framework.Rectangle;
37 using XnaColor = Microsoft.Xna.Framework.Color;
38 
39 namespace Jypeli.Widgets
40 {
41  public class MessageDisplay : Widget
42  {
43  private struct Message
44  {
45  public String Text;
46  public Color Color;
47  public TimeSpan Expires;
48 
49  public bool Expired
50  {
51  get { return Expires < Game.Time.SinceStartOfGame; }
52  }
53 
54  public TimeSpan TimeLeft
55  {
56  get { return Expired ? TimeSpan.Zero : Expires - Game.Time.SinceStartOfGame; }
57  }
58 
59  public Message( string text, Color color, TimeSpan lifetime )
60  {
61  Text = text;
62  Color = color;
63  Expires = Game.Time.SinceStartOfGame + lifetime;
64  }
65  }
66 
70  public int MaxMessageCount { get; set; }
71 
75  public TimeSpan MessageTime { get; set; }
76 
80  public Font Font
81  {
82  get { return _font; }
83  set
84  {
85  _font = value;
86  fontHeight = value.XnaFont.MeasureString( "A" ).Y;
87  UpdateTexture();
88  }
89  }
90 
94  public Color TextColor { get; set; }
95 
99  public Color BackgroundColor
100  {
101  get { return bgColor; }
102  set
103  {
104  bgColor = value;
105  UpdateTexture();
106  }
107  }
108 
115  public bool RealTime { get; set; }
116 
117  private Color bgColor = Color.Transparent;
118  private Image bgImage = null;
119  private Font _font;
120  private float fontHeight;
121  private List<Message> messages = new List<Message>();
122  private Queue<String> unseen = new Queue<string>();
123 
124  private Timer removeTimer;
125 
130  public MessageDisplay()
131  : base( Game.Screen.WidthSafe, Game.Screen.HeightSafe )
132  {
133  removeTimer = new Timer();
134  removeTimer.Timeout += removeMessages;
135 
136  TextColor = Color.Black;
138 
139  MaxMessageCount = 20;
140  MessageTime = TimeSpan.FromSeconds( 5 );
141  Font = Font.Default;
142 
143  // default position to top-left-corner
144  this.Position = new Vector( Game.Screen.LeftSafe + Game.Screen.WidthSafe / 2,
146  }
147 
148  private void removeMessages()
149  {
150  removeTimer.Stop();
151 
152  while ( messages.Count > 0 && messages[0].Expired )
153  {
154  messages.RemoveAt( 0 );
155  if ( unseen.Count > 0 ) Add( unseen.Dequeue() );
156  }
157 
158  if ( messages.Count > 0 )
159  {
160  removeTimer.Interval = messages[0].TimeLeft.TotalSeconds;
161  removeTimer.Start();
162  }
163 
164  UpdateTexture();
165  }
166 
167  protected override void Draw( Matrix parentTransformation, Matrix transformation )
168  {
169  SpriteBatch spriteBatch = Graphics.SpriteBatch;
170  Matrix m =
171  Matrix.CreateTranslation( (float)Position.X, (float)Position.Y, 0 )
172  * parentTransformation;
173 
174  spriteBatch.Begin( SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise, null, m );
175 
176  if ( bgImage != null )
177  spriteBatch.Draw( bgImage.XNATexture, Vector2.Zero, XnaColor.White );
178 
179  for ( int i = 0; i < messages.Count; i++ )
180  {
181  spriteBatch.DrawString( this.Font.XnaFont, messages[i].Text, new Vector2( 0, i * fontHeight ), messages[i].Color.AsXnaColor() );
182  }
183 
184  spriteBatch.End();
185 
186  base.Draw( parentTransformation, transformation );
187  }
188 
189  private void UpdateTexture()
190  {
191  if ( messages.Count == 0 || bgColor == Color.Transparent )
192  {
193  bgImage = null;
194  return;
195  }
196 
197  double maxW = 0;
198 
199  for ( int i = 0; i < messages.Count; i++ )
200  {
201  Vector2 dims = Font.XnaFont.MeasureString( messages[i].Text );
202  if ( dims.X > maxW ) maxW = dims.X;
203  }
204 
205  bgImage = new Image( maxW, messages.Count * fontHeight, bgColor );
206  }
207 
211  public void Add( string message )
212  {
213  if ( messages.Count > MaxMessageCount )
214  {
215  if ( RealTime )
216  {
217  messages.RemoveRange( 0, messages.Count - MaxMessageCount + 1 );
218  }
219  else
220  {
221  unseen.Enqueue( message );
222  return;
223  }
224  }
225 
226  messages.Add( new Message( message, TextColor, MessageTime ) );
227  UpdateTexture();
228 
229  if ( !removeTimer.Enabled )
230  {
231  removeTimer.Interval = MessageTime.TotalSeconds;
232  removeTimer.Start();
233  }
234  }
235 
239  public void Add( string message, Color color )
240  {
241  if ( messages.Count > MaxMessageCount )
242  {
243  if ( RealTime )
244  {
245  messages.RemoveRange( 0, messages.Count - MaxMessageCount + 1 );
246  }
247  else
248  {
249  unseen.Enqueue( message );
250  return;
251  }
252  }
253 
254  messages.Add( new Message( message, color, MessageTime ) );
255  UpdateTexture();
256 
257  if ( !removeTimer.Enabled )
258  {
259  removeTimer.Interval = MessageTime.TotalSeconds;
260  removeTimer.Start();
261  }
262  }
263 
267  public void Clear()
268  {
269  messages.Clear();
270  UpdateTexture();
271  }
272  }
273 }
double WidthSafe
Näytön "turvallinen" ts. laiteriippumaton leveys x-suunnassa.
Definition: View.cs:122
override void Draw(Matrix parentTransformation, Matrix transformation)
static readonly Color Black
Musta.
Definition: Color.cs:494
void Clear()
Poistaa kaikki lisätyt viestit.
Fontti.
Definition: Font.cs:22
double TopSafe
Näytön yläreunan "turvallinen" ts. laiteriippumaton y-koordinaatti.
Definition: View.cs:154
double LeftSafe
Näytön vasemman reunan "turvallinen" ts. laiteriippumaton x-koordinaatti.
Definition: View.cs:138
TimeSpan SinceStartOfGame
Aika joka on kulunut pelin alusta.
Definition: Time.cs:32
Käyttöliittymän komponentti.
Definition: Appearance.cs:9
void Add(string message)
Lisää uuden viestin näkymään.
Kuva.
Definition: Image.cs:24
static ScreenView Screen
Näytön dimensiot, eli koko ja reunat.
Definition: Game.cs:194
static readonly Color Transparent
Läpinäkyvä väri.
Definition: Color.cs:869
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
static readonly Font Default
OletusFontti.
Definition: Font.cs:27
Ajastin, joka voidaan asettaa laukaisemaan tapahtumia tietyin väliajoin.
Definition: Timer.cs:39
Väri.
Definition: Color.cs:13
static Time Time
Peliaika. Sisältää tiedon siitä, kuinka kauan peliä on pelattu (Time.SinceStartOfGame) ja kuinka kaua...
Definition: Game.cs:309
void Add(string message, Color color)
Lisää uuden viestin näkymään.
2D-vektori.
Definition: Vector.cs:56
double HeightSafe
Näytön "turvallinen" ts. laiteriippumaton korkeus y-suunnassa.
Definition: View.cs:130
MessageDisplay()
Luo uuden viestinäytön.