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

Revision 8007, 14.8 KB checked in by tesatapa, 3 years ago (diff)

toimiva respawn

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