source: 2013/27/ArttuY/trunk/RampageRebellion/RampageRebellion/RampageRebellion/RREnemySpawner.cs @ 4451

Revision 4451, 9.2 KB checked in by eearyla, 7 years ago (diff)

Backup

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Xml;
6using System.IO;
7using System.Threading;
8using System.Diagnostics;
9using Jypeli;
10using Jypeli.Assets;
11using Jypeli.Controls;
12using Jypeli.Effects;
13using Jypeli.Widgets;
14
15/* Teemun TODO
16 * - Arcade Mode: high score
17 * - Upgrades: AYS
18 * - Enemy AI
19 * - Multiplier function?: -THR
20 * - Common enemy framework
21 * - Arcade/Campaign selector: -JAKE
22 * - Actual level design: -THR
23 */
24public class RREnemySpawner
25{
26    public RREnemySpawner()
27    {
28    }
29
30    public void arcade()
31    {
32        Stopwatch stopwatch = new Stopwatch();
33        stopwatch.Start();
34
35        double multiplier = 1.0;
36
37        RampageRebellion game = RampageRebellion.getGame();
38        Jypeli.Timer t = new Jypeli.Timer();
39        t.Interval = 1.0;
40
41        t.Timeout += delegate {
42            // The multiplier function
43            multiplier = (Math.Pow(1.1, (double)stopwatch.ElapsedMilliseconds / 10000));
44            Console.WriteLine(multiplier);
45            game.Add(new SmallEnemy(inCenteredXCoordinates(RandomGen.NextInt(-300, 300)), 
46                                    inRelativeYCoordinates(RandomGen.NextInt(0, 200), "Small"),
47                                    multiplier));
48            t.Interval = RandomGen.NextDouble(1.0, 2.0);
49        };
50        t.Start();
51    }
52
53    public void levels()
54    {
55        List<RRLevel> levelList = new List<RRLevel>();
56        levelList = loadLevelsFromXML();
57
58        Thread spawnerThread = new Thread(delegate()
59        {
60            executeLevelList(levelList);
61        });
62
63        spawnerThread.IsBackground = true;
64        spawnerThread.Start();
65    }
66
67    private List<RRLevel> loadLevelsFromXML()
68    {
69        // The string to contain the XML data
70        String XMLFile;
71
72        // The type of the enemy to be created
73        String enemyType = "";
74
75        // The coordinates for the enemy
76        double x = 0.0;
77        double y = 0.0;
78
79        List<RRLevel> levelList = new List<RRLevel>();
80
81        // Read the XML data from the file
82        using (StreamReader sr = new StreamReader("Content/levels.xml"))
83        {
84            XMLFile = sr.ReadToEnd();
85        }
86
87        using (XmlReader reader = XmlReader.Create(new StringReader(XMLFile)))
88        {
89            while (reader.ReadToFollowing("level"))
90            {
91                // Creates a new level object to which the waves are added
92                RRLevel currentLevel = new RRLevel();
93
94                // The XMLReader first reads to the first element and then to that element's siblings
95                // This way it doesn't "leak" and read every element in the file
96                reader.ReadToFollowing("wave");
97                do
98                {
99                    reader.ReadToFollowing("enemy");
100                    do
101                    {
102                        reader.MoveToFirstAttribute();      // The type of the enemy (small, medium etc.)
103                        enemyType = reader.Value;
104                        reader.MoveToNextAttribute();       // The x-coordinate
105                        x = Convert.ToDouble(reader.Value);
106                        reader.MoveToNextAttribute();       // The y-coordinate
107                        y = Convert.ToDouble(reader.Value);
108
109                        // In the relative coordinates, the top left corner of the enemy
110                        // is in the top left corner of the screen when (x, y) = (0, 0)
111                        x = inCenteredXCoordinates(x);
112                        y = inRelativeYCoordinates(y, enemyType);
113
114                        // Adds an enemy to the current RRLevel object
115                        if (enemyType == "Small") currentLevel.addEnemy(new SmallEnemy(x, y));
116                        else if (enemyType == "Medium") currentLevel.addEnemy(new MediumEnemy(x, y));
117                        else if (enemyType == "Big") currentLevel.addEnemy(new BigEnemy(x, y));
118                        else if (enemyType == "Boss") currentLevel.addEnemy(new BossEnemy(x, y));
119                        else
120                        {
121                            // Throw an exception, since the type of the enemy is unknown.
122                        }
123
124                    } while (reader.ReadToNextSibling("enemy"));
125
126                    // Notifies the Level object that we're moving to a new wave
127                    currentLevel.initNewWave();
128
129                } while (reader.ReadToNextSibling("wave"));
130
131                // Adds the current Level object to the list of level objects
132                levelList.Add(currentLevel);
133                currentLevel = null;
134            }
135        }
136
137        // Debugging: Reads back the structure
138        /*foreach (RRLevel level in levelList)
139        {
140            Console.WriteLine("Level");
141            level.listAll();
142        }*/
143
144        return levelList;
145    }
146
147    private void executeLevelList(List<RRLevel> levelList)
148    {
149        while (levelList.Count > 0)
150        {
151            while (levelList[0].wavesLeft() > 0)
152            {
153                levelList[0].spawnThisWave();
154
155                // Wait until there are no more enemies, and then spawn the next wave.
156                while (levelList[0].enemiesLeftInCurrentWave() > 0) { Thread.Sleep(1); }
157                levelList[0].removeThisWave();
158
159                // Wait for two seconds before launching the next wave.
160                Thread.Sleep(2000);
161            }
162
163            // Remove the finished level
164            levelList.RemoveAt(0);
165
166            //RampageRebellion.UpgradeScreen();
167        }
168
169        // We're done!
170        RampageRebellion.getGame().GameEnd();
171    }
172
173    // The first correction term gets the enemy's center to the top left screen
174    // and the second term moves the enemy so that it isn't immediately destroyed.
175    private double inRelativeXCoordinates(double originalX, string enemyType)
176    {
177        return originalX - 517 + (getEnemySizeByType(enemyType) / 2);
178    }
179
180    private double inRelativeYCoordinates(double originalY, string enemyType)
181    {
182        return (-originalY) + 485 - (getEnemySizeByType(enemyType) / 2);
183    }
184
185    private double inCenteredXCoordinates(double originalX)
186    {
187        return originalX - 190;
188    }
189    private double getEnemySizeByType(string enemyType)
190    {
191        if (enemyType == "Small") return RampageRebellion.SMALLENEMY_SIZE;
192        else if (enemyType == "Medium") return RampageRebellion.MEDENEMY_SIZE;
193        else if (enemyType == "Big") return RampageRebellion.BIGENEMY_SIZE;
194        else if (enemyType == "Boss") return RampageRebellion.BOSS_SIZE;
195        else return 0; // Shouldn't ever happen!
196    }
197
198    private class RRLevel
199    {
200        private List<RRWave> waveList = new List<RRWave>();
201        private RRWave currentWave = new RRWave();
202
203        public void addEnemy(RREnemy enemy)
204        {
205            currentWave.addEnemy(enemy);
206        }
207
208        // Called when the parser is moving to the next wave, so the current wave should be added to the list
209        public void initNewWave()
210        {
211            waveList.Add(currentWave);
212
213            // Resets the wave
214            currentWave = null;
215            currentWave = new RRWave();
216        }
217
218        public void spawnThisWave()
219        {
220            if (waveList.Count > 0)
221            {
222                waveList[0].spawn();
223            }
224            else
225            {
226                // Throw an exception!
227            }
228        }
229
230        // Mostly for debugging; should use spawnThisWave() instead
231        public void spawnAllWaves()
232        {
233            foreach (RRWave wave in waveList)
234            {
235                wave.spawn();
236            }
237        }
238
239        public int enemiesLeftInCurrentWave()
240        {
241            return waveList[0].enemiesLeft();
242        }
243
244        // Mostly for debugging purposes
245        public void listAll()
246        {
247            foreach (RRWave wave in waveList)
248            {
249                Console.WriteLine("\tWave");
250                wave.listAll();
251            }
252        }
253
254        public int wavesLeft()
255        {
256            return waveList.Count;
257        }
258
259        public void removeThisWave()
260        {
261            waveList.RemoveAt(0);
262        }
263    }
264
265    private class RRWave
266    {
267        private List<RREnemy> enemyList = new List<RREnemy>();
268
269        public void addEnemy(RREnemy enemy)
270        {
271            enemyList.Add(enemy);
272        }
273
274        public void spawn()
275        {
276            RampageRebellion game = RampageRebellion.getGame();
277
278            foreach (RREnemy enemy in enemyList)
279            {
280                game.Add(enemy);
281            }
282        }
283
284        public int enemiesLeft()
285        {
286            // We must manually remove destroyed enemies
287            enemyList.RemoveAll(delegate(RREnemy e)
288            {
289                if (e.IsDestroyed) return true;
290                else return false;
291            });
292            return enemyList.Count;
293        }
294
295        public void listAll()
296        {
297            foreach (RREnemy enemy in enemyList)
298            {
299                Console.WriteLine("\t\tEnemy");
300            }
301        }
302    }
303}
Note: See TracBrowser for help on using the repository browser.