PageRenderTime 67ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 2ms

/Poing2/frmBaseBlock.cs

http://github.com/BCProgramming/BASeBlock
C# | 6177 lines | 3673 code | 1651 blank | 853 comment | 589 complexity | 39e75fa9d13489553b0b7ee172863e7d MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * BASeCamp BASeBlock
  3. Copyright (c) 2011, Michael Burgwin
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  6. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  7. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  8. Neither the name of BASeCamp Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  9. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10. * */
  11. using System;
  12. using System.Collections.Generic;
  13. using System.ComponentModel;
  14. using System.Data;
  15. using System.Diagnostics;
  16. using System.Drawing;
  17. using System.Drawing.Drawing2D;
  18. using System.Drawing.Imaging;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Runtime.InteropServices;
  22. using System.Runtime.Serialization;
  23. using System.Runtime.Serialization.Formatters.Binary;
  24. using System.Text;
  25. using System.Threading;
  26. using System.Windows.Forms;
  27. using System.Security;
  28. //using System.Windows.Media;
  29. using BASeCamp.BASeBlock.Blocks;
  30. using BASeCamp.BASeBlock.Cheats;
  31. using BASeCamp.BASeBlock.Events;
  32. using BASeCamp.BASeBlock.GameObjects;
  33. using BASeCamp.BASeBlock.GameObjects.Orbs;
  34. using BASeCamp.BASeBlock.PaddleBehaviours;
  35. using BASeCamp.BASeBlock.Particles;
  36. using BASeCamp.Configuration;
  37. using BASeCamp.BASeBlock.GameStates;
  38. using BASeCamp.BASeBlock.HighScores;
  39. using BASeCamp.Updating;
  40. using BASeCamp.Licensing;
  41. using Brush=System.Drawing.Brush;
  42. using Color=System.Drawing.Color;
  43. using Pen=System.Drawing.Pen;
  44. using ThreadState=System.Threading.ThreadState;
  45. using Timer = System.Threading.Timer;
  46. namespace BASeCamp.BASeBlock
  47. {
  48. public partial class frmBaseBlock : Form,iGameClient ,iManagerCallback
  49. {
  50. [DllImport("user32.dll")]
  51. public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
  52. public IGameState ActiveState { get { return gamerunstate;} set { gamerunstate = value;}}
  53. private const int WM_SETREDRAW = 11;
  54. public int[][] GameOverMatrix = new int[][]
  55. {
  56. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  57. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  58. new int[]{0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,},
  59. new int[]{0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,},
  60. new int[]{0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,},
  61. new int[]{0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,0,0,},
  62. new int[]{0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0,},
  63. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,},
  64. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,},
  65. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,},
  66. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  67. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  68. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,},
  69. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,},
  70. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,},
  71. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,1,0,0,1,1,},
  72. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,},
  73. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,},
  74. new int[]{0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,},
  75. new int[]{0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,},
  76. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  77. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  78. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  79. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  80. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  81. };
  82. private int MaxParticles = 800;
  83. public class MenuModeMenuItem
  84. {
  85. public class MenuItemStyleData
  86. {
  87. //private Color _BackColor = Color.White;
  88. //private Color _ForeColor = Color.Black;
  89. private Brush _Background = new SolidBrush(Color.White);
  90. private Brush _Foreground = new SolidBrush(Color.Black);
  91. private Pen _BoxBorder = new Pen(Color.Black);
  92. public Brush Background { get { return _Background; } set { _Background = value; } }
  93. public Brush Foreground { get { return _Foreground; } set { _Foreground = value; } }
  94. public Pen BoxBorder { get { return _BoxBorder; } set { _BoxBorder = value; } }
  95. private Color _BackColor, _ForeColor;
  96. public Color BackColor
  97. {
  98. get { return _BackColor; }
  99. set
  100. {
  101. _BackColor = value;
  102. _Background = new SolidBrush(_BackColor);
  103. }
  104. }
  105. public Color ForeColor
  106. {
  107. get { return _ForeColor; }
  108. set
  109. {
  110. _ForeColor = value;
  111. _Foreground = new SolidBrush(_ForeColor);
  112. }
  113. }
  114. private Font _ItemFont = new Font("Arial", 14);
  115. public Font ItemFont { get { return _ItemFont; } set { _ItemFont = value; } }
  116. public MenuItemStyleData()
  117. {
  118. }
  119. public MenuItemStyleData(Color pBackColor, Color pForeColor,Font pItemFont)
  120. {
  121. BackColor = pBackColor;
  122. ForeColor = pForeColor;
  123. ItemFont = pItemFont;
  124. }
  125. }
  126. public delegate void MenuItemEvent(MenuModeMenuItem sender);
  127. public delegate void MenuItemPrePaintEvent(MenuModeMenuItem sender, RectangleF drawarea);
  128. public event MenuItemEvent MenuItemSelect;
  129. public event MenuItemEvent MenuItemUnselect;
  130. public event MenuItemEvent MenuItemChosen;
  131. public event MenuItemPrePaintEvent MenuItemPrePaint;
  132. public void InvokeItemPrePaint(RectangleF drawarea)
  133. {
  134. var temp = MenuItemPrePaint;
  135. if (temp != null) temp.Invoke(this,drawarea);
  136. }
  137. public void InvokeItemSelect()
  138. {
  139. var temp = MenuItemSelect;
  140. if (temp != null) temp.Invoke(this);
  141. }
  142. public void InvokeItemUnselect()
  143. {
  144. var temp = MenuItemUnselect;
  145. if (temp != null) temp.Invoke(this);
  146. }
  147. public void InvokeItemChosen()
  148. {
  149. var temp = MenuItemChosen;
  150. if (temp != null) temp.Invoke(this);
  151. }
  152. private Object _Tag = null;
  153. public Object Tag { get { return _Tag; } set { _Tag = value; } }
  154. private String _Text;
  155. private MenuModeMenuItem.MenuItemStyleData Style = new MenuModeMenuItem.MenuItemStyleData(Color.White,Color.Black,new Font("Arial",14));
  156. private MenuModeMenuItem.MenuItemStyleData SelStyle = new MenuModeMenuItem.MenuItemStyleData(Color.Black,Color.Yellow,new Font("Arial",14,FontStyle.Bold)) ;
  157. private bool _Selected=false;
  158. public bool Selected { get { return _Selected; } set { _Selected = value; } }
  159. public MenuModeMenuItem.MenuItemStyleData OurStyle { get {
  160. return Selected?SelStyle:Style;
  161. } }
  162. public delegate void ItemActionProc(MenuModeMenuItem sender);
  163. private ItemActionProc _Action;
  164. public ItemActionProc Action { get { return _Action; } set { _Action = value; } }
  165. private static Graphics useg = null;
  166. private static bool ginitialized;
  167. public SizeF MeasureItem()
  168. {
  169. if (!ginitialized)
  170. {
  171. Bitmap useb = new Bitmap(1, 1);
  172. useg = Graphics.FromImage(useb);
  173. }
  174. SizeF gotsize = useg.MeasureString(_Text, OurStyle.ItemFont);
  175. return new SizeF(gotsize.Width*1.5f,gotsize.Height);
  176. }
  177. public MenuModeMenuItem(String Text,ItemActionProc MenuAction)
  178. {
  179. _Text=Text;
  180. _Action = MenuAction;
  181. SelStyle.BoxBorder = new Pen(Color.Red, 3);
  182. Style.BoxBorder = new Pen(Color.White, 1);
  183. }
  184. public String Text { get { return _Text; } set { _Text = value; } }
  185. public void Draw(Graphics g, RectangleF drawArea)
  186. {
  187. MenuModeMenuItem.MenuItemStyleData usestyle = OurStyle;
  188. InvokeItemPrePaint(drawArea);
  189. g.FillRectangle(usestyle.Background, drawArea);
  190. StringFormat useformat = new StringFormat();
  191. useformat.Alignment=StringAlignment.Center;
  192. g.DrawRectangle(usestyle.BoxBorder, drawArea.ToRectangle());
  193. g.DrawString(_Text, OurStyle.ItemFont, usestyle.Foreground , drawArea,useformat);
  194. }
  195. }
  196. public class MenuModeData
  197. {
  198. //list of menu items.
  199. private String _MenuMusic = "credit";
  200. private String _MenuTitle = "MENU";
  201. private Font _TitleFont = new Font("Arabia", 18);
  202. public String MenuTitle { get { return _MenuTitle; } set { _MenuTitle = value; } }
  203. public String MenuMusic { get { return _MenuMusic; } set { _MenuMusic = value; } }
  204. public LinkedList<MenuModeMenuItem> items = new LinkedList<MenuModeMenuItem>();
  205. private MenuModeMenuItem _SelectedItem = null;
  206. //accessor which "unselects" (untoggles) the currently selected items selected state when a new one is assigned, and sets the new one.
  207. public MenuModeMenuItem SelectedItem
  208. {
  209. get {return _SelectedItem; }
  210. set {
  211. if (_SelectedItem != null)
  212. {
  213. _SelectedItem.Selected=false;
  214. }
  215. _SelectedItem=value;
  216. _SelectedItem.Selected = true;
  217. }
  218. }
  219. public MenuModeData(IEnumerable<MenuModeMenuItem> pitems, MenuModeMenuItem.MenuItemEvent SelectEvent, MenuModeMenuItem.MenuItemEvent UnselectEvent, MenuModeMenuItem.MenuItemEvent ChosenEvent)
  220. {
  221. foreach (var loopit in pitems)
  222. {
  223. var itemadd = loopit;
  224. itemadd.MenuItemSelect += SelectEvent;
  225. itemadd.MenuItemUnselect += UnselectEvent;
  226. itemadd.MenuItemChosen += ChosenEvent;
  227. items.AddLast(itemadd);
  228. }
  229. }
  230. public void MenuAction(MenuModeMenuItem sender)
  231. {
  232. }
  233. public MenuModeMenuItem HitTest(BCBlockGameState gstate,PointF testpoint)
  234. {
  235. //like the draw routine, we need to acquire the calculated sizes. We just don't draw.
  236. //calculations. First, get a SizeF from each menu item...
  237. List<SizeF> allsizes = (from n in items select n.MeasureItem()).ToList();
  238. //get maximum width...
  239. float totalheight = 0;
  240. foreach (var loopsize in allsizes)
  241. {
  242. totalheight += loopsize.Height;
  243. }
  244. float maxwidth = (from n in allsizes orderby n.Width descending select n).First().Width;
  245. //center the rectangle maxwidth,totalheight in the gamearea.
  246. RectangleF EntireSizeRect = BCBlockGameState.CenterRect(gstate.GameArea,
  247. new SizeF(maxwidth, totalheight));
  248. //title rect will be centered above the entiresize rect. First, we need to measure the title...
  249. SizeF titlesize = BCBlockGameState.MeasureString(_MenuTitle, _TitleFont);
  250. if (titlesize.Width < EntireSizeRect.Width)
  251. {
  252. titlesize = new SizeF(EntireSizeRect.Width, titlesize.Height);
  253. }
  254. PointF TopCenter = new PointF(EntireSizeRect.Left + EntireSizeRect.Width / 2, EntireSizeRect.Top);
  255. RectangleF TitleRect = new RectangleF(TopCenter.X - titlesize.Width / 2, TopCenter.Y - titlesize.Height,
  256. titlesize.Width, titlesize.Height);
  257. //EntireSizeRect = new RectangleF(EntireSizeRect.Left - 20, EntireSizeRect.Top - 20, EntireSizeRect.Width + 20, EntireSizeRect.Height + 20);
  258. float currx = EntireSizeRect.Left;
  259. float currY = EntireSizeRect.Top;
  260. //go through each one and calculate it's rectangle, then see if the given position is inside it.
  261. float selectedY = 0;
  262. MenuModeMenuItem selecteditemuse = null;
  263. foreach (var loopitem in items)
  264. {
  265. var loopiheight = loopitem.MeasureItem();
  266. loopitem.Selected = loopitem == SelectedItem;
  267. {
  268. currY += loopiheight.Height;
  269. RectangleF testrect = new RectangleF(new PointF(currx, currY),
  270. new SizeF(maxwidth, loopiheight.Height));
  271. if (testrect.Contains(testpoint))
  272. {
  273. return loopitem;
  274. }
  275. }
  276. }
  277. return null; //no hit...
  278. }
  279. public void Draw(Graphics g, BCBlockGameState gstate)
  280. {
  281. //calculations. First, get a SizeF from each menu item...
  282. List<SizeF> allsizes = (from n in items select n.MeasureItem()).ToList();
  283. //get maximum width...
  284. float totalheight = 0;
  285. foreach (var loopsize in allsizes)
  286. {
  287. totalheight += loopsize.Height;
  288. }
  289. float maxwidth = (from n in allsizes orderby n.Width descending select n).First().Width;
  290. //center the rectangle maxwidth,totalheight in the gamearea.
  291. RectangleF EntireSizeRect = BCBlockGameState.CenterRect(gstate.GameArea,
  292. new SizeF(maxwidth, totalheight));
  293. //title rect will be centered above the entiresize rect. First, we need to measure the title...
  294. SizeF titlesize = BCBlockGameState.MeasureString(_MenuTitle, _TitleFont);
  295. if (titlesize.Width < EntireSizeRect.Width)
  296. {
  297. titlesize = new SizeF(EntireSizeRect.Width, titlesize.Height);
  298. }
  299. PointF TopCenter = new PointF(EntireSizeRect.Left + EntireSizeRect.Width/2, EntireSizeRect.Top);
  300. RectangleF TitleRect = new RectangleF(TopCenter.X - titlesize.Width/2, TopCenter.Y - titlesize.Height,
  301. titlesize.Width, titlesize.Height);
  302. //draw the title.
  303. g.FillRectangle(new SolidBrush(Color.Green), TitleRect);
  304. g.DrawRectangle(new Pen(Color.Yellow, 3), TitleRect.ToRectangle());
  305. g.DrawString(_MenuTitle, _TitleFont, new SolidBrush(Color.White), TitleRect);
  306. //EntireSizeRect = new RectangleF(EntireSizeRect.Left - 20, EntireSizeRect.Top - 20, EntireSizeRect.Width + 20, EntireSizeRect.Height + 20);
  307. float currx = EntireSizeRect.Left;
  308. float currY = EntireSizeRect.Top;
  309. //go through each one and draw it.
  310. float selectedY = 0;
  311. MenuModeMenuItem selecteditemuse = null;
  312. foreach (var loopitem in items)
  313. {
  314. var loopiheight = loopitem.MeasureItem();
  315. //defer drawing if selected item for last... save info when we encounter it, and then use that info after the loop.
  316. loopitem.Selected = loopitem == SelectedItem;
  317. {
  318. if (loopitem.Selected)
  319. {
  320. selectedY = currY;
  321. selecteditemuse = loopitem;
  322. }
  323. else
  324. {
  325. loopitem.Draw(g,
  326. new RectangleF(new PointF(currx, currY),
  327. new SizeF(maxwidth, loopiheight.Height)));
  328. }
  329. currY += loopiheight.Height;
  330. }
  331. }
  332. //draw the selected item...
  333. if (selecteditemuse != null)
  334. {
  335. selecteditemuse.Draw(g,new RectangleF(new PointF(currx,selectedY),new SizeF(maxwidth,selecteditemuse.MeasureItem().Height)));
  336. }
  337. }
  338. public MenuModeData(String[] MenuItems,MenuModeMenuItem.MenuItemEvent SelectEvent,MenuModeMenuItem.MenuItemEvent UnselectEvent,MenuModeMenuItem.MenuItemEvent ChosenEvent,MenuModeMenuItem.MenuItemPrePaintEvent prepaint )
  339. {
  340. //constructor that accepts a bunch of strings, and the event assignments.
  341. foreach (String loopit in MenuItems)
  342. {
  343. var itemadd = new MenuModeMenuItem(loopit, MenuAction);
  344. itemadd.MenuItemSelect += SelectEvent;
  345. itemadd.MenuItemUnselect += UnselectEvent;
  346. itemadd.MenuItemChosen += ChosenEvent;
  347. itemadd.MenuItemPrePaint += prepaint;
  348. items.AddLast(itemadd);
  349. }
  350. }
  351. }
  352. private String GameOverHiScores = "";
  353. private DateTime lastscoreshow;
  354. private int Nextshowhiscore = 1; //next hi score to be shown by the "Game Over" screen...
  355. private Graphics pcgraph;
  356. //private Image GameAreaImage; //used during level complete tally...
  357. private Bitmap BackBufferBitmap;
  358. private Graphics backBufferCanvas;
  359. private List<String> RecentCheats = new List<string>();
  360. private int currentcheatsel = 0; //<<index into the list of the currently "selected" cheat; only really valid for a single
  361. private int currentcheatcharpos = 0; //position within cheat string, will be changable via arrow keys, home, end, etc.
  362. //"session" of the cheat "window".
  363. public bool DemoMode=false; //if true, refuses player interactions.
  364. public struct Tallyscreendata
  365. {
  366. public String TallyScreenString;
  367. public Image TallyImage;
  368. }
  369. private MenuModeData menudata;
  370. private Tallyscreendata tallydata;
  371. private IGameState statebeforepause;
  372. public Rectangle AvailableClientArea = new Rectangle(0, 0, 493, 427); //default client area. the HUD is drawn to the right this.
  373. private IGameState _gamerunstate = new StateNotRunning();
  374. public IGameState gamerunstate { get {
  375. return _gamerunstate; }
  376. set {
  377. _gamerunstate = value; Debug.Print("Game run state set to " + value.GetType().Name +" Stack:" + new StackTrace().ToString());
  378. }
  379. }
  380. public Thread GameThread=null;
  381. public Random mrandom = BCBlockGameState.rgen;
  382. public int mScoreatlevelstart = 0;
  383. public TimeSpan mLevelTime;
  384. public int LevelDeathCount = 0;
  385. public DateTime mLevelIntroStartTime;
  386. public TimeSpan mLevelParTime;
  387. public BCBlockGameState mGameState;
  388. public LevelSet mPlayingSet;
  389. public int mPlayingLevel;
  390. private Queue<PlayMessageData> LevelMessageQueue = null;
  391. public bool ShowDebugInfo=false;
  392. public LevelSet GetPlayingSet()
  393. {
  394. return mPlayingSet;
  395. }
  396. public static void SuspendDrawing(Control parent)
  397. {
  398. parent.Invoke((MethodInvoker)(()=>SendMessage(parent.Handle, WM_SETREDRAW, false, 0)));
  399. }
  400. public static void ResumeDrawing(Control parent)
  401. {
  402. parent.Invoke((MethodInvoker)(() => SendMessage(parent.Handle, WM_SETREDRAW, true, 0)));
  403. //parent.Refresh();
  404. }
  405. public Level mPlayingLevelobj
  406. {
  407. get
  408. {
  409. return mPlayingSet.Levels[mPlayingLevel - 1];
  410. }
  411. }
  412. //draws in several layers
  413. //the background layer...
  414. private Bitmap backgroundbitmap;
  415. private Graphics BackgroundBuffer;
  416. private Random mRandom = new Random();
  417. //and the "block" layer...
  418. private Bitmap BlockDrawBitmap;
  419. private Graphics BlockDrawBuffer;
  420. private bool sidebarbgdrawn=false;
  421. //decided that the moving blocks will be on a separate layer from the standard blocks.
  422. private Bitmap MovingBlockBitmap;
  423. private Graphics MovingBlockBuffer;
  424. private Bitmap SidebarBitmap;
  425. private Graphics sidebarGraphics;
  426. private Image SidebarImage;
  427. //private Bitmap backgroundpic = new Bitmap("D:\\banner2.png");
  428. private int drawbackgroundoffset = 0;
  429. /// <summary>
  430. /// set in GameProc and queried in the Paint() routine to determine wether nonanimated blocks need to be redrawn.
  431. /// </summary>
  432. private bool mredrawblocks=true;
  433. /// <summary>
  434. /// set in GameProc and queried in the Paint() routine to determine wether nonanimated blocks need to be redrawn.
  435. /// </summary>
  436. ///
  437. ///<summary>
  438. ///also set in GameProc for consumption in the paint() routine; previously I was performing the LINQ to create this (the blocks that return true for "requiresPerformFrame" were in one, ones that returned false in another).
  439. ///although I don't know how LINQ is implemented internally I hazard a guess and say that repetition is not a good thing, so I graduated
  440. ///some collections to form-level locals.
  441. /// </summary>
  442. private List<Block> staticblocks;
  443. private List<Block> AnimatedBlocks;
  444. private bool mRedrawAnimated=true;
  445. private bool gamethreadsuspended=false;
  446. private int gamepauseamount=0;
  447. //the ball and paddle are drawn to the Picturebox graphics object in the Paint routine.
  448. private Color getrandomcolor()
  449. {
  450. Func<int> randomint = new Func<int>(()=>((int)(mrandom.NextDouble()*255)));
  451. return Color.FromArgb(randomint(),randomint(),randomint(),randomint());
  452. }
  453. public void ReplaceBlocks(Func<Block, Block> replacefunc)
  454. {
  455. LinkedList<Block> newblocks = new LinkedList<Block>();
  456. Block createdblock;
  457. foreach (Block loopblock in mGameState.Blocks)
  458. {
  459. if (!loopblock.BlockRectangle.IsEmpty)
  460. {
  461. createdblock = replacefunc(loopblock);
  462. createdblock.BlockTriggers = loopblock.BlockTriggers;
  463. createdblock.BlockEvents = loopblock.BlockEvents;
  464. foreach (BlockTrigger bt in createdblock.BlockTriggers)
  465. {
  466. bt.OwnerBlock = createdblock;
  467. }
  468. foreach (BlockEvent be in createdblock.BlockEvents)
  469. {
  470. be.OwnerBlock = createdblock;
  471. }
  472. if (createdblock != null)
  473. newblocks.AddLast(createdblock);
  474. }
  475. }
  476. mGameState.Blocks.Clear();
  477. mGameState.Blocks.AddRangeAfter(newblocks);
  478. staticblocks = (from bsel in mGameState.Blocks where !bsel.RequiresPerformFrame() select bsel).ToList();
  479. AnimatedBlocks = (from bsel in mGameState.Blocks where bsel.RequiresPerformFrame() select bsel).ToList();
  480. mredrawblocks = true;
  481. mRedrawAnimated = true;
  482. //invoke redraw
  483. PicGame.Invoke((MethodInvoker)(() => PicGame.Invalidate()));
  484. }
  485. public void UpdateBlocks()
  486. {
  487. staticblocks = (from bsel in mGameState.Blocks where !bsel.RequiresPerformFrame() select bsel).ToList();
  488. AnimatedBlocks = (from bsel in mGameState.Blocks where bsel.RequiresPerformFrame() select bsel).ToList();
  489. mredrawblocks = true;
  490. mRedrawAnimated = true;
  491. }
  492. public static int ScoreRevealDelayTime = 500;
  493. private Color RandomColor()
  494. {
  495. return Color.FromArgb((int)(mrandom.NextDouble() * 128 + 128), (int)(mrandom.NextDouble() * 255), (int)(mrandom.NextDouble() * 255), (int)(mrandom.NextDouble() * 255));
  496. }
  497. private LevelSet CreateDefaultLevelSet()
  498. {
  499. iLevelSetBuilder defaultbuilder = new DefaultLevelBuilder();
  500. LevelSet returnset = defaultbuilder.BuildLevelSet(AvailableClientArea,this);
  501. //returnset.Save(@"D:\textoutxaml.xaml");
  502. return returnset;
  503. }
  504. private Level CreateDefaultLeveltestray(int levelnumber)
  505. {
  506. Level returnlevel = new Level();
  507. //returnlevel.levelballs.Add(new cBall(new PointF(PicGame.ClientSize.Width / 2, PicGame.ClientSize.Height - 50), new PointF(-2f, -2f)));
  508. returnlevel.LevelName = "Level " + levelnumber.ToString();
  509. returnlevel.MusicName = "ENDLESSCHALLENGE";
  510. returnlevel.levelballs.Add(new cBall(new PointF(30, 30), new PointF(2, 2)));
  511. /*
  512. for (int i = 0; i < PicGame.Width; i += 32)
  513. {
  514. returnlevel.levelblocks.Add(new RayBlock(new RectangleF(i, 50, 32, 16)));
  515. }
  516. */
  517. //returnlevel.levelblocks.Add(new RayBlock(new RectangleF(0,2,PicGame.Width,32)));
  518. for (int i = 0; i < PicGame.Width / 2; i += 32)
  519. {
  520. returnlevel.levelblocks.Add(new BoundedMovingBlock(new RayBlock(new RectangleF(PicGame.Width/2-(i/2), i, 32, 16)),
  521. new PointF(2 + (float)(mRandom.NextDouble() * 3), 0)));
  522. returnlevel.levelblocks.Add(new BoundedMovingBlock(new RayBlock(new RectangleF(PicGame.Width / 2 + (i / 2), i, 32, 16)),
  523. new PointF(2+ (float)(mRandom.NextDouble()*3), 0)));
  524. }
  525. returnlevel.levelblocks.Add(new NormalBlock(new RectangleF(PicGame.Width/2,5,32,16),new SolidBrush(Color.Red),new Pen(Color.Yellow)));
  526. return returnlevel;
  527. }
  528. private BCBlockGameState InitGameState(LevelSet useset, int startlevel)
  529. {
  530. BCBlockGameState newstate = new BCBlockGameState(this,PicGame,AvailableClientArea);
  531. BCBlockGameState.MainGameState = newstate;
  532. if(useset.Levels.Count < startlevel)
  533. throw new ArgumentException("Specified Level, " + startlevel.ToString() + " not found in given levelset, which contains " + useset.Levels.Count.ToString() + " Levels.");
  534. Level levelcopy = useset.Levels[startlevel-1];
  535. foreach(cBall levelball in levelcopy.levelballs)
  536. {
  537. newstate.Balls.AddLast(new cBall(levelball));
  538. }
  539. //newstate.Balls.Add(new cBall(newstate,new PointF(PicGame.ClientSize.Width/2,PicGame.ClientSize.Height-50),new PointF(-4f,-4f)));
  540. newstate.OnBallHitBottom += new BCBlockGameState.BallHitBottomProcedure(newstate_OnBallHitBottom);
  541. foreach(Block levelblock in levelcopy.levelblocks)
  542. {
  543. newstate.Blocks.AddLast((Block)levelblock.Clone());
  544. }
  545. /*
  546. for (int x = 0; x < PicGame.Width; x += 32)
  547. {
  548. for (int y = 0; y < PicGame.Height / 2; y += 16)
  549. {
  550. if (mrandom.NextDouble() > 0.1)
  551. newstate.Blocks.Add(new NormalBlock(newstate, new RectangleF(x, y, 32, 16), new SolidBrush(RandomColor()), new Pen(Color.Black, 1)));
  552. else
  553. newstate.Blocks.Add(new BombBlock(newstate, new RectangleF(x, y, 32, 16)));
  554. }
  555. }
  556. * */
  557. return newstate;
  558. }
  559. private PointF MidPoint(RectangleF ofrect)
  560. {
  561. return new PointF(ofrect.Left + (ofrect.Width / 2), ofrect.Top + (ofrect.Height / 2));
  562. }
  563. private IEnumerable<RectangleF> BlocksFromMatrix(int[][] Matrixuse)
  564. {
  565. //15/26, also zero.
  566. float usewidth = AvailableClientArea.Width / Matrixuse[0].Length;
  567. float useheight = AvailableClientArea.Height / Matrixuse.Length;
  568. for (int x = 0; x < Matrixuse.Length; x++)
  569. {
  570. for (int y = 0; y < Matrixuse[x].Length; y++)
  571. {
  572. //if it is a black pixel..
  573. if (Matrixuse[x][y]==1)
  574. {
  575. //add a new rectangle...
  576. yield return new RectangleF(y*usewidth,x*useheight,usewidth,useheight);
  577. }
  578. }
  579. }
  580. }
  581. private LevelSet CreateGameOverSet()
  582. {
  583. LevelSet returnset = new LevelSet();
  584. for (int i = 0; i < mPlayingSet.Levels.Count; i++)
  585. {
  586. Level golevel = new Level();
  587. golevel.levelballs.Add(new cBall(new PointF(15, 15), new PointF(2, 2)));
  588. golevel.SidebarTextColor = Color.Black;
  589. //now, we add the blocks.
  590. //a square of blocks, 10 blocks wide and 15 blocks high, centered around the middle.
  591. SizeF middleblocksize = new SizeF(32*10, 16*15);
  592. RectangleF middlecentered = GetCenteredRect(middleblocksize, AvailableClientArea);
  593. GraphicsPath usepath = new GraphicsPath();
  594. IEnumerable<RectangleF> userects = BlocksFromMatrix(GameOverMatrix); //known to work
  595. foreach (RectangleF createblockrect in userects)
  596. {
  597. Block addthisblock;
  598. if (BCBlockGameState.rgen.NextDouble() > 0.1f)
  599. addthisblock = new InvincibleBlock(createblockrect);
  600. else
  601. {
  602. addthisblock = new NormalBlock(createblockrect);
  603. }
  604. golevel.levelblocks.Add(addthisblock);
  605. }
  606. golevel.levelblocks.Add(new NormalBlock(new RectangleF(-300, -300, 32, 16)));
  607. //add the top line...
  608. /* for (int x = 0; x < middleblocksize.Width; x += 32)
  609. {
  610. Block newblock = new InvincibleBlock(new RectangleF(middlecentered.Left + x, middlecentered.Top, 32, 16));
  611. golevel.levelblocks.Add(newblock);
  612. }
  613. //add the line on the left...
  614. for (int y = 16; y < middleblocksize.Height; y += 16)
  615. {
  616. Block newblock = new InvincibleBlock(new RectangleF(middlecentered.Left, middlecentered.Top + y, 32, 16));
  617. golevel.levelblocks.Add(newblock);
  618. }
  619. */
  620. returnset.Levels.Add(golevel);
  621. }
  622. return returnset;
  623. }
  624. bool HiscoreCheck()
  625. {
  626. String PlayerName = BCBlockGameState.Settings.PlayerName;
  627. int position = 0;
  628. // gamethread should be aborted. If it isn't- we do it.
  629. if ((GameThread!=null) && (GameThread.IsAlive) && GameThread != Thread.CurrentThread)
  630. {
  631. //abort it.
  632. GameThread.Abort();
  633. GameThread=null;
  634. }
  635. if ((position = mPlayingSet.HighScores.Eligible(PlayerName,(int)mGameState.GameScore)) > 0)
  636. {
  637. //score made! woop!
  638. HighScoreEntryMode(position,PlayerName);
  639. return true;
  640. }
  641. return false;
  642. }
  643. void GameOver()
  644. {
  645. if (GameThread != null && GameThread!=Thread.CurrentThread)
  646. GameThread.Abort();
  647. bool gotscore=false;
  648. BCBlockGameState.Soundman.StopMusic();
  649. //TODO: here is where we would "submit" the score to the HighScore management system... but ONLY if demo mode is off!
  650. //create the game over level.
  651. if (DemoMode == false)
  652. {
  653. gotscore=HiscoreCheck();
  654. }
  655. //if they didn't get a hi score, forcegameover().... otherwise, game over will be called after they enter their name.
  656. if(!gotscore) forcegameover();
  657. }
  658. private int HighScoreNamesMaxLength = 0;
  659. private int HighScoreScoresMaxLength = 0;
  660. private int HighScoresMaxSeparators = 0;
  661. private LevelSet restartset = null;
  662. private void forcegameover()
  663. {
  664. gamerunstate = new StateLevelOutroGameOver();
  665. LevelSet mGoverSet = CreateGameOverSet();
  666. DemoMode = true;
  667. ActualPlaySet = mPlayingSet;
  668. Nextshowhiscore = 0;
  669. GameOverHiScores = "Top - " + ActualPlaySet.SetName;
  670. //calculate maximum length of names and scores.
  671. HighScoreNamesMaxLength = Math.Min(ActualPlaySet.HighScores.GetScores().Max((w) => w.Name.Length),20);
  672. HighScoreScoresMaxLength = ActualPlaySet.HighScores.GetScores().Max((w) => w.Score.ToString().Length);
  673. HighScoresMaxSeparators= Math.Max(HighScoreNamesMaxLength+1,9);
  674. //cache the current set...
  675. restartset = mPlayingSet;
  676. tallydata.TallyImage = BCBlockGameState.Imageman.getImageRandom(mPlayingLevelobj.GameOverPicKey);
  677. PlayLevel(mGameState, mGoverSet.Levels[0]);
  678. gamerunstate = new StateLevelOutroGameOver();
  679. }
  680. protected iActiveSoundObject ds;
  681. private void ExplodePaddle()
  682. {
  683. if(mGameState.PlayerPaddle==null) return;
  684. Random rg = BCBlockGameState.rgen;
  685. Rectangle paddlerect = mGameState.PlayerPaddle.Getrect();
  686. for (int i = 0; i < 120; i++)
  687. {
  688. //todo: fix so this isn't called repeatedly because there is a ball outside...
  689. //(add another ball somewhere else, invisible, maybe?)
  690. int minvalue = Math.Min(paddlerect.Left, paddlerect.Right);
  691. int maxvalue = Math.Max(paddlerect.Left, paddlerect.Right);
  692. Point randomspot = new Point(rg.Next(minvalue, maxvalue), rg.Next(paddlerect.Top, paddlerect.Bottom));
  693. PointF rspot = randomspot.ToPointF();
  694. Particle dp = null;
  695. //Type[] particletypes = new Type[] { typeof(DustParticle),typeof(FireParticle),typeof(PolyDebris)};
  696. int rnum = rg.Next(1, 3);
  697. if (rnum == 1)
  698. dp = new DustParticle(rspot);
  699. else
  700. {
  701. PolyDebris pd = new PolyDebris(rspot, (rg.NextDouble()*4)-2, Color.YellowGreen);
  702. pd.PenColor=Color.YellowGreen;
  703. pd.BrushColor=Color.YellowGreen;
  704. dp = pd;
  705. }
  706. mGameState.Particles.Add(dp);
  707. }
  708. //use Level death sound...
  709. //BCBlockGameState.Soundman.SetMusicVolume(0.0f);
  710. BCBlockGameState.Soundman.PauseMusic(true);
  711. BCBlockGameState.Soundman.Driver.OnSoundStop += new OnSoundStopDelegate(DeathMusicStop);
  712. ds = BCBlockGameState.Soundman.PlaySound(mPlayingLevelobj.DeathSound);
  713. mGameState.PlayerPaddle.InvokeOnDeath();
  714. mGameState.PlayerPaddle = null;
  715. }
  716. void DeathMusicStop(iActiveSoundObject objstop)
  717. {
  718. if (objstop == ds)
  719. {
  720. //remove this method...
  721. BCBlockGameState.Soundman.Driver.OnSoundStop -= DeathMusicStop;
  722. //reset the volume, too.
  723. try
  724. {
  725. BCBlockGameState.Soundman.PauseMusic(false); //unpause...
  726. //BCBlockGameState.Soundman.GetPlayingMusic_Active().setVolume(1.0f);
  727. }
  728. catch
  729. {
  730. //ignored...
  731. }
  732. }
  733. }
  734. private DateTime DeathStart;
  735. void LifeLost()
  736. {
  737. //we cant lose a life if we are already "dying"
  738. Dorefreshstats = true;
  739. if(gamerunstate is StateDeath) return;
  740. //change state to be death, and put a bunch of explodey particles all over.
  741. if (mGameState.PlayerPaddle != null)
  742. {
  743. Rectangle paddlerect = mGameState.PlayerPaddle.Getrect();
  744. /* foreach (cBall createball in mGameState.Balls)
  745. {
  746. createball.Velocity = new PointF(0, 0);
  747. createball.Location = new PointF(-50, paddlerect.Bottom);
  748. createball.Radius = 05f;
  749. createball.DrawColor = Color.Blue;
  750. }
  751. */
  752. LevelDeathCount++;
  753. //cut macguffins in half and explode from the paddle.
  754. mGameState.MacGuffins /= 2;
  755. PointF SpawnGuffLocation = new PointF((float)mGameState.PlayerPaddle.Getrect().CenterPoint().X, mGameState.PlayerPaddle.Getrect().Top - 16);
  756. for (int i = 0; i < mGameState.MacGuffins; i++)
  757. {
  758. //choose a random velocity. between PI and PI*2; this will be upwards-only.
  759. double useangle = Math.PI + (BCBlockGameState.rgen.NextDouble()*Math.PI);
  760. PointF RandomSpeed = BCBlockGameState.GetRandomVelocity(3, 5, useangle);
  761. MacGuffinOrb mgo = new MacGuffinOrb(SpawnGuffLocation);
  762. mgo.MacGuffinValue = BCBlockGameState.rgen.Next(0, 6);
  763. mgo.Velocity = RandomSpeed;
  764. mGameState.GameObjects.AddLast(mgo);
  765. }
  766. ExplodePaddle();
  767. }
  768. //remove all gamecharacter objects.
  769. List<GameCharacter> removethese = new List<GameCharacter>(from m in mGameState.GameObjects where m is GameCharacter select (GameCharacter)m);
  770. foreach (GameCharacter gchar in removethese)
  771. {
  772. mGameState.GameObjects.Remove(gchar);
  773. }
  774. gamerunstate = new StateDeath();
  775. DeathStart=DateTime.Now;
  776. }
  777. void PostLifeLost()
  778. {
  779. Dorefreshstats = true;
  780. if (mPlayingSet != null)
  781. {
  782. mPlayingSet.Statistics.Deaths++;
  783. }
  784. mGameState.playerLives--;
  785. //lblLives.Invoke(((MethodInvoker)(() => lblLives.Text = mGameState.playerLives.ToString())));
  786. gamethreadsuspended = true;
  787. //Thread.Sleep(500);
  788. gamethreadsuspended = false;
  789. gamerunstate = new StateRunning();
  790. if (mGameState.playerLives <= 0)
  791. {
  792. GameOver();
  793. }
  794. else
  795. {
  796. //reinitialize the balls from the "stored" levelset...
  797. if (mGameState.PlayerPaddle != null)
  798. {
  799. lock (mGameState.PlayerPaddle) //lock it to prevent race condition.
  800. {
  801. //added June 24th 2011- Destroy() routine needs to be called when reinstantiating the paddle, otherwise
  802. //the "old" paddle, and it's behaviours, will still have active hooks to any events they hooked.
  803. foreach (var loopbeh in mGameState.PlayerPaddle.Behaviours)
  804. {
  805. loopbeh.UnHook();
  806. }
  807. mGameState.PlayerPaddle.Behaviours.Clear();
  808. }
  809. }
  810. mGameState.PlayerPaddle = new Paddle(mGameState, new Size(48, 15), new PointF(mGameState.GameArea.Width / 2, mGameState.TargetObject.Height - 35), BCBlockGameState.Imageman.getLoadedImage("paddle"));
  811. mGameState.PlayerPaddle.OnHPChange+=PlayerPaddle_OnHPChange;
  812. mGameState.PlayerPaddle.OnEnergyChange +=PlayerPaddle_OnEnergyChange;
  813. foreach (cBall loopball in mPlayingSet.Levels[mPlayingLevel - 1].levelballs)
  814. {
  815. mGameState.Balls.AddLast((cBall)loopball.Clone());
  816. }
  817. //iterate through the levels blocks as well and see which ones we need to respawn...
  818. foreach (Block iterateblock in mPlayingSet.Levels[mPlayingLevel - 1].levelblocks)
  819. {
  820. if (iterateblock.AutoRespawn)
  821. {
  822. mGameState.Blocks.AddLast((Block)iterateblock.Clone());
  823. }
  824. }
  825. }
  826. }
  827. public void ForceDeath()
  828. {
  829. LifeLost();
  830. }
  831. void newstate_OnBallHitBottom(cBall ball)
  832. {
  833. }
  834. private Bitmap IntroSequenceBitmap;
  835. private Graphics IntroSequenceGraphic;
  836. public float CurrentFPS { get; set; }
  837. public void PlayLevel(BCBlockGameState stateobject, Level playthislevel)
  838. {
  839. Debug.Print("PlayLevel Entered...");
  840. //first, terminate the game thread, if it is running...
  841. bool ongamethread = (GameThread == Thread.CurrentThread);
  842. if (GameThread != null && GameThread != Thread.CurrentThread)
  843. {
  844. Debug.Print("GameThread is running; Aborting...");
  845. GameThread.Abort();
  846. }
  847. Debug.Print("Stopping playing music...");
  848. BCBlockGameState.Soundman.StopMusic();
  849. //next, we copy the balls and blocks from playthislevel...
  850. //clear any existing balls or blocks...
  851. //stateobject.Balls.Clear();
  852. //stateobject.Blocks.Clear();
  853. Debug.Print("Clearing current game state variables...");
  854. stateobject.GameObjects.Clear();
  855. stateobject.Particles.Clear();
  856. stateobject.Balls = new LinkedList<cBall>();
  857. stateobject.Blocks = new LinkedList<Block>();
  858. stateobject.RemoveBalls.Clear();
  859. Debug.Print("Cloning level data to current state...");
  860. foreach (cBall copyball in playthislevel.levelballs)
  861. {
  862. stateobject.Balls.AddLast((cBall) copyball.Clone());
  863. }
  864. foreach (Block copyblock in playthislevel.levelblocks)
  865. {
  866. stateobject.Blocks.AddLast((Block) copyblock.Clone());
  867. }
  868. if (stateobject.PlayerPaddle != null)
  869. {
  870. lock (stateobject.PlayerPaddle) //lock it to prevent race condition.
  871. {
  872. //added June 24th 2011- Destroy() routine needs to be called when reinstantiating the paddle, otherwise
  873. //the "old" paddle, and it's behaviours, will still have active hooks to any events they hooked.
  874. foreach (var loopbeh in stateobject.PlayerPaddle.Behaviours)
  875. {
  876. loopbeh.UnHook();
  877. }
  878. stateobject.PlayerPaddle.Behaviours.Clear();
  879. }
  880. stateobject.PlayerPaddle.OnHPChange += PlayerPaddle_OnHPChange;
  881. stateobject.PlayerPaddle.OnEnergyChange += PlayerPaddle_OnEnergyChange;
  882. }
  883. //LevelMessageQueue = new Queue<PlayMessageData>(playthislevel.MessageQueue.Clone());
  884. LevelMessageQueue = playthislevel.CreateMessageQueue();
  885. Debug.Print("Level contains " + stateobject.Balls.Count.ToString() + " balls and " +
  886. stateobject.Blocks.Count.ToString() + " blocks.");
  887. Debug.Print("Playing level music...");
  888. PlayLevelMusic(playthislevel, true);
  889. //change sidebarimage if the Level has one to use.
  890. //the sidebarimage in the Level will be a key. if it's not null or empty, load the Image from the Image manager.
  891. SideBarImageCanvas = null; //nullify so PaintSideBarStats will redraw it.
  892. if (!String.IsNullOrEmpty(playthislevel.SidebarImageKey))
  893. {
  894. SidebarImage = BCBlockGameState.Imageman.getLoadedImage(playthislevel.SidebarImageKey);
  895. }
  896. else
  897. {
  898. SidebarImage = BCBlockGameState.Imageman.getLoadedImage("sidebarbg");
  899. }
  900. //create the bitmap of the introduction text.
  901. #region create introduction bitmap
  902. Debug.Print("Creating Intro sequence bitmap...");
  903. //mGameState.BackgroundDraw = new BackgroundColourImageDrawer(playthislevel);
  904. mGameState.PlayingLevel = playthislevel;
  905. mGameState.BackgroundDraw=playthislevel.Background;
  906. //CreateIntroBitmap(playthislevel, out IntroSequenceBitmap, out IntroSequenceGraphic);
  907. playthislevel.CreateIntroBitmap(out IntroSequenceBitmap, out IntroSequenceGraphic);
  908. #endregion
  909. //initialize textanimator.
  910. //IntroAnimator = new TextAnimationManager(playthislevel.LevelName, getLinearCharAnimator,new PointF(AvailableClientArea.Width/2,AvailableClientArea.Height/2 ));
  911. if (playthislevel.NoPaddle)
  912. {
  913. mGameState.PlayerPaddle=null;
  914. }
  915. Dorefreshstats = true;
  916. gamerunstate = new StateLevelIntro();
  917. mScoreatlevelstart = (int)mGameState.GameScore;
  918. mLevelParTime = playthislevel.CalculateParTime();
  919. mLevelIntroStartTime = DateTime.Now;
  920. mLevelTime = new TimeSpan(0);
  921. LevelDeathCount = 0;
  922. mRedrawAnimated=true;
  923. mredrawblocks=true;
  924. //initialize the AnimatedBlocks and StaticBlocks collections, otherwise we still won't
  925. //get them to draw.
  926. staticblocks = (from n in mGameState.Blocks where !n.RequiresPerformFrame() select n).ToList();
  927. AnimatedBlocks = (from n in mGameState.Blocks where n.RequiresPerformFrame() select n).ToList();
  928. if (!ongamethread)
  929. {
  930. Debug.Print("Not on game thread, creating new gamethread...");
  931. GameThread = new Thread(gameproc);
  932. GameThread.Start();
  933. }

Large files files are truncated, but you can click here to view the full file