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

Revision 7982, 11.8 KB checked in by empaheik, 3 years ago (diff)
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 Image advenaBlob = LoadImage("advenaBlob");
24        private Image advenbBlob = LoadImage("advenbBlob");
25
26        private readonly Image advenaCrouch = LoadImage("advenacrouch");
27        private readonly Image advenbCrouch = LoadImage("advenbcrouch");
28
29        private List<Player> advenae;
30
31        private Vector cameraSpeed = new Vector(2.0, 4.0);
32        private Vector cameraTarget;
33
34        private SimplePhysics.Object borderleft;
35        private SimplePhysics.Object borderright;
36
37        public VenienteFragore() : base(tileSize: 50)
38        {
39        }
40
41        public override void Begin()
42        {
43            StartLevel("thehub");
44
45            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
46        }
47
48        public double DistanceToNearestPlayer(Vector point)
49        {
50            return advenae.Min(p => Vector.Distance(p.Position, point));
51        }
52
53        private void StartLevel(string lvlName)
54        {
55            ClearAll();
56            advenae = new List<Player>();
57            objectMethods = new Dictionary<string, ObjectMethod>();
58            objectMethods.Add("ball", TestBall);
59            objectMethods.Add("player", CreatePlayer);
60            objectMethods.Add("moving", CreateMovingPlatform);
61            objectMethods.Add("door", CreateDoor);
62            objectMethods.Add("goomba", CreateGoomba);
63            objectMethods.Add("goomba2", CreateGoomba2);
64            objectMethods.Add("drip", CreateWaterDrip);
65
66            string backgroundImageName = null;
67
68            var tileMap = TiledTileMap.FromLevelAsset(lvlName);
69            tileMap.SetTileMethod("Tiilet", TileMethod);
70            tileMap.SetObjectMethod("Oliot", CreateObject);
71            tileMap.SetTileMethod("Etuala", Foreground);
72            tileMap.Execute((levelProperty, value) =>
73            {
74                // Jos kentän propertyistä löytyy "background", niin asetetaan
75                // sen arvon niminen kuva taustakuvaksi.
76                // Kentän propertyjä voi säätää Tiled-editorissa valikosta
77                // Map -> Map Properties
78                if (levelProperty == "background")
79                    backgroundImageName = value;
80            });
81
82            if (backgroundImageName != null)
83            {
84                Level.Background.Image = LoadImage(backgroundImageName);
85                Level.Background.TileToLevel();
86            }
87            else Level.Background.CreateGradient(Color.Beige, Color.OrangeRed);
88
89            Gravity = new Vector(0, -1400);
90           
91            CameraInitialization();
92        }
93
94        private void CameraInitialization()
95        {
96            Camera.StayInLevel = true;
97
98            Window.Width = 1500;
99            Window.Height = 750;
100
101            borderleft = new SimplePhysics.Object(TileSize, Level.Height) { X = Camera.X + Window.Width / 2, IsVisible = false };
102            Add(borderleft);
103            borderright = new SimplePhysics.Object(TileSize, Level.Height) { X = Camera.X - Window.Width / 2, IsVisible = false };
104            Add(borderright);
105
106            Timer checkit = new Timer();
107            checkit.Interval = 0.02;
108            checkit.Timeout += () => { UpdateCameraTarget(checkit); };
109            checkit.Start();
110        }
111
112        private void UpdateCameraTarget(Timer checkit)
113        {
114            var activePlayers = advenae.FindAll(o => o.IsVisible);
115
116            switch (activePlayers.Count)
117            {
118                case 1:
119                    Camera.StopFollowing();
120                    Player soloYolo = activePlayers[0];
121                    cameraTarget.X = soloYolo.Position.X + (soloYolo.FacingDirection.GetVector().X * (TileSize * 4));
122                    if (soloYolo.IsCrouching) cameraTarget.Y = soloYolo.Position.Y - TileSize * 4;
123                    else if (soloYolo.IsGrounded) cameraTarget.Y = soloYolo.Position.Y;
124                    break;
125                case 2:
126                    var minPosition = new Vector(activePlayers.Max(p => p.X), activePlayers.Min(p => p.Y));
127                    var maxPosition = new Vector(activePlayers.Min(p => p.X), activePlayers.Max(p => p.Y));
128                    cameraTarget = (minPosition + maxPosition) * 0.5;
129                    break;
130                default:
131                    Camera.StopFollowing();
132                    checkit.Stop();
133                    break;
134            }
135
136            borderleft.X = Camera.X + Window.Width / 2.0;
137            borderright.X = Camera.X - Window.Width / 2.0;
138        }
139
140        protected override void Update(Time time)
141        {
142            Camera.X += (cameraTarget.X - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.X;
143            Camera.Y += (cameraTarget.Y - Camera.Y) * time.SinceLastUpdate.TotalSeconds * cameraSpeed.Y;
144
145            base.Update(time);
146        }
147       
148        private void SetMovementKeys(Player adven, List<Key> keys)
149        {
150            Keyboard.Listen(keys[3], ButtonState.Down, Walk, null, adven, 200.0);
151            Keyboard.Listen(keys[2], ButtonState.Down, Walk, null, adven, -200.0);
152            Keyboard.Listen(keys[0], ButtonState.Down, Jump, null, adven);
153            Keyboard.Listen(keys[1], ButtonState.Pressed, Crouch, null, adven, true);
154            Keyboard.Listen(keys[1], ButtonState.Released, Crouch, null, adven, false);
155            Keyboard.Listen(keys[4], ButtonState.Pressed, Interact, null, adven);
156            // Keyboard.Listen(keys[4], ButtonState.Pressed, SplitOrMorph, "Splits or morphs the player back to 1 player", adven);
157        }
158
159        private void Interact(Player adven)
160        {
161            //Jos kannetaan jotain, viskataan se
162            var carrying = adven.Carrying;
163            if (carrying != null) //Throw
164            {
165                adven.Carrying = null;
166                double dir = adven.FacingDirection == Direction.Left ? -1 : 1;
167                carrying.Velocity = new Vector(dir * 350, 350);
168                carrying.Position = carrying.Position + new Vector(dir * 10, 30);
169                //Pitäisiköhän oma aliohjelma tehdä
170                carrying.IgnoresGravity = false;
171                carrying.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                var obj = item as InteractableObject;
188                obj?.InteractWith(adven);
189            }
190        }
191
192        private void Pickup(SimplePhysics.Object player, InteractableObject target)
193        {
194            var adven = player as Player;
195            if (adven != null && adven.Carrying == null)
196            {
197                adven.Carrying = target;
198                target.IgnoresGravity = true;
199                target.IgnoresCollisionResponse = true;
200                //Lentävän palikan nostaminen
201            }
202        }
203
204        private void SetGeneralKeys()
205        {
206            Keyboard.Listen(Key.R, ButtonState.Pressed, () => { ClearAll(); advenae = new List<Player>(); Begin(); }, "Lopeta peli");
207            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
208
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        }
212       
213        /// <summary>
214        /// Sotku
215        /// </summary>
216        /// <param name="playerNro">Sen pelaajan numero, joka haluaa toimia</param>
217        private void SplitOrMorph(int playerNro)
218        {
219            if (!advenae[playerNro - 1].IsVisible && advenae[1 - playerNro + 1].IsVisible)
220            {
221                Split(advenae[1 - playerNro + 1]);
222            }
223            else
224            {
225                Morph(advenae[1 - playerNro + 1]);
226            }
227        }
228
229        private void Morph(Player adven)
230        {
231            if (advenae.FindAll(o => o.IsVisible == true).Count != 2) return;
232
233            if (Vector.Distance(advenae[0].Position, advenae[1].Position) < adven.Width * 1.5)
234            {
235                Player destroyable = advenae.Find(o => o.PlayerNumber != adven.PlayerNumber);
236
237                destroyable.ControlKeys.ForEach(delegate (Key key)
238                {
239                    Keyboard.Disable(key);
240                });
241
242                destroyable.Destroy();
243            }
244
245            //TODO: Eeppinen hypäytys takaisin? Samalla voisi ajastimella tarkastaa jatkuvasti, ovatko pelaajat tarpeeksi lähellä toisiaan.
246            /*
247            Vector center = new Vector();
248
249            for (int i = 0; i < advenae.Count; i++)
250            {
251                center = (advenae[i].Position - center) * 0.5;
252            }
253            foreach (Player item in advenae)
254            {
255                item.Velocity = (center - item.Position) * 3.0;
256            }
257            morphing = true;
258            Timer.SingleShot(2.0, delegate { morphing = false; });
259            */
260        }
261
262        private void Split(Player adven)
263        {
264            if (advenae.FindAll(o => o.IsVisible == true).Count == 2) return;
265
266            Player advenNew = new Player(adven.Width, adven.Height);
267            switch (adven.PlayerNumber)
268            {
269                case 1:
270                    advenNew = CreatePlayer2(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
271                    break;
272                case 2:
273                    advenNew = CreatePlayer1(adven.Position + new Vector(adven.Width, 0), adven.Width, adven.Height);
274                    break;
275            }
276
277            advenNew.Position = adven.Position + new Vector(adven.Width, 0);
278
279            if (Collisions(advenNew, Vector.Zero, true).Count > 0)
280            {
281                advenNew.Destroy();
282                return;
283            }
284
285            advenNew.ControlKeys.ForEach(delegate (Key key)
286            {
287                Keyboard.Enable(key);
288            });
289        }
290
291        private void Walk(Player pelaaja, double nopeus)
292        {
293            pelaaja.Walk(nopeus);
294        }
295
296        private void Jump(SimplePlatformCharacter player)
297        {
298            ((Player)player).Jump();
299        }
300
301        private void Crouch(Player player, bool crouch)
302        {
303            player.Crouch = crouch;
304        }
305    }
306}
Note: See TracBrowser for help on using the repository browser.