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

Revision 6383, 37.2 KB checked in by empaheik, 5 years ago (diff)

Parannukset voi pudotella + poimia uudelleen epämääräisillä painikkeilla.

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#region Improvement
27public abstract class Improvement : PlatformCharacter
28{
29    public List<Animation> Animations { get; set; }
30
31    protected Improvement(double width, double height)
32        : base(width, height)
33    {
34
35    }
36
37    public HillBilly Owner
38    {
39        get { return owner; }
40        set { owner = value; }
41    }
42    private HillBilly owner;
43
44    public virtual void DoTheThing(HillbillyRun game) { }
45
46    public SoundEffect sound;
47
48    public void Rid()
49    {
50        Owner.AnimWalk = Owner.Animations[0];
51        Owner.AnimIdle = Owner.Animations[1];
52        Owner.Improvement = null;
53        Owner = null;
54    }
55}
56
57public class MilkImprovement : Improvement
58{
59    public override void DoTheThing(HillbillyRun game)
60    {
61        //HillbillyRun game = this.Game as HillbillyRun;
62        Owner.PlayAnimation(Animations[1]);
63        game.CreateMilkParticles(this.Owner, 10, 200, 300, new Vector(0, -30), "milkparticle");
64        this.sound.Play();
65    }
66
67    public MilkImprovement(double width, double height)
68        : base(width, height)
69    {
70
71    }
72}
73
74
75public class PitchForkImprovement : Improvement
76{
77    public override void DoTheThing(HillbillyRun game)
78    {
79        //HillbillyRun game = this.Game as HillbillyRun;
80        //game.CreateMilkParticles(this.Owner, 10, 200, 300, new Vector(0, -30), "milkparticle");
81        //TODO: hitting things w/ pitchfork
82        game.ForkThings(Owner);
83    }
84
85    public PitchForkImprovement(double width, double height)
86        : base(width, height)
87    {
88
89    }
90}
91#endregion
92
93public class HillBilly : PlatformCharacter
94{
95    public List<Animation> Animations { get; set; }
96
97    private IntMeter lifeCounter = new IntMeter(4, 0, 4);
98    public IntMeter Life
99    {
100        set { lifeCounter = value; }
101        get { return lifeCounter; }
102    }
103
104    public Improvement Improvement { get; set; }
105
106    public Label Name { get; set; }
107
108    private ProgressBar visibleLife;
109    public ProgressBar VisibleLife
110    {
111        get { return visibleLife; }
112        set { visibleLife = value; }
113    }
114
115    public void GainImprovement(Improvement improvement)
116    {
117
118        this.AnimWalk = improvement.Animations[0];
119        this.AnimIdle = new Animation(improvement.Animations[0].CurrentFrame);
120        this.Improvement = improvement;
121        improvement.Owner = this;
122
123        //improvement.Destroy();
124    }
125
126    public void UseImprovement()
127    {
128        HillbillyRun game = this.Game as HillbillyRun;
129        if (this.Improvement == null)
130        {
131            game.CreateMilkParticles(this, 5, 100, 100, new Vector(0, Height / 3), "tears");
132        }
133        else if (Animation != this.Improvement.Animations[1])
134        {
135            this.Improvement.DoTheThing(game);
136        }
137    }
138
139    public HillBilly(double leveys, double korkeus, String name)
140        : base(leveys, korkeus)
141    {
142
143        this.visibleLife = new ProgressBar(50, 15); //(this.Width, this.Height/8);
144        this.Add(visibleLife);
145        this.visibleLife.Position += new Vector(0, this.Height / 2 + this.Height / 5);
146        this.visibleLife.BindTo(this.lifeCounter);
147        this.visibleLife.Color = Color.Black;
148
149        this.Name = new Label(name);
150        this.Add(Name);
151        this.Name.Position += new Vector(0, this.Height / 2 + this.Height / 3);
152    }
153}
154
155/// <summary>
156/// An MMO where you go to war with mages in the lava kingdom.
157/// </summary>
158public class HillbillyRun : PhysicsGame
159{
160    private List<HillBilly> players = new List<HillBilly>();
161    private List<HillBilly> startingPlayers = new List<HillBilly>();
162
163    //private List<double> playerPositionsX = new List<double>();
164    //private List<double> playerPositionsY = new List<double>();
165
166    private const double PLAYER_SPEED = 180;
167    public const double TILE_SIZE = 70;
168
169    public String[] names = new String[] { "Adolfiina", "Rasputiina", "Hermanniina", "Joosefiina"};
170       
171    private double cameraTargetX; // Sijainti jossa kameran pitäisi olla.
172    private Vector cameraTarget;
173
174    private double cameraOffset; //= 400; // TODO: Tämän voisi ehkä laskea jostain (esim. ikkunan leveydestä kolmasosa tai jotain).
175    private double cameraSpeed = 2.0; // Kameran liikkumisnopeus.
176
177    # region Images
178    private Image[] groundImages = LoadImages("ground", "ground_forest");    //Näitä ei tosin kaikkia kenties jaksa tehdä erilaisiksi levelistä riippuen
179    private Image[] groundTopImages = LoadImages("ground_top", "ground_top_forest");
180    private Image[] foregroundDecorations = LoadImages("viljaa", "grass");
181    private Image[] blockImages = LoadImages("box2", "rock");
182
183    private Image[] houseImages = LoadImages("house", "houseburned");
184
185    private Image cartImage = LoadImage("cart");
186    private Image milkImage = LoadImage("tonkkaitem");
187    private Image pitchforkImage = LoadImage("fork");
188
189    private Image cartWheelImage = LoadImage("cartwheel");
190
191    private Image smokeImage1 = LoadImage("smoke1");
192    private Image smokeImage2 = LoadImage("smoke2");
193
194    private Image treeTrunkImage = LoadImage("bigtree");
195    private Image treeBottomImage = LoadImage("bigtree3x2");
196    private Image treeBranchImage = LoadImage("bigtreebranch");
197    private Image forestBackgroundImage = LoadImage("forestbackground");
198
199    private Animation crawl;
200    private Animation blaze;
201
202    private Animation pitchforkAttack;
203    private Animation pitchforkWalk;
204    private Animation milkThrow;
205    private Animation milkWalk;
206    private Animation normalWalk;
207    private Animation playerIdle;
208    private Animation playerJump;
209    private Animation playerFall;
210    private Animation firemageAnimation;
211    private Animation firemageCastAnimation;
212    private Animation wormAnimation;
213    #endregion
214
215    #region Sounds
216    private SoundEffect splash = LoadSoundEffect("splash");
217    #endregion
218
219    private double leftCamLimit;
220    private double rightCamLimit;
221    private double bottomCamLimit;
222
223    private int levelNumber = 0;
224
225    public override void Begin()
226    {
227        Initializing();
228        //IntroSequence();
229        //MainMenu();
230        StartGame();
231    }
232
233    #region Intro
234    void IntroSequence()
235    {
236        Level.Background.Color = Color.Black;
237
238        Keyboard.Listen(Key.Escape, ButtonState.Pressed, SkipIntro, "Skip");
239
240        ShowMadeWithJypeli();
241
242        Timer.SingleShot(4.0, delegate // TODO get rid of fixed amount of seconds
243        {
244            ShowBackgroundStory();
245        });
246
247
248
249    }
250
251    void ShowMadeWithJypeli()
252    {
253        Image madewithImage = LoadImage("madewithjypeli");
254
255        double w = Window.Width / 4;
256        double h = w * (madewithImage.Height / (double)madewithImage.Width); // take aspect ratio from the picture
257
258        GameObject madewithjypeliObject = new GameObject(w, h);
259        madewithjypeliObject.Image = madewithImage;
260        Add(madewithjypeliObject);
261
262        // 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...
263
264        //fadeTimer = new Timer();
265        //fadeTimer.Interval = 0.5;
266        //fadeTimer.Timeout += delegate
267        //{
268        //    madewithjypeliObject.Image = LerpImage(madewithjypeliObject.Image, Color.Black, 0.6);
269        //};
270        //fadeTimer.Start(5);
271
272        Timer.SingleShot(1.2, delegate
273        {
274            madewithjypeliObject.Destroy();
275        });
276
277    }
278
279    Image LerpImage(Image original, Color targetColor, double ratio)
280    {
281        Image newImage = new Image(original.Width, original.Height, Color.Transparent);
282        for (int y = 0; y < original.Height; y++)
283        {
284            for (int x = 0; x < original.Width; x++)
285            {
286                newImage[y, x] = Color.Lerp(original[y, x], targetColor, ratio);
287            }
288        }
289        return newImage;
290    }
291
292    void ShowBackgroundStory()
293    {
294        ShowStoryText(new Queue<string>(new[] { "Once upon a time...", "...blaa blaa blaa.", "Blaa." }));
295    }
296
297    void ShowStoryText(Queue<string> messages)
298    {
299        // Mennään alkuvalikkoon jos ei ole enää viestejä.
300        if (messages.Count == 0)
301        {
302            MainMenu();
303            return;
304        }
305
306        // Näytetään nykyinen viesti.
307        var storyLabel = new Label(messages.Dequeue()) { TextColor = Color.Black, TextScale = new Vector(3, 3) };
308        Add(storyLabel);
309
310        var textTimer = new Timer { Interval = 0.05 };
311        textTimer.Timeout += () => storyLabel.TextColor = Color.Lerp(storyLabel.TextColor, Color.White, 0.05);
312        textTimer.Start();
313
314        // Näytetään seuraava viesti muutaman sekunnin päästä.
315        Timer.SingleShot(4, delegate { storyLabel.Destroy(); ShowStoryText(messages); });
316    }
317
318    void SkipIntro()
319    {
320        ClearTimers();
321        ClearAll();
322        Keyboard.Clear();
323        MainMenu();
324    }
325
326    void MainMenu()
327    {
328        Level.Background.Color = Color.DarkBlue;
329
330        MultiSelectWindow mainmenu = new MultiSelectWindow("Main menu",
331"Start game", "Credits", "Exit");
332        mainmenu.AddItemHandler(0, StartGame);
333        mainmenu.AddItemHandler(1, ShowCredits);
334        mainmenu.AddItemHandler(2, Exit);
335        mainmenu.DefaultCancel = 2;
336        Add(mainmenu);
337    }
338
339    void ShowCredits()
340    {
341        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");
342        win.Closed += delegate
343        {
344            ClearAll();
345            MainMenu();
346        };
347        Add(win);
348    }
349    #endregion
350
351    void StartGame()
352    {
353        ClearAll();
354        CreateLevel();
355        ScreenSettings();
356        SetControls();
357    }
358
359    public void NextLevel()
360    {
361        levelNumber++;
362        StartGame();
363    }
364
365    void Initializing()
366    {
367        crawl = LoadAnimation("crawl");
368        blaze = LoadAnimation("flame");
369        pitchforkAttack = LoadAnimation("attack");
370        pitchforkWalk = LoadAnimation("hanko");
371        milkThrow = LoadAnimation("heitto");
372        milkWalk = LoadAnimation("tonkka");
373        normalWalk = LoadAnimation("pwalk");
374        playerIdle = LoadAnimation("idle");
375        playerJump = LoadAnimation("jump");
376        playerFall = LoadAnimation("fall");
377        firemageAnimation = LoadAnimation("firemage");
378        firemageCastAnimation = LoadAnimation("firemagecast");
379        wormAnimation = LoadAnimation("worm");
380
381        cameraOffset = Window.Width / 4;
382    }
383
384    void ScreenSettings()
385    {
386        Window.Width = 1800;
387        Window.Height = 900;
388
389        leftCamLimit = Level.Left + Window.Width / 2.0;
390        rightCamLimit = Level.Right - Window.Width / 2.0;
391        bottomCamLimit = Level.Bottom + Window.Height / 2.0;
392
393        Camera.X = cameraTargetX = leftCamLimit;
394
395        Timer cameraTimer = new Timer();
396        cameraTimer.Interval = 1 / 30.0;
397        cameraTimer.Timeout += UpdateCamera;
398        cameraTimer.Start();
399
400        //Background
401        GameObject forestBackground = new GameObject(Level.Width, Level.Height);
402        forestBackground.Image = forestBackgroundImage;
403        forestBackground.TextureWrapSize = new Vector(5, 1);
404        Add(forestBackground, -3);
405        Layers[-3].RelativeTransition = new Vector(0.5, 1.0);
406
407        if (levelNumber == 1)
408        {
409            Level.Background.CreateGradient(Color.Black, Color.FromHexCode("495147"));
410        }
411        else
412        {
413            Level.Background.CreateGradient(Color.Black, Color.SkyBlue);
414        }
415    }
416
417    #region LevelCreation
418    void CreateLevel()
419    {
420        startingPlayers.Clear();
421        players.Clear();
422        Gravity = new Vector(0, -1000);
423
424        //Tilemap
425        ColorTileMap level = ColorTileMap.FromLevelAsset("level" + levelNumber);
426        level.SetTileMethod(Color.Black, CreateGroundTop);
427        level.SetTileMethod(Color.Brown, CreateGround);
428
429        level.SetTileMethod(Color.Cyan, CreateHouse);
430        level.SetTileMethod(Color.PaintDotNetBlue, CreateBurnedHouse);
431
432        level.SetTileMethod(Color.Gold, CreatePlayer);
433        level.SetTileMethod(Color.Harlequin, CreateCart);
434        level.SetTileMethod(Color.White, CreateBlockObject);
435        //level.SetTileMethod(Color.DarkGray, (new AbstractTileMap<Color>.TileMethod[] { CreateMilk, CreatePitchfork })[levelNumber]);  // Vain jos jaksan vippastaa maitokannun pysymään mukana ClearAllin läpi hmm
436        level.SetTileMethod(Color.DarkGray, CreateMilk);
437        level.SetTileMethod(Color.FromHexCode("A17FFF"), CreatePitchfork);
438
439        level.SetTileMethod(Color.Gray, (new AbstractTileMap<Color>.TileMethod[] { CreateCrawly, CreateWorm })[levelNumber]); // ಠ_ಠ
440        level.SetTileMethod(Color.Red, CreateFireMage);
441        level.SetTileMethod(Color.Rose, CreateFlame, true);
442        //level.SetTileMethod(Color.Azure, CreateDummy, Color.Azure);   //TODO: CreateSmoke
443        //level.SetTileMethod(Color.Orange, CreateDummy, Color.Orange); //TODO: CreateTombstone
444
445        level.SetTileMethod(Color.FromHexCode("FF6A00"), CreateTreeTrunk);  //Pihhh jostain heksoista. Ikävästi haisee luovuttamiselta! :----D
446        level.SetTileMethod(Color.FromHexCode("57007F"), CreateTreeRoot);
447        level.SetTileMethod(Color.FromHexCode("00FF21"), CreateTreeBranch);
448
449        level.Optimize(Color.Brown);    //Color.Black   //Tekee jännittäviä asioita wheatille, jos optimoidaan (tietysti). Jotenn.
450
451        level.Execute(TILE_SIZE, TILE_SIZE);
452    }
453
454    void CreatePitchfork(Vector position, double width, double height)
455    {
456        double size = 30;
457        double ratio = pitchforkImage.Width / pitchforkImage.Height;
458
459        Improvement fork = new PitchForkImprovement(size * ratio, size);
460        fork.Image = pitchforkImage;
461        fork.Animations = new List<Animation> { pitchforkWalk, pitchforkAttack };
462        fork.Position = position;
463        fork.Tag = "improvement";
464        Add(fork);
465
466    }
467
468    void CreateTreeBranch(Vector position, double width, double height)
469    {
470        PhysicsObject branch = PhysicsObject.CreateStaticObject(width, height);
471        branch.Position = position;
472        branch.Image = treeBranchImage;
473        Add(branch, -1);
474    }
475
476    void CreateTreeTrunk(Vector position, double width, double height)
477    {
478        GameObject trunk = new GameObject(width * 3, height);
479        trunk.Position = position;
480        trunk.Image = treeTrunkImage;
481        Add(trunk, -1);
482    }
483
484    void CreateTreeRoot(Vector position, double width, double height)
485    {
486        GameObject roots = new GameObject(width * 9, height * 4);
487        roots.Position = position;
488        roots.Y -= height;
489        roots.Image = treeBottomImage;
490        Add(roots, -1);
491    }
492   
493    void CreateFlame(Vector position, double width, double height, bool suuri)
494    {
495        PhysicsObject flame = new PhysicsObject(width, height * 2);
496        //flame.Image = flameImage;
497        flame.Color = Color.Red;
498        double hieman = height * 0.3;
499        flame.Position = position - new Vector(0, hieman);
500        flame.CollisionIgnoreGroup = 3;
501        flame.Tag = "burn";
502        flame.Animation = new Animation(blaze) { FPS = RandomGen.NextInt(20, 26) };
503        flame.Animation.Step(RandomGen.NextInt(0, 12));
504        flame.Animation.Resume();
505        flame.CanRotate = false;
506        Add(flame, 1);
507
508        Smoke savu = new Smoke();
509        if (suuri)
510        {
511            flame.IgnoresCollisionResponse = true;
512
513            savu.ParticleImage = smokeImage1;
514            savu.OuterParticleImage = smokeImage2;
515            savu.MaxLifetime = 1.0;
516            savu.MaxScale = 200;
517            savu.MinScale = 10;
518            savu.Position = flame.Position;
519            Wind = new Vector(-10, 0);
520            Add(savu);
521            flame.MakeStatic();
522        }
523
524        AddCollisionHandler(flame, "milkparticle", delegate(PhysicsObject c, PhysicsObject particle)
525        {
526            particle.Destroy();
527            flame.Destroy();
528            savu.Destroy();
529
530        });
531    }
532
533    void CreateBlockObject(Vector position, double width, double height)
534    {
535        // Säädin vähän tätä jotta laatikko näkyy hyvin. Pitää ehkä tehdä laatikolle ihan oma metodi.
536        PhysicsObject block = PhysicsObject.CreateStaticObject(width, height);
537        block.IsVisible = false;
538        //block.Image = blockImages[levelNumber];
539        block.Position = position;
540        block.Y -= height / 2.0;
541        Add(block, 1);
542
543        GameObject visibleBlock = new GameObject(width, height * 1.5);
544        visibleBlock.Position = position;
545        visibleBlock.Image = blockImages[levelNumber];
546        visibleBlock.Y -= height / 2.0;
547        Add(visibleBlock, -1);
548    }
549
550    void CreateMilk(Vector position, double width, double height)
551    {
552        double size = 30;
553        double ratio = milkImage.Height / milkImage.Width;
554
555        Improvement milk = new MilkImprovement(size, size * ratio);
556        milk.Image = milkImage;
557        milk.Animations = new List<Animation> { milkWalk, milkThrow };
558        milk.Position = position;
559        //milk.Tag = "milk";
560        milk.Tag = "improvement";
561        milk.sound = splash;
562        Add(milk);
563
564        //PhysicsObject milk = new PhysicsObject(size, size * ratio);
565        //milk.Image = milkImage;
566        //milk.Position = position;
567        //milk.Tag = "milk";
568        //Add(milk);
569    }
570
571    void CreateWorm(Vector position, double width, double height)
572    {
573        PlatformCharacter worm = new PlatformCharacter(width, height * 0.6);
574        worm.Position = position;
575        worm.Animation = new Animation(wormAnimation);
576        worm.Animation.FPS = RandomGen.NextInt(18, 24);
577        worm.Animation.Step(RandomGen.NextInt(0, 16));
578        worm.Animation.Resume();
579        worm.Tag = "worm";
580        worm.CollisionIgnoreGroup = 3;
581        Add(worm, 1);
582
583        PlatformWandererBrain brain = new PlatformWandererBrain();
584        brain.Speed = 60;
585        brain.FallsOffPlatforms = false;
586        worm.Brain = brain;
587
588        AddCollisionHandler(worm, "pitchfork", delegate(PhysicsObject w, PhysicsObject p) { w.Destroy(); });
589    }
590
591    void CreateCrawly(Vector position, double width, double height)
592    {
593        PlatformCharacter crawly = new PlatformCharacter(width * 2, height * 0.6);
594        crawly.Position = position;
595        crawly.Color = Color.Gray;
596        crawly.Animation = new Animation(crawl);
597        crawly.Animation.FPS = RandomGen.NextInt(18, 24);
598        crawly.Animation.Step(RandomGen.NextInt(0, 16));
599        crawly.Animation.Resume();
600        crawly.Tag = "burn";
601        crawly.CollisionIgnoreGroup = 3;
602        Add(crawly, 1);
603
604        GameObject flame = new GameObject(width * 1.4, height * 2);
605        flame.Animation = new Animation(blaze) { FPS = RandomGen.NextInt(20, 26) };
606        flame.Animation.Step(RandomGen.NextInt(0, 12));
607        flame.Animation.Resume();
608        Add(flame);
609
610        // Pakko liikutella näin koska lapsioliona liekki näkyisi ryömijän päällä.
611        Timer flameMover = new Timer { Interval = 0.05 };
612        flameMover.Timeout += delegate
613        {
614            double hieman = height * 0.75;
615            flame.Position = crawly.Position + new Vector(0, hieman);
616        };
617        flameMover.Start();
618
619        PlatformWandererBrain brain = new PlatformWandererBrain();
620        brain.Speed = 20;
621        brain.FallsOffPlatforms = true;
622
623        crawly.Brain = brain;
624
625        // Sammuu törmätessään maitoon.
626        AddCollisionHandler(crawly, "milkparticle", delegate(PhysicsObject c, PhysicsObject particle)
627        {
628            particle.Destroy();
629            crawly.Brain = null;
630            crawly.Animation = new Animation(crawly.Animation.CurrentFrame);
631            crawly.Tag = "";
632            flame.Destroy();
633            RemoveCollisionHandlers(crawly);
634        });
635    }
636
637    void CreateFireMage(Vector position, double width, double height)
638    {
639        PlatformCharacter mage = new PlatformCharacter(width * 3, height * 4);
640        mage.Position = position;
641        mage.Y += mage.Height / 2.0;
642        mage.Tag = "burn";
643        mage.Tag += "fireMage";
644        mage.AnimWalk = new Animation(firemageAnimation);
645        mage.CollisionIgnoreGroup = 3;
646        Add(mage, 1);
647        bool immune = false;
648
649        // Pään päällä oleva liekki (taitaa olla vähän huonossa kohtaa tällä hetkellä)
650        PhysicsObject flame = new PhysicsObject(width * 1.4, height * 2);
651        flame.Y += mage.Height * 0.65;
652        flame.X += mage.FacingDirection.GetVector().X + 30;
653        flame.Animation = new Animation(blaze);
654        flame.IgnoresPhysicsLogics = true;
655        flame.Animation.Start();
656        mage.Add(flame);
657
658        PlatformWandererBrain brain = new PlatformWandererBrain();
659        brain.Speed = 20;
660        brain.FallsOffPlatforms = false;
661        //mage.Brain = brain;
662
663        //PhysicsObject trigger = PhysicsObject.CreateStaticObject(10, Level.Height); //A truly cool and efficient way to make the boogeyman react only to our closeness
664        //trigger.Position = mage.Position - new Vector(Window.Width / 2, 0);
665        ////trigger.Color = Color.Red;
666        //trigger.IsVisible = false;
667        //trigger.IgnoresCollisionResponse = true;
668        //Add(trigger);
669
670        FollowerBrain attackBrain = new FollowerBrain("player");
671        attackBrain.DistanceFar = Window.Width / 2.5;
672        attackBrain.DistanceClose = Window.Width / 2;
673        attackBrain.StopWhenTargetClose = false;
674        attackBrain.Speed = brain.Speed * 6;
675        attackBrain.FarBrain = brain;
676        mage.Brain = attackBrain;
677
678        // Taiotaan tulta välillä.
679        var castTimer = new Timer { Interval = 10.0 };
680        castTimer.Timeout += delegate
681        {
682            // TODO: Kävelyanimaatio pysähtyy jostain syystä tämän animaation jälkeen.
683            mage.PlayAnimation(firemageCastAnimation);
684
685            Timer.SingleShot(RandomGen.NextDouble(5, 8), delegate { mage.Brain = attackBrain; });
686
687            Timer.SingleShot(1.5,
688                delegate
689                {
690                    for (int i = 0; i < 6; i++)
691                    {
692                        CreateFlame(new Vector(attackBrain.CurrentTarget.X + RandomGen.NextDouble(-300, 300), mage.Y + mage.Height * 1.5), 30, 60, false);
693                        mage.Brain = brain;
694                    }
695                });
696
697        };
698
699        attackBrain.DistanceToTarget.AddTrigger(Window.Width / 2, TriggerDirection.Down, delegate() 
700        { 
701            castTimer.Start(); 
702            attackBrain.DistanceToTarget.RemoveTriggers(Window.Width/2);
703        });
704
705        //castTimer.Start();
706
707        AddCollisionHandler(mage, "milkparticle", delegate(PhysicsObject fireMage, PhysicsObject milk)
708        {
709            if (milk.Y > fireMage.Y + fireMage.Height * 0.15 && !immune)
710            {
711                flame.Size *= 0.95;
712                immune = true;
713                if (flame.Height < height)
714                {
715                    castTimer.Stop();
716                    CreatePitchfork(mage.Position, TILE_SIZE, TILE_SIZE);
717                    mage.Destroy();
718                    Timer.SingleShot(6, NextLevel); 
719                }
720                Timer.SingleShot(0.5, delegate { immune = false; });
721
722            }
723        });
724
725        //AddCollisionHandler(trigger, "player", delegate(PhysicsObject a, PhysicsObject b) { castTimer.Start(); });
726    }
727
728    void CreateHouse(Vector position, double width, double height)
729    {
730        // Näkyvä talo
731        GameObject house = new GameObject(width * 10, height * 8);
732        house.Image = houseImages[0];
733        house.Position = position - new Vector(0, height * 2.5);
734        Add(house, -2);
735
736        //Seisottava tasanne
737        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width - (TILE_SIZE * 3.25), 1);     //Tätä kohtaa on nyt vähän hakemalla haettu.
738        platform.IsVisible = false;
739        platform.Position = new Vector(house.X + (TILE_SIZE * 0.5), house.Top);
740        Add(platform);
741    }
742
743    void CreateBurnedHouse(Vector position, double width, double height)
744    {
745        GameObject house = new GameObject(width * 10, height * 8);
746        house.Image = houseImages[1];
747        house.Position = position - new Vector(0, height * 2.5);
748        Add(house, -2);
749
750        PhysicsObject platform = PhysicsObject.CreateStaticObject(house.Width * 0.25, 1);
751        platform.IsVisible = false;
752        platform.Position = new Vector(house.X + platform.Width * 0.5, house.Top);
753        Add(platform);
754    }
755
756    private void CreateCart(Vector position, double width, double height)
757    {
758        double size = 0.7;
759        PhysicsObject cart = new PhysicsObject(400 * size, 80 * size);
760        cart.Position = position;
761        cart.Image = cartImage;
762        cart.CollisionIgnoreGroup = 2;
763        Add(cart);
764        PhysicsObject cartWheel = new PhysicsObject(160 * size, 160 * size, Shape.Circle);
765        cartWheel.Image = cartWheelImage;
766        cartWheel.Position = cart.Position + new Vector(-110, -30) * size;
767        cartWheel.CollisionIgnoreGroup = 2;
768        Add(cartWheel);
769        AxleJoint joint = new AxleJoint(cart, cartWheel);
770        Add(joint);
771    }
772
773    private void CreateDummy(Vector position, double width, double height, Color color)
774    {
775        PhysicsObject dummy = PhysicsObject.CreateStaticObject(width, height);
776        dummy.Position = position;
777        dummy.Color = color;
778        Add(dummy);
779    }
780
781    void CreatePlayer(Vector position, double width, double height)
782    {
783        HillBilly player = new HillBilly(width, height * 2, names[players.Count()]);
784        player.Shape = Shape.Rectangle;
785        player.Position = position + new Vector(0, height * 0.5);
786        player.Color = Color.White;
787        player.AnimWalk = new Animation(normalWalk);
788        player.AnimIdle = new Animation(playerIdle);
789        player.AnimJump = new Animation(playerJump);
790        player.AnimFall = new Animation(playerFall);
791        player.Animations = new List<Animation>();
792        player.Animations.Add(normalWalk);
793        player.Animations.Add(playerIdle);
794        player.AnimFall.StopOnLastFrame = true;
795        players.Add(player);
796        startingPlayers.Add(player);
797        player.Tag = "player";
798        Add(player);
799
800        AddCollisionHandler(player, "burn", delegate(PhysicsObject p, PhysicsObject t)
801        {
802            player.Life.Value--;
803        });
804
805        AddCollisionHandler(player, "worm", delegate(PhysicsObject p, PhysicsObject worm)
806        {
807            if (player.Y > worm.Y && Math.Abs(player.X - worm.X) < worm.Width / 2.0)
808            {
809                worm.Destroy();
810            }
811            else
812            {
813                player.Life.Value--;
814            }
815        });
816
817
818        player.Life.LowerLimit += delegate
819        {
820            if (players.Count < 2)
821            {
822                Loss();
823            }
824            else
825            {
826                players.Remove(player);
827
828                //if (player.Improvement != null)
829                //{
830                    GetRidOfImprovement(player);
831                    //Improvement parannus = player.Improvement;
832                    //parannus.Position = player.Position;
833                    //parannus.IsVisible = true;
834                    //parannus.IgnoresCollisionResponse = false;
835                    //parannus.Tag = "improvement";
836                //}
837
838                player.Destroy();
839
840
841            }
842        };
843
844        AddCollisionHandler(player, "improvement", CollectImprovement);
845       // AddCollisionHandler(player, "improvement", CollectImprovement);
846    }
847
848    void CreateGroundTop(Vector position, double width, double height)
849    {
850        // Puolet pienempi näkymätön palikka alla johon törmää.
851        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height / 2.0);
852        ground.IsVisible = false;
853        ground.Position = position - new Vector(0.0, TILE_SIZE / 4.0);
854        Add(ground);
855
856        // Maanpinnan näkyvä osa.
857        GameObject visibleGround = new GameObject(width, height);
858        visibleGround.Image = groundTopImages[levelNumber];
859        visibleGround.Position = position;
860        visibleGround.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
861        Add(visibleGround, -1);
862
863        int probability = RandomGen.NextInt(100);
864        bool wheat = probability < 20;
865
866        if (wheat)
867        {
868            GameObject wheatBlock = new GameObject(width * 1.5, height * 2);
869            wheatBlock.Image = foregroundDecorations[levelNumber];
870            wheatBlock.X = visibleGround.X;
871            wheatBlock.Bottom = visibleGround.Bottom;
872            wheatBlock.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
873            Add(wheatBlock, 2);
874        }
875    }
876
877    void CreateGround(Vector position, double width, double height)
878    {
879        PhysicsObject ground = PhysicsObject.CreateStaticObject(width, height);
880        ground.Image = groundImages[levelNumber];
881        ground.Position = position;
882        ground.TextureWrapSize = new Vector(width / TILE_SIZE, height / TILE_SIZE);
883        Add(ground, -1);
884    }
885    #endregion
886
887    void SetControls()
888    {
889        Keyboard.Listen(Key.A, ButtonState.Down, delegate { startingPlayers[0].Walk(-PLAYER_SPEED); }, "Player 1 moves left");
890        Keyboard.Listen(Key.D, ButtonState.Down, delegate { startingPlayers[0].Walk(PLAYER_SPEED); }, "Player 1 moves right");
891        Keyboard.Listen(Key.W, ButtonState.Down, delegate { startingPlayers[0].Jump(PLAYER_SPEED * 2); }, "Player 1 jumps");    //Just PLAYER_SPEED felt alright as well
892        Keyboard.Listen(Key.E, ButtonState.Pressed, delegate { startingPlayers[0].UseImprovement(); }, "Player 1 uses their tools");
893        Keyboard.Listen(Key.Tab, ButtonState.Pressed, GetRidOfImprovement, "Player 1 throws their tools away", startingPlayers[0]);
894
895        Keyboard.Listen(Key.Left, ButtonState.Down, delegate { startingPlayers[1].Walk(-PLAYER_SPEED); }, "Player 2 moves left");
896        Keyboard.Listen(Key.Right, ButtonState.Down, delegate { startingPlayers[1].Walk(PLAYER_SPEED); }, "Player 2 moves right");
897        Keyboard.Listen(Key.Up, ButtonState.Down, delegate { startingPlayers[1].Jump(PLAYER_SPEED * 2); }, "Player 2 jumps");
898        Keyboard.Listen(Key.RightShift, ButtonState.Pressed, delegate { startingPlayers[1].UseImprovement(); }, "Player 2 uses their tools");
899        Keyboard.Listen(Key.Enter, ButtonState.Pressed, GetRidOfImprovement, "Player 1 throws their tools away", startingPlayers[1]);
900
901        Keyboard.Listen(Key.F12, ButtonState.Pressed, NextLevel, null);
902        Keyboard.Listen(Key.R, ButtonState.Pressed, StartGame, null);
903
904        Keyboard.Listen(Key.F1, ButtonState.Pressed, ShowControlHelp, "Show help");
905        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Exit game");
906    }
907
908    void GetRidOfImprovement(HillBilly player)
909    {
910        if(player.Improvement != null)
911        {
912            Improvement parannus = player.Improvement;
913            parannus.Position = player.Position + player.FacingDirection.GetVector() * 100;
914            parannus.IsVisible = true;
915            parannus.IgnoresCollisionResponse = false;
916            parannus.Tag = "improvement";
917            player.Improvement.Rid();
918        }
919    }
920
921    public void CreateMilkParticles(HillBilly billy, int size, int xBase, int yBase, Vector position, String tag)
922    {
923        //splash.Play();
924        for (int i = 0; i < 10; i++)
925        {
926            const double maxLife = 1.0;
927            PhysicsObject milkParticle = new PhysicsObject(size, size, Shape.Circle);
928            milkParticle.Color = new Color(255, 255, 255, 128);
929            milkParticle.Position = billy.Position + position;
930            milkParticle.IgnoresCollisionResponse = true;
931            milkParticle.Tag = tag;
932            milkParticle.LifetimeLeft = TimeSpan.FromSeconds(maxLife);
933            Add(milkParticle);
934
935            // Väri muuttuu läpinäkyväksi.
936            var fadeTimer = new Timer { Interval = 0.07 };
937            fadeTimer.Timeout += delegate
938            {
939                byte c = 255;
940                milkParticle.Color = new Color(c, c, c, (byte)(128 * milkParticle.LifetimeLeft.TotalSeconds / maxLife));
941            };
942            fadeTimer.Start();
943            milkParticle.Destroyed += fadeTimer.Stop;
944
945            // Random lentonopeus.
946            var rx = RandomGen.NextDouble(-50, 50);
947            var ry = RandomGen.NextDouble(-50, 50);
948            milkParticle.Hit(new Vector(billy.FacingDirection.GetVector().X * (xBase + rx), yBase + ry));
949        }
950    }
951
952    //private void UseImprovement(HillBilly player)
953    //{
954    //    if (player.Improvement == null)
955    //    {
956           
957    //        CreateMilkParticles(player, 5, 100, 100, new Vector(0, player.Height/3), "tears");
958    //        return;
959    //    }
960
961    //    player.UseImprovement(player.Improvement);
962    //}
963
964    void Loss()
965    {
966        //TODO: Sumthin' flashy for our fallen friends.
967        Exit();
968    }
969
970    void CollectImprovement(PhysicsObject player, PhysicsObject milk)
971    {
972        HillBilly billy = player as HillBilly;
973        if (billy == null || billy.Improvement != null)
974            return;
975
976        Improvement milkI = milk as Improvement;
977        billy.GainImprovement(milkI);
978
979        milk.IsVisible = false;
980        milk.IgnoresCollisionResponse = true;
981        milk.Tag = "none";
982
983        //Remove(milk);
984        //billy.AnimWalk = new Animation(milkWalk);
985        //billy.AnimIdle = new Animation(milkWalk.CurrentFrame);
986    }
987
988    #region Camera
989    void UpdateCamera()
990    {
991        double minY = players.Min(p => p.Y);
992        double maxY = players.Max(p => p.Y);
993        double minX = players.Min(p => p.X) + cameraOffset;
994
995        Vector minPosition = new Vector(Math.Max(minX, cameraTargetX), minY);
996        Vector maxPosition = new Vector(minX, maxY);
997
998        cameraTarget = (minPosition + maxPosition) * 0.5;
999        cameraTarget.X = Math.Max(cameraTargetX, minX);     //Lellllll.
1000
1001        //cameraTarget.Y = Math.Max(cameraTarget.X, Level.Bottom + Window.Height/2.0);
1002
1003        cameraTargetX = Math.Max(cameraTargetX, minX);
1004
1005        cameraTarget.X = Math.Min(cameraTargetX, rightCamLimit);
1006        cameraTarget.Y = Math.Max(cameraTarget.Y, bottomCamLimit);
1007
1008        double windowMax = Camera.ScreenToWorld(new Vector(Window.Width / 2.0, 0)).X;
1009        double windowMin = Camera.ScreenToWorld(new Vector(-Window.Width / 2.0, 0)).X;
1010        foreach (var player in players)
1011        {
1012            player.Left = Math.Max(player.Left, windowMin);
1013            player.Right = Math.Min(player.Right, windowMax);
1014        }
1015    }
1016
1017    public void ForkThings(HillBilly Owner)
1018    {
1019        PhysicsObject evilClone = new PhysicsObject(Owner.Width, Owner.Height * 0.7);
1020        evilClone.Position = Owner.Position + Owner.FacingDirection.GetVector() * 40 + new Vector(0, -(Owner.Height * 0.3));
1021        evilClone.Color = Color.Red;
1022        evilClone.IsVisible = false;
1023        evilClone.Tag = "pitchfork";
1024        evilClone.IgnoresCollisionResponse = true;
1025        evilClone.IgnoresPhysicsLogics = true;
1026        evilClone.LifetimeLeft = TimeSpan.FromSeconds(Owner.Animation.FPS * Owner.Animation.FrameCount);
1027        Add(evilClone);
1028
1029        Owner.PlayAnimation(Owner.Improvement.Animations[1], evilClone.Destroy);
1030    }
1031   
1032
1033    protected override void Update(Time time)
1034    {
1035        Camera.Position += (cameraTarget - Camera.Position) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
1036        //Camera.X += (cameraTargetX - Camera.X) * time.SinceLastUpdate.TotalSeconds * cameraSpeed;
1037
1038
1039        base.Update(time);
1040    }
1041
1042    /// <summary>
1043    /// Yritän leikkiä kameralla. Vielä varmaan hetken pidempään.
1044    /// </summary>
1045    /// <param name="gameTime"></param>
1046    /*
1047    protected override void Update(Microsoft.Xna.Framework.GameTime gameTime)
1048    {
1049        foreach(HillBilly player in players)
1050        {
1051            playerPositionsX.Add(player.Position.X);
1052            playerPositionsY.Add(player.Position.Y);
1053        }
1054
1055        double maxX = playerPositionsX.Max();
1056        double maxY = playerPositionsY.Max();
1057        double minX = playerPositionsX.Min();
1058        double minY = playerPositionsY.Min();
1059
1060        Vector minPosition = new Vector(minX, minY);
1061        Vector maxPosition = new Vector(maxX, maxY);
1062
1063        Camera.Position = (minPosition + maxPosition) * 0.5;
1064
1065        playerPositionsX.Clear();
1066        playerPositionsY.Clear();
1067
1068        base.Update(gameTime);
1069    }
1070     */
1071    #endregion
1072
1073
1074}
Note: See TracBrowser for help on using the repository browser.