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

Revision 7810, 15.4 KB checked in by tesatapa, 3 years ago (diff)

ovi, josta vaihtaa kenttää

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