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

Revision 7811, 16.4 KB checked in by sieerinn, 3 years ago (diff)

Vihollinen lisätty ja konfliktit taisteltu läpi

Line 
1using System;
2using System.Collections.Generic;
3using Jypeli;
4using Jypeli.Assets;
5using Jypeli.Controls;
6using Jypeli.Effects;
7using Jypeli.Widgets;
8using SimplePhysics;
9
10namespace VenienteFragore
11{
12    public 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 List<Player> advenae;
18
19        private Vector cameraSpeed = new Vector(2.0, 4.0);
20        private Vector cameraTarget;
21
22        public VenienteFragore() : base(tileSize: 50)
23        {
24        }
25
26        public override void Begin()
27        {
28            StartLevel("thehub");
29
30            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
31        }
32
33
34
35        private void StartLevel(string lvlName)
36        {
37            ClearAll();
38            advenae = new List<Player>();
39            objectMethods = new Dictionary<string, ObjectMethod>();
40            objectMethods.Add("ball", TestBall);
41            objectMethods.Add("player", CreatePlayer);
42            objectMethods.Add("moving", CreateMovingPlatform);
43            objectMethods.Add("door", CreateDoor);
44            objectMethods.Add("goomba", CreateGoomba);
45
46            var tileMap = TiledTileMap.FromLevelAsset(lvlName);
47            tileMap.SetTileMethod("Tiilet", TileMethod);
48            tileMap.SetObjectMethod("Oliot", CreateObject);
49            tileMap.SetTileMethod("Etuala", Foreground);
50            tileMap.Execute();
51
52            Gravity = new Vector(0, -800);
53
54            //Camera.ZoomToLevel();
55
56            Level.Background.CreateGradient(Color.Beige, Color.OrangeRed);
57
58            CameraInitialization();
59        }
60
61        void CameraInitialization()
62        {
63            Camera.StayInLevel = true;
64
65            Timer checkit = new Timer();
66            checkit.Interval = 0.02;
67            checkit.Timeout += () => { UpdateCameraTarget(checkit); };
68            checkit.Start();
69        }
70
71        void UpdateCameraTarget(Timer checkit)
72        {
73            List<Player> activePlayers = advenae.FindAll(o => o.IsVisible == true);
74
75            switch (activePlayers.Count)
76            {
77                case 1:
78                    Player soloYolo = activePlayers[0];
79                    cameraTarget.X = soloYolo.Position.X + (soloYolo.FacingDirection.GetVector().X * (TileSize * 4));
80                    if (soloYolo.IsCrouching) cameraTarget.Y = soloYolo.Position.Y - TileSize * 4;
81                    else if (soloYolo.IsGrounded) cameraTarget.Y = soloYolo.Position.Y;
82                    break;
83                case 2:
84                    cameraTarget = activePlayers[1].Position;
85                    break;
86                default:
87                    Camera.StopFollowing();
88                    checkit.Stop();
89                    break;
90            }
91        }
92
93        protected override void Update(Time time)
94        {
95            Camera.X += (cameraTarget.X - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.X;
96            Camera.Y += (cameraTarget.Y - Camera.Y) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.Y;
97
98            base.Update(time);
99        }
100
101        private void CreateObject(Vector position, double width, double height, Angle angle, Shape shape, string name, Dictionary<string, string> properties)
102        {
103            if (objectMethods.ContainsKey(name))
104                objectMethods[name](position, width, height, properties);
105            else
106                throw new Exception("Unknown object type: " + name);
107        }
108
109        void TestBall(Vector position, double width, double height, Dictionary<string, string> properties)
110        {
111            var testObject = new InteractableObject(TileSize * 0.99, TileSize * 0.99);
112            testObject.Position = position;
113            testObject.Color = Color.DarkGreen;
114            testObject.Shape = Shape.Circle;
115            testObject.RestitutionX = 0.5;
116            testObject.RestitutionY = 0.5;
117            testObject.CollisionIgnoreGroup = 1;
118            testObject.OnInteractedWith += Pickup;
119            Add(testObject);
120        }
121
122        void CreateGoomba(Vector position, double width, double height, Dictionary<string, string> properties)
123        {
124            var goomba = new GoombaEnemy(TileSize * 0.99, TileSize * 0.99);
125            goomba.Position = position;
126            goomba.Color = Color.Pink;
127            goomba.Tag = "goomba";
128            goomba.Speed = 50;
129            goomba.FallOffPlatforms = true;
130            Add(goomba);
131
132            goomba.AddCollisionHandler("player", (a, player) =>
133            {
134                if (player.Bottom >= goomba.Top)
135                {
136                    goomba.Destroy();
137                    player.Velocity = new Vector(player.Velocity.X, 400);
138                }
139                else
140                {
141                    player.Destroy();
142                }
143            });
144        }
145
146        void CreatePlayer(Vector position, double width, double height, Dictionary<string, string> properties)
147        {
148            CreatePlayer1(position, width, height);
149            var p = CreatePlayer2(position, width, height);
150            p.Destroy();
151            SetGeneralKeys();
152        }
153
154        Player CreatePlayer1(Vector position, double width, double height)
155        {
156            if (advenae.Count > 0 && !advenae[0].IsVisible) { advenae[0].Reappear(); return advenae[0]; };
157
158            Player advenA = MakePlayer(position, width, height, 1, new List<Key> { Key.Up, Key.Down, Key.Left, Key.Right, Key.Enter });
159            advenA.Color = Color.HotPink;
160            advenae.Add(advenA);
161            return advenA;
162        }
163
164
165        Player CreatePlayer2(Vector position, double width, double height)
166        {
167            if (advenae.Count > 1 && !advenae[1].IsVisible) { advenae[1].Reappear(); return advenae[1]; };
168
169            Player advenA = MakePlayer(position, width, height, 2, new List<Key> { Key.W, Key.S, Key.A, Key.D, Key.E });
170            advenA.Color = Color.Harlequin;
171            advenae.Add(advenA);
172            return advenA;
173        }
174
175        private void SetMovementKeys(Player adven, List<Key> keys)
176        {
177            Keyboard.Listen(keys[3], ButtonState.Down, Walk, null, adven, 200.0);
178            Keyboard.Listen(keys[2], ButtonState.Down, Walk, null, adven, -200.0);
179            Keyboard.Listen(keys[0], ButtonState.Down, Jump, null, adven);
180            Keyboard.Listen(keys[1], ButtonState.Pressed, Crouch, null, adven, true);
181            Keyboard.Listen(keys[1], ButtonState.Released, Crouch, null, adven, false);
182            Keyboard.Listen(keys[4], ButtonState.Pressed, Interact, null, adven);
183            // Keyboard.Listen(keys[4], ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player back to 1 player", adven);
184
185        }
186
187        private void Interact(Player adven)
188        {
189            //Jos kannetaan jotain, viskataan se
190            SimplePhysics.Object carryed = adven.Carrying;
191            if (carryed != null) //Throw
192            {
193                adven.Carrying = null;
194                double dir = adven.FacingDirection == Direction.Left ? -1 : 1;
195                carryed.Velocity = new Vector(dir * 350, 350);
196                carryed.Position = carryed.Position + new Vector(dir * 10, 30);
197                //Pitäisiköhän oma aliohjelma tehdä
198                carryed.IgnoresGravity = false;
199                carryed.IgnoresCollisionResponse = false;
200            }
201
202            Vector pingPoint = adven.Position + (adven.FacingDirection == Direction.Left ? new Vector(-adven.Width, 0) : new Vector(adven.Width, 0));
203            List<GameObject> interactedObjects = GetObjectsAt(pingPoint);
204
205            GameObject sphere = new GameObject(1, 1);
206            sphere.Position = pingPoint;
207            sphere.Shape = Shape.Circle;
208            sphere.Color = new Color(100, 0, 100, 25);
209            Add(sphere, 1);
210
211            TimerAddons.Until(() => sphere.Width == 100.0, delegate { sphere.Width += 1; sphere.Height += 1; }, 0.01, sphere.Destroy);
212
213            foreach (GameObject item in interactedObjects)
214            {
215                InteractableObject obj = item as InteractableObject;
216                if (obj == null)
217                    continue;
218                obj.InteractWith(adven);
219            }
220        }
221
222
223        void Pickup(SimplePhysics.Object player, InteractableObject target)
224        {
225            Player adven = player as Player;
226            if (adven.Carrying == null)
227            {
228                adven.Carrying = target;
229                target.IgnoresGravity = true;
230                target.IgnoresCollisionResponse = true;
231                //Lentävän palikan nostaminen
232            }
233
234        }
235
236        private void SetGeneralKeys()
237        {
238            Keyboard.Listen(Key.R, ButtonState.Pressed, () => { ClearAll(); advenae = new List<Player>(); Begin(); }, "Lopeta peli");
239            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
240
241            //Keyboard.Listen(keys[4], ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player back to 1 player", adven);
242            Keyboard.Listen(Key.X, ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player", 2);
243            Keyboard.Listen(Key.RightShift, ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player", 1);
244        }
245
246
247        private Player MakePlayer(Vector position, double width, double height, int playerNum, List<Key> keys)
248        {
249            Player adven = new Player(TileSize * 0.99, TileSize * 1.98);
250            adven.Position = position;
251            adven.Friction = 0.2;
252            adven.Tag = "player";
253            adven.Crushed += adven.Destroy;
254            adven.CollisionIgnoreGroup = playerNum;
255            adven.PlayerNumber = playerNum;
256            adven.ControlKeys = keys;
257            adven.OnInteractedWith += Pickup;
258            Add(adven);
259
260            adven.AddCollisionHandler("death", (a, b) => adven.Destroy());
261
262            SetMovementKeys(adven, keys);
263
264            return adven;
265        }
266
267        /// <summary>
268        /// Sotku
269        /// </summary>
270        /// <param name="playerNro">Sen pelaajan numero, joka haluaa toimia</param>
271        private void SplitOrMorph(int playerNro)
272        {
273            if (!advenae[playerNro - 1].IsVisible && advenae[1 - playerNro + 1].IsVisible)
274            {
275                Split(advenae[1 - playerNro + 1]);
276            }
277            else
278            {
279                Morph(advenae[1 - playerNro + 1]);
280            }
281        }
282
283        private void Morph(Player adven)
284        {
285            if (advenae.FindAll(o => o.IsVisible == true).Count != 2) return;
286
287            if (Vector.Distance(advenae[0].Position, advenae[1].Position) < adven.Width * 1.5)
288            {
289                Player destroyable = advenae.Find(o => o.PlayerNumber != adven.PlayerNumber);
290
291                destroyable.ControlKeys.ForEach(delegate (Key key)
292                {
293                    Keyboard.Disable(key);
294                });
295
296                destroyable.Destroy();
297            }
298
299            //TODO: Eeppinen hypäytys takaisin? Samalla voisi ajastimella tarkastaa jatkuvasti, ovatko pelaajat tarpeeksi lähellä toisiaan.
300            /*
301            Vector center = new Vector();
302
303            for (int i = 0; i < advenae.Count; i++)
304            {
305                center = (advenae[i].Position - center) * 0.5;
306            }
307            foreach (Player item in advenae)
308            {
309                item.Velocity = (center - item.Position) * 3.0;
310            }
311            morphing = true;
312            Timer.SingleShot(2.0, delegate { morphing = false; });
313            */
314        }
315
316        void Split(Player adven)
317        {
318            if (advenae.FindAll(o => o.IsVisible == true).Count == 2) return;
319
320            Player advenNew = new Player(adven.Width, adven.Height);
321            switch (adven.PlayerNumber)
322            {
323                case 1:
324                    advenNew = CreatePlayer2(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
325                    break;
326                case 2:
327                    advenNew = CreatePlayer1(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
328                    break;
329                default:
330                    break;
331            }
332
333            advenNew.Position = adven.Position + new Vector(adven.Width, 0);
334
335            if (Collisions(advenNew, Vector.Zero, true).Count > 0)
336            {
337                advenNew.Destroy();
338                return;
339            }
340
341            advenNew.ControlKeys.ForEach(delegate (Key key)
342            {
343                Keyboard.Enable(key);
344            });
345        }
346
347        void Walk(Player pelaaja, double nopeus)
348        {
349            pelaaja.Walk(nopeus);
350        }
351
352        private void Jump(SimplePlatformCharacter player)
353        {
354            if (player.IsGrounded)
355                player.Velocity = new Vector(player.Velocity.X, 500);
356        }
357
358        private void Crouch(Player player, bool crouch)
359        {
360            player.Crouch = crouch;
361        }
362
363        private void CreateMovingPlatform(Vector position, double width, double height, Dictionary<string, string> properties)
364        {
365            var dirX = double.Parse(properties["directionx"]);
366            var dirY = double.Parse(properties["directiony"]);
367            var distance = double.Parse(properties["distance"]);
368            var platform = new MovingPlatform(position, new Vector(dirX, dirY), distance, width, height);
369            Add(platform);
370        }
371
372
373        private void CreateDoor(Vector position, double width, double height, Dictionary<string, string> properties)
374        {
375           string lvlName = properties["levelName"];
376            InteractableObject door = new InteractableObject(width, height);
377            door.Position = position;
378            door.Color = Color.Purple;
379            door.OnInteractedWith += delegate (SimplePhysics.Object actor, InteractableObject actedDoor)
380            {
381                EnterDoor(actor, actedDoor, lvlName);
382            };
383            Add(door);
384        }
385
386        private void EnterDoor(SimplePhysics.Object actor, InteractableObject actedDoor, string lvlName)
387        {
388            //Tämä tänne, jotta anim. tai jotain jos joskus halutaan, muuten suoraan voi vaihtaa kenttää delegattissa
389            StartLevel(lvlName);
390        }
391
392        private void Foreground(int x, int y, Image image, string layerName, Dictionary<string, string> properties)
393        {
394            var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true };
395            tile.Image = image;
396            tile.IgnoresCollisionResponse = true;
397            Add(tile, 3);
398            SetTile(x, y, tile);
399        }
400
401        private void TileMethod(int x, int y, Image image, string layerName, Dictionary<string, string> properties)
402        {
403            var tile = new SimplePhysics.Object(TileSize, TileSize) { IsStatic = true };
404            tile.Image = image;
405            Add(tile);
406            SetTile(x, y, tile);
407
408            if (properties.ContainsKey("type"))
409            {
410                var features = properties["type"].Split(',');
411                foreach (var feature in features)
412                {
413                    ApplyFeature(tile, feature);
414                }
415            }
416        }
417
418        private void ApplyFeature(SimplePhysics.Object tile, string feature)
419        {
420            switch (feature)
421            {
422                case "ice":
423                    tile.Friction = 0.0;
424                    break;
425
426                case "death":
427                    tile.Tag = "death";
428                    break;
429
430                case "oneway":
431                    tile.OneWayPlatform = true;
432                    break;
433
434                case "break":
435                    tile.AddCollisionHandler("player", (t, player) =>
436                    {
437                        if (player.Top <= tile.Bottom)
438                        {
439                            tile.Destroy();
440                        }
441                    });
442                    break;
443                default:
444                    throw new Exception("Unknown tile feature: " + feature);
445            }
446        }
447    }
448}
Note: See TracBrowser for help on using the repository browser.