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

Revision 6217, 20.1 KB checked in by sieerinn, 4 years ago (diff)

Kuvia. Kuvia kaikkialla.

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("tonkkaitem");
75   
76    private Image cartWheelImage = LoadImage("cartwheel");
77
78    private Image smokeImage1 = LoadImage("smoke1");
79    private Image smokeImage2 = LoadImage("smoke2");
80
81    private Image forestBackgroundImage = LoadImage("forestbackground");
82
83    private Animation crawl;
84    private Animation blaze;
85
86    private Animation pitchforkAttack;
87    private Animation pitchforkWalk;
88    private Animation milkThrow;
89    private Animation milkWalk;
90    private Animation normalWalk;
91    private Animation playerIdle;
92    #endregion
93
94    private double leftCamLimit;
95    private double rightCamLimit;
96    private double bottomCamLimit;
97
98    private int levelNumber = 0;
99   
100    public override void Begin()
101    {
102        //IntroSequence();
103        //MainMenu();
104        StartGame();
105    }
106
107    #region Intro
108    void IntroSequence()
109    {
110        Level.Background.Color = Color.Black;
111
112        Keyboard.Listen(Key.Escape, ButtonState.Pressed, SkipIntro, "Skip");
113       
114        ShowMadeWithJypeli();
115
116        Timer.SingleShot(4.0, delegate // TODO get rid of fixed amount of seconds
117        {
118            ShowBackgroundStory();
119        });
120       
121
122
123    }
124
125    void ShowMadeWithJypeli()
126    {
127        Image madewithImage = LoadImage("madewithjypeli");
128       
129        double w = Window.Width / 4;
130        double h = w * (madewithImage.Height / (double)madewithImage.Width); // take aspect ratio from the picture
131       
132        GameObject madewithjypeliObject = new GameObject(w, h);
133        madewithjypeliObject.Image = madewithImage;
134        Add(madewithjypeliObject);
135
136        // 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...
137
138        //fadeTimer = new Timer();
139        //fadeTimer.Interval = 0.5;
140        //fadeTimer.Timeout += delegate
141        //{
142        //    madewithjypeliObject.Image = LerpImage(madewithjypeliObject.Image, Color.Black, 0.6);
143        //};
144        //fadeTimer.Start(5);
145       
146        Timer.SingleShot(1.2, delegate
147        {
148            madewithjypeliObject.Destroy();
149        });
150
151    }
152
153    Image LerpImage(Image original, Color targetColor, double ratio)
154    {
155        Image newImage = new Image(original.Width, original.Height, Color.Transparent);
156        for (int y = 0; y < original.Height; y++)
157        {
158            for (int x = 0; x < original.Width; x++)
159            {
160                newImage[y, x] = Color.Lerp(original[y, x], targetColor, ratio);
161            }
162        }
163        return newImage;
164    }
165
166    void ShowBackgroundStory()
167    {
168        Label storyLabel = new Label("Once upon a time...");
169        storyLabel.TextColor = Color.Black;
170        Add(storyLabel);
171
172        Timer textTimer = new Timer();
173        textTimer.Interval = 0.1;
174        textTimer.Timeout += delegate
175        {
176            // lightens text up:
177            storyLabel.TextColor = Color.Lerp(storyLabel.TextColor, Color.Gray, 0.1);
178        };
179        textTimer.Start();
180        // TODO siirrä aliohjelmaan, jolle voi antaa parametrina stringin, joka näytetään siististi feidaamalla esille
181
182        // TODO lisää koko pelin tarina usealla feidailevalla tekstinpätkällä esitettynä
183
184        // Clean up after the intro:
185        Timer.SingleShot(5, delegate // TODO get rid of this fixed amount of seconds
186        { // TODO replace this SingleShot with something else. It must be the last thing after the intro sequence
187            storyLabel.Destroy();
188
189            ClearAll();
190            MainMenu();
191        });
192    }
193
194    void SkipIntro()
195    {
196        ClearTimers();
197        ClearAll();
198        Keyboard.Clear();
199        MainMenu();
200    }
201
202    void MainMenu()
203    {
204        Level.Background.Color = Color.DarkBlue;
205
206        MultiSelectWindow mainmenu = new MultiSelectWindow("Main menu",
207"Start game", "Credits", "Exit");
208        mainmenu.AddItemHandler(0, StartGame);
209        mainmenu.AddItemHandler(1, ShowCredits);
210        mainmenu.AddItemHandler(2, Exit);
211        mainmenu.DefaultCancel = 2;
212        Add(mainmenu);
213    }
214
215    void ShowCredits()
216    {
217        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");
218        win.Closed += delegate
219        {
220            ClearAll();
221            MainMenu();
222        };
223        Add(win);
224    }
225    #endregion
226
227    void StartGame()
228    {
229        Initializing();
230        CreateLevel();
231        ScreenSettings();
232
233        // Taustatestailua.
234        GameObject forestBackground = new GameObject(Level.Width, Level.Height);
235        forestBackground.Image = forestBackgroundImage;
236        forestBackground.TextureWrapSize = new Vector(5, 1);
237        Add(forestBackground, -3);
238        Layers[-3].RelativeTransition = new Vector(0.5, 1.0);
239        Level.Background.CreateGradient(Color.Black, Color.SkyBlue);
240
241        // Testailen tässä kärryn luomista.
242        //double size = 0.7;
243        //PhysicsObject cart = new PhysicsObject(400 * size, 80 * size);
244        //cart.X = -1600;
245        //cart.Y = 200;
246        //cart.Image = cartImage;
247        //cart.CollisionIgnoreGroup = 2;
248        //Add(cart);
249        //PhysicsObject cartWheel = new PhysicsObject(160 * size, 160 * size, Shape.Circle);
250        //cartWheel.Image = cartWheelImage;
251        //cartWheel.Position = cart.Position + new Vector(-110, -30) * size;
252        //cartWheel.CollisionIgnoreGroup = 2;
253        //Add(cartWheel);
254        //AxleJoint joint = new AxleJoint(cart, cartWheel);
255        //Add(joint);
256    }
257
258    void Initializing()
259    {
260        crawl = LoadAnimation("crawl");
261        blaze = LoadAnimation("flame");
262        pitchforkAttack = LoadAnimation("attack");
263        pitchforkWalk = LoadAnimation("hanko");
264        milkThrow = LoadAnimation("heitto");
265        milkWalk = LoadAnimation("tonkka");
266        normalWalk = LoadAnimation("pwalk");
267        playerIdle = LoadAnimation("idle");
268    }
269
270    void ScreenSettings()
271    {
272        Window.Width = 1800;
273        Window.Height = 900;
274
275        leftCamLimit = Level.Left + Window.Width / 2.0;
276        rightCamLimit = Level.Right - Window.Width / 2.0;
277        bottomCamLimit = Level.Bottom + Window.Height / 2.0;
278
279        //Camera.X = cameraTargetX = players[0].X;
280        //Camera.ZoomToLevel();
281        Camera.X = cameraTargetX = leftCamLimit;
282
283        Timer cameraTimer = new Timer();
284        cameraTimer.Interval = 1 / 30.0;
285        cameraTimer.Timeout += UpdateCamera;
286        cameraTimer.Start();
287    }
288
289    #region LevelCreation
290    void CreateLevel()
291    {
292        Gravity = new Vector(0, -1000);
293
294        ColorTileMap level = ColorTileMap.FromLevelAsset("level" + levelNumber);
295        level.SetTileMethod(Color.Black, CreateGroundTop);
296        level.SetTileMethod(Color.Brown, CreateGround);
297
298        level.SetTileMethod(Color.Cyan, CreateHouse);
299        level.SetTileMethod(Color.PaintDotNetBlue, CreateBurnedHouse);
300
301        level.SetTileMethod(Color.Gold, CreatePlayer);
302        level.SetTileMethod(Color.Harlequin, CreateCart);
303        level.SetTileMethod(Color.White, CreateBlockObject); 
304        level.SetTileMethod(Color.DarkGray, CreateMilk);   
305        level.SetTileMethod(Color.Gray, CreateCrawly);
306        level.SetTileMethod(Color.Red, CreateDummy, Color.Red);    //TODO: CreateWitch
307        level.SetTileMethod(Color.Rose, CreateFlame);   
308        //level.SetTileMethod(Color.Azure, CreateDummy, Color.Azure);   //TODO: CreateSmoke
309        //level.SetTileMethod(Color.Orange, CreateDummy, Color.Orange); //TODO: CreateTombstone
310        level.Optimize(Color.Black, Color.Brown);
311        level.Execute(TILE_SIZE, TILE_SIZE);
312       
313
314        //TileMap level = TileMap.FromLevelAsset("level" + levelNumber);
315        //level.SetTileMethod('P', CreatePlayer);
316        //level.SetTileMethod('#', CreateGroundTop);
317        //level.SetTileMethod('%', CreateGround);
318        //level.Optimize('#', '%');
319        //level.Execute(TILE_SIZE, TILE_SIZE);
320        //Level.CreateBorders(true);
321
322        SetControls();
323    }
324
325    void CreateFlame(Vector position, double width, double height)
326    {
327        PhysicsObject flame = PhysicsObject.CreateStaticObject(width, height * 2);
328        //flame.Image = flameImage;
329        flame.Color = Color.Red;
330        double hieman = height * 0.3;
331        flame.Position = position - new Vector(0, hieman);
332        flame.CollisionIgnoreGroup = 3;
333        flame.Tag = "burn";
334        flame.Animation = new Animation(blaze) { FPS = RandomGen.NextInt(20, 26) };
335        flame.Animation.Step(RandomGen.NextInt(0, 12));
336        flame.Animation.Resume();
337        Add(flame);
338
339        Smoke savu = new Smoke();
340        savu.ParticleImage = smokeImage1;
341        savu.OuterParticleImage = smokeImage2;
342        savu.MaxLifetime = 1.0;
343        savu.MaxScale = 200;
344        savu.MinScale = 10;
345        savu.Position = flame.Position;
346        Wind = new Vector(-10, 0);
347        Add(savu);
348    }
349
350    void CreateBlockObject(Vector position, double width, double height)
351    {
352        PhysicsObject block = PhysicsObject.CreateStaticObject(width, height);
353        block.Image = blockImages[levelNumber];
354        block.Position = position;
355        Add(block);
356    }
357
358    void CreateMilk(Vector position, double width, double height)
359    {
360        GameObject milk = new GameObject(milkImage.Width, milkImage.Height);
361        milk.Image = milkImage;
362        milk.Position = position;
363        milk.Tag = "milk";
364        Add(milk);
365    }
366
367    void CreateCrawly(Vector position, double width, double height)
368    {
369        PlatformCharacter crawly = new PlatformCharacter(width * 2, height);
370        crawly.Position = position;
371        crawly.Color = Color.Gray;
372        crawly.Animation = crawl;
373        crawly.Animation.Start();
374        crawly.Tag = "burn";
375        crawly.CollisionIgnoreGroup = 3;
376        Add(crawly);
377
378        PlatformWandererBrain brain = new PlatformWandererBrain();
379        brain.Speed = 20;
380        brain.FallsOffPlatforms = true;
381
382        crawly.Brain = brain;
383    }
384
385    void CreateHouse(Vector position, double width, double height)
386    {
387        // Näkyvä talo
388        GameObject house = new GameObject(width * 10, height * 8);
389        house.Image = houseImages[0];
390        house.Position = position - new Vector(0, height * 2.5);
391        Add(house, -2);
392
393        //Seisottava tasanne
394        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width - (TILE_SIZE * 3.25), 1);     //Tätä kohtaa on nyt vähän hakemalla haettu.
395        platform.IsVisible = false;
396        platform.Position = new Vector(house.X + (TILE_SIZE * 0.5), house.Top);
397        Add(platform);
398    }
399
400    void CreateBurnedHouse(Vector position, double width, double height)
401    {
402        GameObject house = new GameObject(width * 10, height * 8);
403        house.Image = houseImages[1];
404        house.Position = position - new Vector(0, height * 2.5);
405        Add(house, -2);
406
407        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width* 0.25, 1);
408        platform.IsVisible = false;
409        platform.Position = new Vector(house.X + platform.Width * 0.5, house.Top);
410        Add(platform);
411    }
412
413    private void CreateCart(Vector position, double width, double height)
414    {
415        double size = 0.7;
416        PhysicsObject cart = new PhysicsObject(400 * size, 80 * size);
417        cart.Position = position;
418        cart.Image = cartImage;
419        cart.CollisionIgnoreGroup = 2;
420        Add(cart);
421        PhysicsObject cartWheel = new PhysicsObject(160 * size, 160 * size, Shape.Circle);
422        cartWheel.Image = cartWheelImage;
423        cartWheel.Position = cart.Position + new Vector(-110, -30) * size;
424        cartWheel.CollisionIgnoreGroup = 2;
425        Add(cartWheel);
426        AxleJoint joint = new AxleJoint(cart, cartWheel);
427        Add(joint);
428    }
429
430
431    private void CreateDummy(Vector position, double width, double height, Color color)
432    {
433        PhysicsObject dummy = PhysicsObject.CreateStaticObject(width, height);
434        dummy.Position = position;
435        dummy.Color = color;
436        Add(dummy);
437    }
438
439    void CreatePlayer(Vector position, double width, double height)
440    {
441        HillBilly player = new HillBilly(width, height * 2);
442        player.Shape = Shape.Rectangle;
443        player.Position = position + new Vector(0, height * 0.5);
444        player.Color = Color.White;
445        player.AnimWalk = new Animation(normalWalk);
446        player.AnimIdle = new Animation(playerIdle);
447        players.Add(player);
448        startingPlayers.Add(player);
449        Add(player);
450        AddCollisionHandler(player, "burn", delegate(PhysicsObject p, PhysicsObject t) 
451        {
452            HillBilly billy = p as HillBilly;
453            billy.Life.Value--;
454
455        });
456
457        player.Life.LowerLimit += delegate 
458        { 
459            if (players.Count < 2)
460            {
461                Loss();
462            }
463            players.Remove(player); player.Destroy();
464        };
465    }
466
467    void CreateGroundTop(Vector position, double width, double height)
468    {
469        // Puolet pienempi näkymätön palikka alla johon törmää.
470        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height / 2.0);
471        ground.IsVisible = false;
472        ground.Position = position - new Vector(0.0, TILE_SIZE / 4.0);
473        Add(ground);
474
475        // Maanpinnan näkyvä osa.
476        GameObject visibleGround = new GameObject(width, height);
477        visibleGround.Image = groundImages[levelNumber];
478        visibleGround.Position = position;
479        visibleGround.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
480        Add(visibleGround, -1);
481
482        int probability = RandomGen.NextInt(100);
483        bool wheat = probability < 20;
484
485        if (wheat)
486        {
487            GameObject wheatBlock = new GameObject(width * 1.5, height * 2);
488            wheatBlock.Image = foregroundDecorations[0];
489            wheatBlock.X = visibleGround.X;
490            wheatBlock.Bottom = visibleGround.Bottom;
491            wheatBlock.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
492            Add(wheatBlock, 2);
493        }
494    }
495
496    void CreateGround(Vector position, double width, double height) 
497    {
498        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height);
499        ground.Image = groundTopImages[levelNumber];
500        ground.Position = position;
501        ground.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
502        Add(ground);
503    }
504    #endregion
505
506    void SetControls()
507    {
508        double speed = 180; // TODO: Siirrä tämä johonkin.
509        Keyboard.Listen(Key.A, ButtonState.Down, delegate { startingPlayers[0].Walk(-speed); }, "Player 1 moves left");
510        Keyboard.Listen(Key.D, ButtonState.Down, delegate { startingPlayers[0].Walk(speed); }, "Player 1 moves right");
511        Keyboard.Listen(Key.W, ButtonState.Down, delegate { startingPlayers[0].Jump(1000); }, "Player 1 jumps");
512
513        Keyboard.Listen(Key.Left, ButtonState.Down, delegate { startingPlayers[1].Walk(-speed); }, "Player 2 moves left");
514        Keyboard.Listen(Key.Right, ButtonState.Down, delegate { startingPlayers[1].Walk(speed); }, "Player 2 moves right");
515        Keyboard.Listen(Key.Up, ButtonState.Down, delegate { startingPlayers[1].Jump(1000); }, "Player 2 jumps");
516
517        Keyboard.Listen(Key.F1, ButtonState.Pressed, ShowControlHelp, "Show help");
518        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Exit game");
519    }
520
521    void Loss()
522    {
523        //TODO: Sumthin' flashy for our fallen friends.
524        Exit();
525    }
526
527    #region Camera
528    void UpdateCamera()
529    {
530        double minY = players.Min(p => p.Y);
531        double maxY = players.Max(p => p.Y);
532        double minX = players.Min(p => p.X) + cameraOffset;
533
534        Vector minPosition = new Vector(Math.Max(minX, cameraTargetX), minY);
535        Vector maxPosition = new Vector(minX, maxY);
536
537        cameraTarget = (minPosition + maxPosition) * 0.5;
538        cameraTarget.X = Math.Max(cameraTargetX, minX);     //Lellllll.
539
540        //cameraTarget.Y = Math.Max(cameraTarget.X, Level.Bottom + Window.Height/2.0);
541
542        cameraTargetX = Math.Max(cameraTargetX, minX);
543
544        cameraTarget.X = Math.Min(cameraTargetX, rightCamLimit);
545        cameraTarget.Y = Math.Max(cameraTarget.Y, bottomCamLimit);
546
547        double windowMax = Camera.ScreenToWorld(new Vector(Window.Width / 2.0, 0)).X;
548        double windowMin = Camera.ScreenToWorld(new Vector(-Window.Width / 2.0, 0)).X;
549        foreach (var player in players)
550        {
551            player.Left = Math.Max(player.Left, windowMin);
552            player.Right = Math.Min(player.Right, windowMax);
553        }
554    }
555
556    protected override void Update(Time time)
557    {
558        Camera.Position += (cameraTarget - Camera.Position) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
559        //Camera.X += (cameraTargetX - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
560
561
562        base.Update(time);
563    }
564
565    /// <summary>
566    /// Yritän leikkiä kameralla. Vielä varmaan hetken pidempään.
567    /// </summary>
568    /// <param name="gameTime"></param>
569    /*
570    protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
571    {
572        foreach(HillBilly player in players)
573        {
574            playerPositionsX.Add(player.Position.X);
575            playerPositionsY.Add(player.Position.Y);
576        }
577
578        double maxX = playerPositionsX.Max();
579        double maxY = playerPositionsY.Max();
580        double minX = playerPositionsX.Min();
581        double minY = playerPositionsY.Min();
582
583        Vector minPosition = new Vector(minX, minY);
584        Vector maxPosition = new Vector(maxX, maxY);
585
586        Camera.Position = (minPosition + maxPosition) * 0.5;
587
588        playerPositionsX.Clear();
589        playerPositionsY.Clear();
590
591        base.Update(gameTime);
592    }
593     */
594    #endregion
595}
Note: See TracBrowser for help on using the repository browser.