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

Revision 7809, 14.3 KB checked in by empaheik, 3 years ago (diff)

Yksinpelaajan kamerakokeiluja.

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