source: 2016/27/ohjaajat/VenienteFragore/VenienteFragore/VenienteFragore/VenienteFragore.cs @ 10335

Revision 8018, 17.4 KB checked in by tesatapa, 3 years ago (diff)

score toimimaan

Line 
1using System;
2using System.Collections.Generic;
3using Jypeli;
4using Jypeli.Assets;
5using Jypeli.Controls;
6using Jypeli.Effects;
7using Jypeli.Widgets;
8using System.Linq;
9
10namespace VenienteFragore
11{
12    public partial class VenienteFragore : SimplePhysics.Game
13    {
14        private delegate void ObjectMethod(Vector position, double width, double height, Dictionary<string, string> properties);
15        private Dictionary<string, ObjectMethod> objectMethods;
16
17        private readonly Image platformImage = LoadImage("platform");
18        private readonly Image dripImage = LoadImage("drip");
19        private readonly Image[] minimiiniiImages = LoadImages("minimiiniianim\\minimiiniianim", 1, 4);
20        private readonly Image[] minimiinii2Images = LoadImages("minimiinii2anim\\anim", 1, 4);
21        private readonly Image[] advenaImages = LoadImages("advenawalk\\advenawalk00", 1, 49, true);
22        private readonly Image[] advenbImages = LoadImages("advenbwalk\\advenb00", 1, 49, true);
23        private readonly string[] songNames = { "DST-IceStar", "DST-HollowBreath", "DST-PhaserSwitch", "DST-Kronos" };
24
25        private readonly Image[] advenaLiftImages = LoadImages("advenaliftingwalk\\advenaliftingwalk00", 1, 49, true);
26        private readonly Image[] advenbLiftImages = LoadImages("advenbliftingwalk\\advenbliftingwalk00", 1, 49, true);
27
28        private readonly Image advenaBlob = LoadImage("advenaBlob");
29        private readonly Image advenbBlob = LoadImage("advenbBlob");
30       
31        private readonly Image advenaCrouch = LoadImage("advenacrouch");
32        private readonly Image advenbCrouch = LoadImage("advenbcrouch");
33
34
35        // Lista kenttien nimistä, joista aluksen osa on kerätty.
36        private string currentLevelName;
37        private readonly List<string> collectedParts = new List<string>();
38        private IntMeter lives;
39        private IntMeter pointsCounter;
40
41        private List<Player> advenae;
42        private Vector respawnPoint;
43
44        private Vector cameraSpeed = new Vector(2.0, 4.0);
45        private Vector cameraTarget;
46
47        private SimplePhysics.Object borderleft;
48        private SimplePhysics.Object borderright;
49
50        public VenienteFragore() : base(tileSize: 50)
51        {
52        }
53
54        public override void Begin()
55        {
56            MediaPlayer.Volume = 0.35;
57            MediaPlayer.IsRepeating = true;
58            MediaPlayer.Play("DST-OrganicSpace");
59
60            IsMouseVisible = true;
61            Level.Background.CreateGradient(Color.DarkBlue, Color.Black);
62
63            Label title = new Label(Screen.Width * 0.65, Screen.Height *0.25);
64            title.Position = new Vector(0, Screen.Top - Screen.Height * 0.15);
65            title.Text = "Veniente Fragore";
66            title.TextScale = new Vector(Screen.Width * 0.004, Screen.Height * 0.003);
67            title.TextColor = new Color(50, 25, 100);
68            title.HorizontalAlignment = HorizontalAlignment.Left;
69            Add(title);
70
71            PushButton start = new PushButton(Screen.Width * 0.15, Screen.Height * 0.1);
72            start.Position = new Vector(0, Screen.Top - Screen.Height * 0.45);
73            start.Text = "Start game";
74            start.Color = Color.DarkBlue;
75            start.Clicked += StartGame;
76
77            Add(start);
78
79            PushButton exit = new PushButton(Screen.Width * 0.15, Screen.Height * 0.1);
80            exit.Position = new Vector(0, Screen.Top - Screen.Height * 0.65);
81            exit.Text = "Exit";
82            exit.Color = Color.DarkBlue;
83            exit.Clicked += Exit;
84
85            Add(exit);
86            Keyboard.Listen(Key.Enter, ButtonState.Pressed, StartGame, null);
87            Keyboard.Listen(Key.Space, ButtonState.Pressed, StartGame, null);
88
89            Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, null);
90
91            Label credits = new Label(@"Music by DST: http://dreade.com/nosoap/");
92            credits.Position = new Vector(0, Screen.Top - Screen.Height * 0.9);
93            Add(credits);
94
95
96        }
97
98
99        private void StartGame()
100        {
101            ClearAll();
102
103            MediaPlayer.Play(RandomGen.SelectOne(songNames));
104
105            IsMouseVisible = false;
106            lives = new IntMeter(6, 0, 99);
107
108
109            pointsCounter = new IntMeter(0);
110            pointsCounter.Changed += PointsGained;
111
112            StartLevel("desolatecaves");
113       
114
115            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
116        }
117
118        private void PointsGained(int oldValue, int newValue)
119        {
120            double diff = newValue - oldValue;
121            if(((int)oldValue) / 10000 < ((int)newValue / 10000))
122                {
123                lives.Value++;
124            }
125        }
126
127        private void CreateGUI()
128        {
129            Label liveMeter = new Label(Screen.Width * 0.10, Screen.Height * 0.05);
130            liveMeter.Position = new Vector(Screen.Left + Screen.Width * 0.165, Screen.Top - Screen.Height * 0.1);
131            liveMeter.BindTo(lives);
132            liveMeter.HorizontalAlignment = HorizontalAlignment.Center;
133            Add(liveMeter);
134
135            Label border = new Label(Screen.Width * 0.1, Screen.Height * 0.05);
136            border.Position = new Vector(Screen.Left + Screen.Width * 0.15, Screen.Top - Screen.Height * 0.1);
137            border.BorderColor = Color.Gold;
138            Add(border);
139
140            Label face = new Label(Screen.Width * 0.035, Screen.Width * 0.05);
141            face.Image = advenaImages[0];
142            face.Position = new Vector(Screen.Left + Screen.Width * 0.12, Screen.Top - Screen.Height * 0.1);
143            Add(face);
144
145            Label scoreLabel = new Label(pointsCounter);
146            scoreLabel.X = Screen.Right - 200;
147            scoreLabel.Y = Screen.Top - 100;
148            scoreLabel.IntFormatString = "Score: {0:D7}";
149            Add(scoreLabel);
150        }
151
152        private void GameOver()
153        {
154            advenae.ForEach(x => x.Destroy());
155            ClearAll();
156
157            Level.Background.CreateGradient(Color.Black, new Color(20, 20, 115));
158            Label youLose = new Label(Screen.Width, Screen.Height);
159            youLose.Text = "You lost the game";
160            youLose.TextColor = Color.Red;
161            Add(youLose);
162
163        }
164
165        public double DistanceToNearestPlayer(Vector point)
166        {
167            return advenae.Min(p => Vector.Distance(p.Position, point));
168        }
169
170        private void StartLevel(string lvlName)
171        {
172            currentLevelName = lvlName;
173            ClearAll();
174
175            // Jos aloitetaan hubista kaikilla kamoilla, niin peli on voitettu.
176            if (collectedParts.Count == 3)
177            {
178                Action<double, string> makeLabel = (y, text) =>
179                {
180                    Add(new Label(text) { Y = y, TextColor = Color.White });
181                };
182                Level.Background.Color = Color.Black;
183                makeLabel(50, "The advenae managed to repair their ship\n          and flew to their home planet.");
184                makeLabel(-50, "Your final score is <insert score here>");
185                Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
186                return;
187            }
188
189           
190            advenae = new List<Player>();
191            objectMethods = new Dictionary<string, ObjectMethod>();
192            objectMethods.Add("ball", TestBall);
193            objectMethods.Add("player", CreatePlayer);
194            objectMethods.Add("moving", CreateMovingPlatform);
195            objectMethods.Add("door", CreateDoor);
196            objectMethods.Add("goomba", CreateGoomba);
197            objectMethods.Add("goomba2", CreateGoomba2);
198            objectMethods.Add("collectible", CreateCollectible);
199            objectMethods.Add("drip", CreateWaterDrip);
200            objectMethods.Add("shippart", CreateShipPart);
201
202            string backgroundImageName = null;
203
204            var tileMap = TiledTileMap.FromLevelAsset(lvlName);
205            tileMap.SetTileMethod("Tiilet", TileMethod);
206            tileMap.SetObjectMethod("Oliot", CreateObject);
207            tileMap.SetTileMethod("Etuala", Foreground);
208            tileMap.SetTileMethod("Takaala", BackgroundTile);
209            tileMap.Execute((levelProperty, value) =>
210            {
211                // Jos kentän propertyistä löytyy "background", niin asetetaan
212                // sen arvon niminen kuva taustakuvaksi.
213                // Kentän propertyjä voi säätää Tiled-editorissa valikosta
214                // Map -> Map Properties
215                if (levelProperty == "background")
216                    backgroundImageName = value;
217            });
218
219            if (backgroundImageName != null)
220            {
221                Level.Background.Image = LoadImage(backgroundImageName);
222                Level.Background.TileToLevel();
223            }
224            else Level.Background.CreateGradient(Color.Beige, Color.OrangeRed);
225
226            Gravity = new Vector(0, -1400);
227            Camera.Position = advenae[0].Position;
228            CameraInitialization();
229
230            CreateGUI();
231        }
232
233
234
235        private void CameraInitialization()
236        {
237            Camera.StayInLevel = true;
238
239            Window.Width = 1500;
240            Window.Height = 750;
241
242            borderleft = new SimplePhysics.Object(TileSize, Level.Height) { X = Camera.X + Window.Width / 2, IsVisible = false };
243            Add(borderleft);
244            borderright = new SimplePhysics.Object(TileSize, Level.Height) { X = Camera.X - Window.Width / 2, IsVisible = false };
245            Add(borderright);
246
247            Timer checkit = new Timer();
248            checkit.Interval = 0.02;
249            checkit.Timeout += () => { UpdateCameraTarget(checkit); };
250            checkit.Start();
251        }
252
253        private void UpdateCameraTarget(Timer checkit)
254        {
255            var activePlayers = advenae.FindAll(o => o.IsVisible);
256
257            switch (activePlayers.Count)
258            {
259                case 1:
260                    Player soloYolo = activePlayers[0];
261                    cameraTarget.X = soloYolo.Position.X + (soloYolo.FacingDirection.GetVector().X * (TileSize * 4));
262                    if (soloYolo.IsCrouching) cameraTarget.Y = soloYolo.Position.Y - TileSize * 4;
263                    else if (soloYolo.IsGrounded) cameraTarget.Y = soloYolo.Position.Y;
264                    break;
265                case 2:
266                    var minPosition = new Vector(activePlayers.Max(p => p.X), activePlayers.Min(p => p.Y));
267                    var maxPosition = new Vector(activePlayers.Min(p => p.X), activePlayers.Max(p => p.Y));
268                    cameraTarget = (minPosition + maxPosition) * 0.5;
269                    break;
270            }
271
272            borderleft.X = Camera.X + Window.Width / 2.0;
273            borderright.X = Camera.X - Window.Width / 2.0;
274        }
275
276        protected override void Update(Time time)
277        {
278            Camera.X += (cameraTarget.X - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.X;
279            Camera.Y += (cameraTarget.Y - Camera.Y) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.Y;
280
281            base.Update(time);
282        }
283       
284        private void SetMovementKeys(Player adven, List<Key> keys)
285        {
286            Keyboard.Listen(keys[3], ButtonState.Down, Walk, null, adven, 200.0);
287            Keyboard.Listen(keys[2], ButtonState.Down, Walk, null, adven, -200.0);
288            Keyboard.Listen(keys[0], ButtonState.Down, Jump, null, adven);
289            Keyboard.Listen(keys[1], ButtonState.Pressed, Crouch, null, adven, true);
290            Keyboard.Listen(keys[1], ButtonState.Released, Crouch, null, adven, false);
291            Keyboard.Listen(keys[4], ButtonState.Pressed, Interact, null, adven);
292            // Keyboard.Listen(keys[4], ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player back to 1 player", adven);
293        }
294
295        private void Interact(Player adven)
296        {
297            //Jos kannetaan jotain, viskataan se
298            var carrying = adven.Carrying;
299            if (carrying != null) //Throw
300            {
301                adven.Carrying = null;
302                double dir = adven.FacingDirection == Direction.Left ? -1 : 1;
303                carrying.Velocity = new Vector(dir * 350, 350);
304                carrying.Position = carrying.Position + new Vector(dir * 10, 30);
305                //Pitäisiköhän oma aliohjelma tehdä
306                carrying.IgnoresGravity = false;
307                carrying.IgnoresCollisionResponse = false;
308            }
309
310            Vector pingPoint = adven.Position + (adven.FacingDirection == Direction.Left ? new Vector(-adven.Width, 0) : new Vector(adven.Width, 0));
311            List<GameObject> interactedObjects = GetObjectsAt(pingPoint);
312
313            GameObject sphere = new GameObject(1, 1);
314            sphere.Position = pingPoint;
315            sphere.Shape = Shape.Circle;
316            sphere.Color = new Color(100, 0, 100, 25);
317            Add(sphere, 1);
318
319            TimerAddons.Until(() => sphere.Width == 100.0, delegate { sphere.Width += 1; sphere.Height += 1; }, 0.01, sphere.Destroy);
320
321            foreach (GameObject item in interactedObjects)
322            {
323                var obj = item as InteractableObject;
324                obj?.InteractWith(adven);
325            }
326        }
327
328        private void Pickup(SimplePhysics.Object player, InteractableObject target)
329        {
330            var adven = player as Player;
331            if (adven != null && adven.Carrying == null)
332            {
333                adven.Carrying = target;
334                target.IgnoresGravity = true;
335                target.IgnoresCollisionResponse = true;
336                //Lentävän palikan nostaminen
337            }
338        }
339
340        private void SetGeneralKeys()
341        {
342            Keyboard.Listen(Key.R, ButtonState.Pressed, () => { ClearAll(); advenae = new List<Player>(); Begin(); }, "Lopeta peli");
343            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
344
345            Keyboard.Listen(Key.X, ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player", 2);
346            Keyboard.Listen(Key.RightShift, ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player", 1);
347        }
348       
349        /// <summary>
350        /// Sotku
351        /// </summary>
352        /// <param name="playerNro">Sen pelaajan numero, joka haluaa toimia</param>
353        private void SplitOrMorph(int playerNro)
354        {
355            if (!advenae[playerNro - 1].IsVisible && advenae[1 - playerNro + 1].IsVisible)
356            {
357                Split(advenae[1 - playerNro + 1]);
358            }
359            else
360            {
361                Morph(advenae[1 - playerNro + 1]);
362            }
363        }
364
365        private void Morph(Player adven)
366        {
367            if (advenae.FindAll(o => o.IsVisible == true).Count != 2) return;
368
369            if (Vector.Distance(advenae[0].Position, advenae[1].Position) < adven.Width * 1.5)
370            {
371                Player destroyable = advenae.Find(o => o.PlayerNumber != adven.PlayerNumber);
372
373                destroyable.ControlKeys.ForEach(delegate (Key key)
374                {
375                    Keyboard.Disable(key);
376                });
377
378                destroyable.Destroy();
379                destroyable.IsAlive = false;
380                lives.Value++;
381            }
382
383
384            //TODO: Eeppinen hypäytys takaisin? Samalla voisi ajastimella tarkastaa jatkuvasti, ovatko pelaajat tarpeeksi lähellä toisiaan.
385            /*
386            Vector center = new Vector();
387
388            for (int i = 0; i < advenae.Count; i++)
389            {
390                center = (advenae[i].Position - center) * 0.5;
391            }
392            foreach (Player item in advenae)
393            {
394                item.Velocity = (center - item.Position) * 3.0;
395            }
396            morphing = true;
397            Timer.SingleShot(2.0, delegate { morphing = false; });
398            */
399        }
400
401        private void Split(Player adven)
402        {
403            if (advenae.FindAll(o => o.IsVisible == true).Count == 2 || lives.Value == 0) return;
404
405            Player advenNew = new Player(adven.Width, adven.Height);
406
407           
408
409            switch (adven.PlayerNumber)
410            {
411                case 1:
412                    advenNew = CreatePlayer2(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
413                    break;
414                case 2:
415                    advenNew = CreatePlayer1(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
416                    break;
417            }
418
419           
420            advenNew.Position = adven.Position + new Vector(adven.Width, 0);
421
422            if (Collisions(advenNew, Vector.Zero, true).Count > 0)
423            {
424                advenNew.Destroy();
425                return;
426            }
427
428            advenNew.ControlKeys.ForEach(delegate (Key key)
429            {
430                Keyboard.Enable(key);
431            });
432
433            lives.Value--;
434        }
435
436        private void Walk(Player pelaaja, double nopeus)
437        {
438            pelaaja.Walk(nopeus);
439        }
440
441        private void Jump(SimplePlatformCharacter player)
442        {
443            ((Player)player).Jump();
444        }
445
446        private void Crouch(Player player, bool crouch)
447        {
448            player.Crouch = crouch;
449        }
450    }
451}
Note: See TracBrowser for help on using the repository browser.