source: 2015/26/ohjaajat/HillbillyRun/HillbillyRun/HillbillyRun/HillbillyRun/HillbillyRun.cs @ 6216

Revision 6216, 18.8 KB checked in by jotapoti, 6 years ago (diff)

better intro sequence

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using Jypeli;
5using Jypeli.Assets;
6using Jypeli.Controls;
7using Jypeli.Effects;
8using Jypeli.Widgets;
9
10/* Muistutuksia.
11 *
12 * Layerit
13 *   3 -
14 *   2 -
15 *   1 -
16 *   0 -
17 *  -1 - Näkyvä maanpinta.
18 *  -2 - Talot taustalla.
19 * 
20 * CollisionIgnoreGroupit
21 *  3 - Ryömivät ja liekit. //TODO: lisätä noidatkin tänne
22 *  2 - Kärry.
23 *
24*/
25
26
27//Luokka maajussien erikoisuuksille.
28class HillBilly : PlatformCharacter
29{
30    private IntMeter lifeCounter = new IntMeter(2, 0, 2);
31    public IntMeter Life
32    {
33        set { lifeCounter = value; }
34        get { return lifeCounter; } 
35    }
36
37
38
39    public HillBilly(double leveys, double korkeus)
40        : base(leveys, korkeus)
41    {
42       
43    }
44}
45
46/// <summary>
47/// An MMO where you go to war with mages in the lava kingdom.
48/// </summary>
49public class HillbillyRun : PhysicsGame
50{
51    private List<HillBilly> players = new List<HillBilly>();
52    private List<HillBilly> startingPlayers = new List<HillBilly>();
53
54    //private List<double> playerPositionsX = new List<double>();
55    //private List<double> playerPositionsY = new List<double>();
56
57    private const double TILE_SIZE = 70;
58
59    private double cameraTargetX; // Sijainti jossa kameran pitäisi olla.
60    private Vector cameraTarget;
61
62    private double cameraOffset = 400; // TODO: Tämän voisi ehkä laskea jostain (esim. ikkunan leveydestä kolmasosa tai jotain).
63    private double cameraSpeed = 2.0; // Kameran liikkumisnopeus.
64
65    # region Images
66    private Image[] groundImages = LoadImages("ground");    //Näitä ei tosin kaikkia kenties jaksa tehdä erilaisiksi levelistä riippuen
67    private Image[] groundTopImages = LoadImages("ground_top");
68    private Image[] foregroundDecorations = LoadImages("viljaa");
69    private Image[] blockImages = LoadImages("box");
70
71    private Image[] houseImages = LoadImages("house", "houseburned");
72
73    private Image cartImage = LoadImage("cart");
74    private Image milkImage = LoadImage("tonkka");
75   
76    private Image cartWheelImage = LoadImage("cartwheel");
77
78    private Image smokeImage1 = LoadImage("smoke1");
79    private Image smokeImage2 = LoadImage("smoke2");
80
81    private Animation crawl;
82    private Animation blaze;
83    #endregion
84
85    private double leftCamLimit;
86    private double rightCamLimit;
87    private double bottomCamLimit;
88
89    private int levelNumber = 0;
90   
91    public override void Begin()
92    {
93        IntroSequence();
94        //MainMenu();
95        //StartGame();
96    }
97
98    #region Intro
99    void IntroSequence()
100    {
101        Level.Background.Color = Color.Black;
102
103        Keyboard.Listen(Key.Escape, ButtonState.Pressed, SkipIntro, "Skip");
104       
105        ShowMadeWithJypeli();
106
107        Timer.SingleShot(4.0, delegate // TODO get rid of fixed amount of seconds
108        {
109            ShowBackgroundStory();
110        });
111       
112
113
114    }
115
116    void ShowMadeWithJypeli()
117    {
118        Image madewithImage = LoadImage("madewithjypeli");
119       
120        double w = Window.Width / 4;
121        double h = w * (madewithImage.Height / (double)madewithImage.Width); // take aspect ratio from the picture
122       
123        GameObject madewithjypeliObject = new GameObject(w, h);
124        madewithjypeliObject.Image = madewithImage;
125        Add(madewithjypeliObject);
126
127        // Tässä oli jotain epätehokasta feidailua tuolle Made with Jypeli -kuvalle. Ei tunnu päivittyvän joka framella tai on muuten vain tosi raskas...
128
129        //fadeTimer = new Timer();
130        //fadeTimer.Interval = 0.5;
131        //fadeTimer.Timeout += delegate
132        //{
133        //    madewithjypeliObject.Image = LerpImage(madewithjypeliObject.Image, Color.Black, 0.6);
134        //};
135        //fadeTimer.Start(5);
136       
137        Timer.SingleShot(1.2, delegate
138        {
139            madewithjypeliObject.Destroy();
140        });
141
142    }
143
144    Image LerpImage(Image original, Color targetColor, double ratio)
145    {
146        Image newImage = new Image(original.Width, original.Height, Color.Transparent);
147        for (int y = 0; y < original.Height; y++)
148        {
149            for (int x = 0; x < original.Width; x++)
150            {
151                newImage[y, x] = Color.Lerp(original[y, x], targetColor, ratio);
152            }
153        }
154        return newImage;
155    }
156
157    void ShowBackgroundStory()
158    {
159        Label storyLabel = new Label("Once upon a time...");
160        storyLabel.TextColor = Color.Black;
161        Add(storyLabel);
162
163        Timer textTimer = new Timer();
164        textTimer.Interval = 0.1;
165        textTimer.Timeout += delegate
166        {
167            // lightens text up:
168            storyLabel.TextColor = Color.Lerp(storyLabel.TextColor, Color.Gray, 0.1);
169        };
170        textTimer.Start();
171        // TODO siirrä aliohjelmaan, jolle voi antaa parametrina stringin, joka näytetään siististi feidaamalla esille
172
173        // TODO lisää koko pelin tarina usealla feidailevalla tekstinpätkällä esitettynä
174
175        // Clean up after the intro:
176        Timer.SingleShot(5, delegate // TODO get rid of this fixed amount of seconds
177        { // TODO replace this SingleShot with something else. It must be the last thing after the intro sequence
178            storyLabel.Destroy();
179
180            ClearAll();
181            MainMenu();
182        });
183    }
184
185    void SkipIntro()
186    {
187        ClearTimers();
188        ClearAll();
189        Keyboard.Clear();
190        MainMenu();
191    }
192
193    void MainMenu()
194    {
195        Level.Background.Color = Color.DarkBlue;
196
197        MultiSelectWindow mainmenu = new MultiSelectWindow("Main menu",
198"Start game", "Credits", "Exit");
199        mainmenu.AddItemHandler(0, StartGame);
200        mainmenu.AddItemHandler(1, ShowCredits);
201        mainmenu.AddItemHandler(2, Exit);
202        mainmenu.DefaultCancel = 2;
203        Add(mainmenu);
204    }
205
206    void ShowCredits()
207    {
208        MessageWindow win = new MessageWindow("This game was made in one week by\nSimo Rinne,\nEmma Heikura,\n and Jouni Potila\n using University of Jyväskylä's\n game programming library Jypeli");
209        win.Closed += delegate
210        {
211            ClearAll();
212            MainMenu();
213        };
214        Add(win);
215    }
216    #endregion
217
218    void StartGame()
219    {
220        Initializing();
221        CreateLevel();
222        ScreenSettings();
223
224        // Testailen tässä kärryn luomista.
225        //double size = 0.7;
226        //PhysicsObject cart = new PhysicsObject(400 * size, 80 * size);
227        //cart.X = -1600;
228        //cart.Y = 200;
229        //cart.Image = cartImage;
230        //cart.CollisionIgnoreGroup = 2;
231        //Add(cart);
232        //PhysicsObject cartWheel = new PhysicsObject(160 * size, 160 * size, Shape.Circle);
233        //cartWheel.Image = cartWheelImage;
234        //cartWheel.Position = cart.Position + new Vector(-110, -30) * size;
235        //cartWheel.CollisionIgnoreGroup = 2;
236        //Add(cartWheel);
237        //AxleJoint joint = new AxleJoint(cart, cartWheel);
238        //Add(joint);
239    }
240
241    void Initializing()
242    {
243        crawl = LoadAnimation("crawl");
244        blaze = LoadAnimation("flame");
245    }
246
247    void ScreenSettings()
248    {
249        Window.Width = 1800;
250        Window.Height = 900;
251
252        leftCamLimit = Level.Left + Window.Width / 2.0;
253        rightCamLimit = Level.Right - Window.Width / 2.0;
254        bottomCamLimit = Level.Bottom + Window.Height / 2.0;
255
256        //Camera.X = cameraTargetX = players[0].X;
257        //Camera.ZoomToLevel();
258        Camera.X = cameraTargetX = leftCamLimit;
259
260        Timer cameraTimer = new Timer();
261        cameraTimer.Interval = 1 / 30.0;
262        cameraTimer.Timeout += UpdateCamera;
263        cameraTimer.Start();
264    }
265
266    #region LevelCreation
267    void CreateLevel()
268    {
269        Gravity = new Vector(0, -1000);
270
271        ColorTileMap level = ColorTileMap.FromLevelAsset("level" + levelNumber);
272        level.SetTileMethod(Color.Black, CreateGroundTop);
273        level.SetTileMethod(Color.Brown, CreateGround);
274
275        level.SetTileMethod(Color.Cyan, CreateHouse);
276        level.SetTileMethod(Color.PaintDotNetBlue, CreateBurnedHouse);
277
278        level.SetTileMethod(Color.Gold, CreatePlayer);
279        level.SetTileMethod(Color.Harlequin, CreateCart);
280        level.SetTileMethod(Color.White, CreateBlockObject); 
281        level.SetTileMethod(Color.DarkGray, CreateMilk);   
282        level.SetTileMethod(Color.Gray, CreateCrawly);
283        level.SetTileMethod(Color.Red, CreateDummy, Color.Red);    //TODO: CreateWitch
284        level.SetTileMethod(Color.Rose, CreateFlame);   
285        //level.SetTileMethod(Color.Azure, CreateDummy, Color.Azure);   //TODO: CreateSmoke
286        //level.SetTileMethod(Color.Orange, CreateDummy, Color.Orange); //TODO: CreateTombstone
287        level.Execute(TILE_SIZE, TILE_SIZE);
288        level.Optimize(Color.Black, Color.Brown);
289
290        //TileMap level = TileMap.FromLevelAsset("level" + levelNumber);
291        //level.SetTileMethod('P', CreatePlayer);
292        //level.SetTileMethod('#', CreateGroundTop);
293        //level.SetTileMethod('%', CreateGround);
294        //level.Optimize('#', '%');
295        //level.Execute(TILE_SIZE, TILE_SIZE);
296        //Level.CreateBorders(true);
297
298        SetControls();
299    }
300
301    void CreateFlame(Vector position, double width, double height)
302    {
303        PhysicsObject flame = PhysicsObject.CreateStaticObject(width, height * 2);
304        //flame.Image = flameImage;
305        flame.Color = Color.Red;
306        double hieman = height * 0.3;
307        flame.Position = position - new Vector(0, hieman);
308        flame.CollisionIgnoreGroup = 3;
309        flame.Tag = "burn";
310        flame.Animation = new Animation(blaze) { FPS = RandomGen.NextInt(20, 26) };
311        flame.Animation.Step(RandomGen.NextInt(0, 12));
312        flame.Animation.Resume();
313        Add(flame);
314
315        Smoke savu = new Smoke();
316        savu.ParticleImage = smokeImage1;
317        savu.OuterParticleImage = smokeImage2;
318        savu.MaxLifetime = 1.0;
319        savu.MaxScale = 200;
320        savu.MinScale = 10;
321        savu.Position = flame.Position;
322        Wind = new Vector(-10, 0);
323        Add(savu);
324    }
325
326    void CreateBlockObject(Vector position, double width, double height)
327    {
328        PhysicsObject block = PhysicsObject.CreateStaticObject(width, height);
329        block.Image = blockImages[levelNumber];
330        block.Position = position;
331        Add(block);
332    }
333
334    void CreateMilk(Vector position, double width, double height)
335    {
336        GameObject milk = new GameObject(milkImage.Width, milkImage.Height);
337        milk.Image = milkImage;
338        milk.Position = position;
339        milk.Tag = "milk";
340        Add(milk);
341    }
342
343    void CreateCrawly(Vector position, double width, double height)
344    {
345        PlatformCharacter crawly = new PlatformCharacter(width * 2, height);
346        crawly.Position = position;
347        crawly.Color = Color.Gray;
348        crawly.Animation = crawl;
349        crawly.Animation.Start();
350        crawly.Tag = "burn";
351        crawly.CollisionIgnoreGroup = 3;
352        Add(crawly);
353
354        PlatformWandererBrain brain = new PlatformWandererBrain();
355        brain.Speed = 20;
356        brain.FallsOffPlatforms = true;
357
358        crawly.Brain = brain;
359    }
360
361    void CreateHouse(Vector position, double width, double height)
362    {
363        // Näkyvä talo
364        GameObject house = new GameObject(width * 10, height * 8);
365        house.Image = houseImages[0];
366        house.Position = position - new Vector(0, height * 2.5);
367        Add(house, -2);
368
369        //Seisottava tasanne
370        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width - (TILE_SIZE * 3.25), 1);     //Tätä kohtaa on nyt vähän hakemalla haettu.
371        platform.IsVisible = false;
372        platform.Position = new Vector(house.X + (TILE_SIZE * 0.5), house.Top);
373        Add(platform);
374    }
375
376    void CreateBurnedHouse(Vector position, double width, double height)
377    {
378        GameObject house = new GameObject(width * 10, height * 8);
379        house.Image = houseImages[1];
380        house.Position = position - new Vector(0, height * 2.5);
381        Add(house, -2);
382
383        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width* 0.25, 1);
384        platform.IsVisible = false;
385        platform.Position = new Vector(house.X + platform.Width * 0.5, house.Top);
386        Add(platform);
387    }
388
389    private void CreateCart(Vector position, double width, double height)
390    {
391        double size = 0.7;
392        PhysicsObject cart = new PhysicsObject(400 * size, 80 * size);
393        cart.Position = position;
394        cart.Image = cartImage;
395        cart.CollisionIgnoreGroup = 2;
396        Add(cart);
397        PhysicsObject cartWheel = new PhysicsObject(160 * size, 160 * size, Shape.Circle);
398        cartWheel.Image = cartWheelImage;
399        cartWheel.Position = cart.Position + new Vector(-110, -30) * size;
400        cartWheel.CollisionIgnoreGroup = 2;
401        Add(cartWheel);
402        AxleJoint joint = new AxleJoint(cart, cartWheel);
403        Add(joint);
404    }
405
406
407    private void CreateDummy(Vector position, double width, double height, Color color)
408    {
409        PhysicsObject dummy = PhysicsObject.CreateStaticObject(width, height);
410        dummy.Position = position;
411        dummy.Color = color;
412        Add(dummy);
413    }
414
415    void CreatePlayer(Vector position, double width, double height)
416    {
417        HillBilly player = new HillBilly(width, height * 2);
418        player.Shape = Shape.Rectangle;
419        player.Position = position + new Vector(0, height * 0.5);
420        player.Color = Color.White;
421        players.Add(player);
422        startingPlayers.Add(player);
423        Add(player);
424        AddCollisionHandler(player, "burn", delegate(PhysicsObject p, PhysicsObject t) 
425        {
426            HillBilly billy = p as HillBilly;
427            billy.Life.Value--;
428
429        }
430        );
431
432        player.Life.LowerLimit += delegate 
433        { 
434            if (players.Count < 2)
435            {
436                Loss();
437            }
438            players.Remove(player); player.Destroy();
439        };
440    }
441
442    void CreateGroundTop(Vector position, double width, double height)
443    {
444        // Puolet pienempi näkymätön palikka alla johon törmää.
445        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height / 2.0);
446        ground.IsVisible = false;
447        ground.Position = position - new Vector(0.0, TILE_SIZE / 4.0);
448        Add(ground);
449
450        // Maanpinnan näkyvä osa.
451        GameObject visibleGround = new GameObject(width, height);
452        visibleGround.Image = groundImages[levelNumber];
453        visibleGround.Position = position;
454        visibleGround.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
455        Add(visibleGround, -1);
456
457        int probability = RandomGen.NextInt(100);
458        bool wheat = probability < 20;
459
460        if (wheat)
461        {
462            GameObject wheatBlock = new GameObject(width * 1.5, height * 3);
463            wheatBlock.Image = foregroundDecorations[0];
464            wheatBlock.Position = visibleGround.Position;
465            Add(wheatBlock, 2);
466        }
467    }
468
469    void CreateGround(Vector position, double width, double height) 
470    {
471        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height);
472        ground.Image = groundTopImages[levelNumber];
473        ground.Position = position;
474        ground.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
475        Add(ground);
476    }
477    #endregion
478
479    void SetControls()
480    {
481        Keyboard.Listen(Key.A, ButtonState.Down, delegate { startingPlayers[0].Walk(-300); }, "Player 1 moves left");
482        Keyboard.Listen(Key.D, ButtonState.Down, delegate { startingPlayers[0].Walk(300); }, "Player 1 moves right");
483        Keyboard.Listen(Key.W, ButtonState.Down, delegate { startingPlayers[0].Jump(1000); }, "Player 1 jumps");
484
485        Keyboard.Listen(Key.Left, ButtonState.Down, delegate { startingPlayers[1].Walk(-300); }, "Player 2 moves left");
486        Keyboard.Listen(Key.Right, ButtonState.Down, delegate { startingPlayers[1].Walk(300); }, "Player 2 moves right");
487        Keyboard.Listen(Key.Up, ButtonState.Down, delegate { startingPlayers[1].Jump(1000); }, "Player 2 jumps");
488
489        Keyboard.Listen(Key.F1, ButtonState.Pressed, ShowControlHelp, "Show help");
490        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Exit game");
491    }
492
493    void Loss()
494    {
495        //TODO: Sumthin' flashy for our fallen friends.
496        Exit();
497    }
498
499    #region Camera
500    void UpdateCamera()
501    {
502        double minY = players.Min(p => p.Y);
503        double maxY = players.Max(p => p.Y);
504        double minX = players.Min(p => p.X) + cameraOffset;
505
506        Vector minPosition = new Vector(Math.Max(minX, cameraTargetX), minY);
507        Vector maxPosition = new Vector(minX, maxY);
508
509        cameraTarget = (minPosition + maxPosition) * 0.5;
510        cameraTarget.X = Math.Max(cameraTargetX, minX);     //Lellllll.
511
512        //cameraTarget.Y = Math.Max(cameraTarget.X, Level.Bottom + Window.Height/2.0);
513
514        cameraTargetX = Math.Max(cameraTargetX, minX);
515
516        cameraTarget.X = Math.Min(cameraTargetX, rightCamLimit);
517        cameraTarget.Y = Math.Max(cameraTarget.Y, bottomCamLimit);
518
519        double windowMax = Camera.ScreenToWorld(new Vector(Window.Width / 2.0, 0)).X;
520        double windowMin = Camera.ScreenToWorld(new Vector(-Window.Width / 2.0, 0)).X;
521        foreach (var player in players)
522        {
523            player.Left = Math.Max(player.Left, windowMin);
524            player.Right = Math.Min(player.Right, windowMax);
525        }
526    }
527
528    protected override void Update(Time time)
529    {
530        Camera.Position += (cameraTarget - Camera.Position) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
531        //Camera.X += (cameraTargetX - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
532
533
534        base.Update(time);
535    }
536
537    /// <summary>
538    /// Yritän leikkiä kameralla. Vielä varmaan hetken pidempään.
539    /// </summary>
540    /// <param name="gameTime"></param>
541    /*
542    protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
543    {
544        foreach(HillBilly player in players)
545        {
546            playerPositionsX.Add(player.Position.X);
547            playerPositionsY.Add(player.Position.Y);
548        }
549
550        double maxX = playerPositionsX.Max();
551        double maxY = playerPositionsY.Max();
552        double minX = playerPositionsX.Min();
553        double minY = playerPositionsY.Min();
554
555        Vector minPosition = new Vector(minX, minY);
556        Vector maxPosition = new Vector(maxX, maxY);
557
558        Camera.Position = (minPosition + maxPosition) * 0.5;
559
560        playerPositionsX.Clear();
561        playerPositionsY.Clear();
562
563        base.Update(gameTime);
564    }
565     */
566    #endregion
567}
Note: See TracBrowser for help on using the repository browser.