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

Revision 8008, 16.6 KB checked in by tesatapa, 3 years ago (diff)

musiikkia ja menu

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