source: 2016/23/ohjaajat/Punasininen/Punasininen/Punasininen/Punasininen.cs @ 7224

Revision 7224, 13.6 KB checked in by sieerinn, 5 years ago (diff)

Loppusäädöt

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
10public class Punasininen : PhysicsGame
11{
12    private const double SPEED = 300;
13    private const double JUMPSPEED = 1250;
14    private const int TILE_SIZE = 60;
15    private const int MATCH_LENGTH = 60;
16
17    private Player blue;
18    private Player red;
19    private Image[] orangeTileImages = LoadImages("orangetile\\orangetile", 12);
20    private Image[] blueTileImages = LoadImages("bluetile\\bluetile", 12);
21    private Image[] orangeWalkImages = LoadImages("walkorange\\walk", 16);
22    private Image[] blueWalkImages = LoadImages("walkblue\\walk", 16);
23    private Image orangeGlow = LoadImage("orangeglow");
24    private Image blueGlow = LoadImage("blueglow");
25
26    Font largeFont = LoadFont("SymtextLarge");
27    Font smallFont = LoadFont("SymtextSmall");
28
29    Color blueColor = Color.FromHexCode("FF1D65CF");
30    Color redColor = Color.FromHexCode("FABE1A");
31
32    private Image cratePic = LoadImage("weaponcrate");
33    private Image bluePistolpic = LoadImage("bluegun");
34    private Image orangePistolpic = LoadImage("orangegun");
35
36    DoubleMeter matchTimer; // Remaining time in seconds.
37    DoubleMeter percentageTracker;
38
39    Dictionary<Vector, WeaponCrate> cratePositions = new Dictionary<Vector, WeaponCrate>();
40
41    private Shader shader;
42
43    public void NewWave(Vector pos)
44    {
45        shader.NewWave(pos);
46    }
47
48    public override void Begin()
49    {
50        shader = new Shader(GraphicsDevice, Content, Camera);
51        SmoothTextures = false;
52
53        CreateLevel();
54        AddControls();
55    }
56
57    private static Image[] LoadImages(string prefix, int numberOfImages)
58    {
59        var images = new Image[numberOfImages];
60        for (int i = 1; i <= numberOfImages; i++)
61        {
62            images[i - 1] = LoadImage(string.Format("{0}{1:0000}", prefix, i));
63        }
64        return images;
65    }
66
67    void CreateLevel()
68    {
69        Gravity = new Vector(0, -1000);
70
71        ColorTileMap map = ColorTileMap.FromLevelAsset("dungeon1");
72        map.SetTileMethod(Color.Black, delegate (Vector vektori, double leveys, double korkeus) { AddPlatform(vektori, leveys, korkeus); });
73        map.SetTileMethod(Color.FromHexCode("#FF0026FF"), delegate (Vector paikka, double leveys, double korkeus) { blue = CreatePlayer(paikka, leveys, korkeus, blueColor, blueWalkImages, bluePistolpic); });
74        map.SetTileMethod(Color.FromHexCode("FFD800"), delegate (Vector a, double b, double c) { cratePositions.Add(a, CreateWeaponCrate(a, b, c)); });
75        map.SetTileMethod(Color.Red, delegate (Vector paikka, double leveys, double korkeus) { red = CreatePlayer(paikka, leveys, korkeus, redColor, orangeWalkImages, orangePistolpic); });
76        map.Execute(TILE_SIZE, TILE_SIZE);
77
78        Tile bottom = AddPlatform(new Vector(0, Level.Bottom - 100), Level.Width * 4, 100);
79        bottom.Tag = "death";
80        Add(bottom);
81
82        // Luo ajastimen, joka värittää kokoajan pelaajien lähellä olevia tiiliä.
83        // (pakko laittaa pieni viive, koska GetObjectsWithTag palauttaa muuten tyhjän listan)
84        Timer.SingleShot(0.1, () =>
85        {
86            int coloringDistance = 90;
87            var tiles = GetObjectsWithTag("platform");
88            Timer playerColorTimer = new Timer() { Interval = 0.1 };
89            playerColorTimer.Timeout += () =>
90            {
91                foreach (var tile in tiles)
92                {
93                    bool redClose = Vector.Distance(red.Position, tile.Position) < coloringDistance;
94                    bool blueClose = Vector.Distance(blue.Position, tile.Position) < coloringDistance;
95
96                    if (redClose && !blueClose) ColorTile(red, (PhysicsObject)tile);
97                    if (blueClose && !redClose) ColorTile(blue, (PhysicsObject)tile);
98                }
99            };
100            playerColorTimer.Start();
101        });
102
103        Timer spawnTimer = new Timer() { };
104
105        Camera.ZoomToLevel();
106        Level.Background.Color = Color.Black;
107
108        percentageTracker = new DoubleMeter(0, 0, 100);
109
110        ProgressBar percentageBar = new ProgressBar(Level.Width / 2, 20) { Y = Screen.Top - 20, BarColor = red.Color, Color = blue.Color };
111        percentageBar.Y = Screen.Top - 20;
112        percentageBar.BindTo(percentageTracker);
113        Add(percentageBar);
114
115        CreateMatchTimer();
116    }
117
118    void CreateMatchTimer()
119    {
120        matchTimer = new DoubleMeter(MATCH_LENGTH);
121        matchTimer.LowerLimit += () =>
122        {
123            Win(percentageTracker.Value >= 50 ? red : blue);
124            var restart = new Timer() { Interval = 5, IgnorePause = true };
125            restart.Timeout += RestartGame;
126            restart.Start();
127        };
128
129        Func<double, double, Color, Label> createLabel = (x, y, color) =>
130        {
131            var label = new Label();
132            label.Font = largeFont;
133            label.Position = new Vector(x, y);
134            label.BindTo(matchTimer);
135            label.TextColor = color;
136            label.DoubleFormatString = "{0}";
137            Add(label);
138            return label;
139        };
140
141        var timeLabelDark = createLabel(5, Window.Height / 2 - 100 - 5, Color.Black);
142        var timeLabel = createLabel(0, Window.Height / 2 - 100, blueColor);
143
144        var matchLabelTimer = new Timer();
145        matchLabelTimer.Interval = 1;
146        matchLabelTimer.Timeout += () =>
147        {
148            matchTimer.Value -= 1;
149            timeLabel.TextColor = matchTimer.Value % 2 == 0 ? blueColor : redColor;
150        };
151        matchLabelTimer.Start();
152
153    }
154
155    WeaponCrate CreateWeaponCrate(Vector place, double width, double height)
156    {
157        WeaponCrate crate = new WeaponCrate(width, height);
158        crate.Position = place;
159        crate.Image = cratePic;
160        crate.IgnoresCollisionResponse = true;
161        crate.MakeStatic();
162        Add(crate);
163
164        crate.Oscillate(Vector.UnitY, 10, 0.4);
165
166        return crate;
167    }
168
169    Tile AddPlatform(Vector paikka, double leveys, double korkeus)
170    {
171        Tile platform = new Tile(leveys, korkeus, paikka);
172        platform.MakeStatic();
173        platform.Color = Color.Black;
174        platform.Tag = "platform";
175        Add(platform);
176        return platform;
177    }
178
179    Player CreatePlayer(Vector paikka, double leveys, double korkeus, Color playersColor, Image[] animation, Image pistolPic)
180    {
181        Player player = new Player(leveys * 1, korkeus * 1.5, playersColor);
182        player.AnimWalk = new Animation(animation) { FPS = 30 };
183        player.AnimIdle = new Animation(new[] { animation[0] });
184        player.Position = paikka + new Vector(0, korkeus / 2);
185        player.Spawn = player.Position;
186        Add(player);
187
188        var glow = new GameObject(240, 240);
189        glow.Image = playersColor == redColor ? orangeGlow : blueGlow;
190        player.Add(glow);
191
192        player.Weapon = new AssaultRifle(leveys * 1.5, korkeus * 1.5)
193        {
194            FireRate = 3,
195            AttackSound = null,
196            MaxAmmoLifetime = TimeSpan.FromSeconds(8),
197            ProjectileCollision = delegate (PhysicsObject a, PhysicsObject b) { ColorTile(a, b); a.Destroy(); },
198            // ProjectileCollision = BulletHitsSomething,
199            Image = pistolPic,
200            Y = 5
201        };
202
203        AddCollisionHandler(player, "platform", delegate (PhysicsObject a, PhysicsObject b)
204        {
205            ColorTile(a, b);
206        });
207        AddCollisionHandler(player, "crate", delegate (PhysicsObject a, PhysicsObject b)
208        {
209            GunLottery(player);
210            b.Destroy();
211        });
212        AddCollisionHandler(player, "death", delegate (PhysicsObject a, PhysicsObject b)
213        {
214            Restore((Player)a);
215        });
216
217        return player;
218    }
219
220    void Restore(Player player)
221    {
222        player.Position = player.Spawn;
223    }
224
225    void GunLottery(Player player)
226    {
227        int hurdur = RandomGen.NextInt(0, 3);
228        Image glow = player == red ? orangeGlow : blueGlow;
229
230        switch (hurdur)
231        {
232            case 0:
233                player.Weapon = new RocketLauncher(player.Weapon.Width, player.Weapon.Height, player.Weapon.Image, glow, player);
234                break;
235            case 1:
236                player.Weapon = new GrenadeLauncher(player.Weapon.Width, player.Weapon.Height, player.Weapon.Image, glow, player);
237                break;
238            case 2:
239                player.Weapon = new SprayGun(player.Weapon.Width, player.Weapon.Height, player.Weapon.Image, glow, player);
240                break;
241            default:
242                break;
243        };
244
245        Timer undo = new Timer() { Interval = 5 };
246        undo.Timeout += delegate ()
247        {
248            undo.Stop();
249            player.Weapon = new AssaultRifle(player.Weapon.Width, player.Weapon.Height)
250            {
251                FireRate = 3,
252                AttackSound = null,
253                MaxAmmoLifetime = TimeSpan.FromSeconds(8),
254                Image = player.Weapon.Image,
255                ProjectileCollision = delegate (PhysicsObject a, PhysicsObject b) { ColorTile(a, b); a.Destroy(); },
256                Y = 5,
257            };
258        };
259        undo.Start();
260
261    }
262
263    void RestartGame()
264    {
265        cratePositions.Clear();
266        ClearAll();
267        Begin();
268        IsPaused = false;
269    }
270
271    void Win(Player winner)
272    {
273        Pause();
274
275        // Haluaisin tehdä tähän jonkinlaisen hauskan ponnahdusefektin jossain vaiheessa. Sellaisen napakan zoomin ja sitten boing. Hurdur.
276
277        string winnerName = winner == blue ? "Blue" : "Yellow";
278        string victoryText = winnerName + " player won!";
279
280        // Tekstille musta tausta, jotta sen näkee lukea.
281        var announcementDark = new Label(victoryText) { Font = largeFont, TextColor = Color.Black };
282        Add(announcementDark);
283
284        // Voittoteksti.
285        var announcement = new Label(victoryText) { Font = largeFont, TextColor = winner.Color };
286        Add(announcement);
287
288        // Zoomaa voittajaan.
289        double targetZoomFactor = 1.5;
290        var zoomTimer = new Timer() { Interval = 0.01 };
291        zoomTimer.Timeout += () =>
292        {
293            Camera.Position += (winner.Position - Camera.Position) * 0.02;
294            Camera.ZoomFactor += (targetZoomFactor - Camera.ZoomFactor) * 0.01;
295            announcement.Position = Camera.WorldToScreen(winner.Position + new Vector(0, 80));
296            announcementDark.Position = announcement.Position + new Vector(5, -5);
297        };
298        zoomTimer.IgnorePause = true;
299        zoomTimer.Start();
300    }
301
302    public void ColorTile(PhysicsObject player, PhysicsObject platform)
303    {
304        var imgs = player.Color == blueColor ? blueTileImages : orangeTileImages;
305        var glowImg = player.Color == blueColor ? blueGlow : orangeGlow;
306
307        if (platform is Tile)
308        {
309            ((Tile)platform).SetColor(imgs, glowImg, player.Color, UpdatePercentage);
310        }
311    }
312
313    void UpdatePercentage()
314    {
315        List<GameObject> colored = GetObjects(o => (o.Color == red.Color || o.Color == blue.Color) && (String)o.Tag == "platform");
316        percentageTracker.Value = (double)colored.FindAll(o => o.Color == red.Color).Count / colored.Count * 100;
317    }
318
319    void AddControls()
320    {
321        ControllerOne.Listen(Button.Back, ButtonState.Pressed, Exit, "Poistu pelistä");
322
323        ControllerOne.ListenAnalog(AnalogControl.LeftStick, 0.1, Move, "Liikuta pelaajaa", red);
324        ControllerOne.Listen(Button.A, ButtonState.Pressed, Jump, "Pelaaja hyppää", red, JUMPSPEED);
325        ControllerOne.ListenAnalog(AnalogControl.RightStick, 0.1, Aim, "Tähtää", red);
326        ControllerOne.ListenAnalog(AnalogControl.RightTrigger, 0.1, Shoot, "", red);
327        ControllerOne.ListenAnalog(AnalogControl.LeftTrigger, 0.1, Shoot, "", red);
328
329        ControllerTwo.ListenAnalog(AnalogControl.LeftStick, 0.1, Move, "Liikuta pelaajaa", blue);
330        ControllerTwo.Listen(Button.A, ButtonState.Pressed, Jump, "Pelaaja hyppää", blue, JUMPSPEED);
331        ControllerTwo.ListenAnalog(AnalogControl.RightStick, 0.1, Aim, "Tähtää", blue);
332        ControllerTwo.ListenAnalog(AnalogControl.RightTrigger, 0.1, Shoot, "", blue);
333        ControllerTwo.ListenAnalog(AnalogControl.LeftTrigger, 0.1, Shoot, "", blue);
334
335        Keyboard.Listen(Key.F1, ButtonState.Pressed, ShowControlHelp, "Ohjeet");
336        Keyboard.Listen(Key.F12, ButtonState.Pressed, RestartGame, null);
337        Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Lopeta");
338
339        Mouse.Listen(MouseButton.Left, ButtonState.Pressed, () => shader.NewWave(Mouse.PositionOnWorld), null);
340    }
341
342    void Move(AnalogState stick, Player player)
343    {
344        if (stick.StateVector.Magnitude > 0.15)
345        {
346            player.Walk(stick.StateVector.X * SPEED);
347        }
348
349    }
350
351    void Shoot(AnalogState trigger, Player player)
352    {
353        if (player.Weapon != null)
354        {
355            PhysicsObject bullet = player.Weapon.Shoot();
356            if (bullet != null)
357            {
358                bullet.Image = null;
359                bullet.Color = player.Color;
360            }
361        }
362    }
363
364    void Jump(Player player, double speed)
365    {
366        player.Jump(speed);
367    }
368
369    void Aim(AnalogState stickState, Player player)
370    {
371        player.Weapon.Angle = stickState.StateVector.Angle;
372    }
373
374    protected override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
375    {
376        shader.Draw(gameTime, base.Draw);
377    }
378}
Note: See TracBrowser for help on using the repository browser.