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

Revision 7978, 11.7 KB checked in by sieerinn, 3 years ago (diff)

Kentän taustakuva on nyt kentän ominaisuutena

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