source: 2017/27/SimoR/juttuja/Jypeli3D/Jypeli3D/Jypeli3D/Jypeli3D.cs @ 8949

Revision 8949, 6.6 KB checked in by sieerinn, 2 years ago (diff)
Line 
1using System;
2using System.Collections.Generic;
3using Jypeli;
4using Jypeli.Assets;
5using Jypeli.Controls;
6using Jypeli.Effects;
7using Jypeli.Widgets;
8using Vector3 = Microsoft.Xna.Framework.Vector3;
9
10
11public class Pallo : GameObject
12{
13    public Pallo() : base(30, 30, Shape.Circle) { }
14
15    public Vector3 Sijainti;
16
17    public double Koko;
18
19    public Color Vari;
20}
21
22public partial class Jypeli3D : Game
23{
24    double nopeus = 3.0;
25    double piirtoEtaisyys = 10;
26    double ihmeJuttu = 1.0;
27
28    ColorTileMap ruudut;
29
30    Vector3 kameranPaikka;
31
32    // Kameran pyöritys Tait-Bryat kulmina.
33    //   X - roll, Y - yaw, Z - pitch
34    Vector3 kulma;
35
36    List<Pallo> pallot = new List<Pallo>();
37
38    public override void Begin()
39    {
40        LuoKentta2();
41    }
42   
43    void LuoKentta()
44    {
45        ClearAll();
46        pallot.Clear();
47        LisaaOhjaimet();
48
49        Level.Background.Color = Color.Black;
50
51        piirtoEtaisyys = 10;
52        ihmeJuttu = 1.0;
53        kameranPaikka = Vector3.Zero;
54        kulma = Vector3.Zero;
55
56        ruudut = ColorTileMap.FromLevelAsset("kentta1");
57        ruudut.SetTileMethod(Color.White, LuoLattia);
58        ruudut.SetTileMethod(Color.Black, LuoSeina);
59        ruudut.SetTileMethod("0000FF", LuoPelaaja);
60        ruudut.Execute(1, 1);
61    }
62   
63    void LuoPelaaja(Vector paikka, double leveys, double korkeus)
64    {
65        kameranPaikka = new Vector3((float)paikka.X, 1f, (float)paikka.Y);
66        LuoLattia(paikka, leveys, korkeus);
67    }
68
69    void LuoLattia(Vector paikka, double leveys, double korkeus)
70    {
71        for (float x = -0.5f; x <= 0.5f; x += 0.5f)
72        {
73            for (float z = -0.5f; z <= 0.5f; z += 0.5f)
74            {
75                LuoPallo(new Vector3((float)paikka.X + x, 0, (float)paikka.Y + z), Color.LightBlue, 100.0);
76            }
77        }
78    }
79
80    void LuoSeina(Vector paikka, double leveys, double korkeus)
81    {
82        for (float y = 0.5f; y <= 3; y += 1.1f)
83        {
84            LuoPallo(new Vector3((float)paikka.X, y, (float)paikka.Y), Color.JungleGreen, 800.0);
85        }
86    }
87
88    void LuoPallo(Vector3 sijainti, Color vari, double koko = 500.0)
89    {
90        Pallo pallo = new Pallo() { Sijainti = sijainti, Koko = koko, Vari = vari };
91        Add(pallo);
92        pallot.Add(pallo);
93    }
94
95    void Kaanny(AnalogState hiirulainen)
96    {
97        kulma.Y += (float)hiirulainen.MouseMovement.X * 0.002f;
98        kulma.X += (float)hiirulainen.MouseMovement.Y * -0.002f;
99    }
100
101    void Liiku(double kerroin, double extraKulma)
102    {
103        Vector3 uusiPaikka = kameranPaikka;
104
105        // Kuljetaan kameran osoittamaan suuntaan.
106        uusiPaikka.X += (float)(Math.Sin(kulma.Y + extraKulma) * nopeus * kerroin) * 1 / 60f;
107        uusiPaikka.Z += (float)(Math.Cos(kulma.Y + extraKulma) * nopeus * kerroin) * 1 / 60f;
108
109        if (!Tormaa(uusiPaikka))
110        {
111            kameranPaikka = uusiPaikka;
112        }
113    }
114
115    bool Tormaa(Vector3 paikka)
116    {
117        if (ruudut == null) return false;
118
119        // Tarpeeksi korkealla ei törmätä.
120        if (paikka.Y > 3) return false;
121
122        // Lasketaan missä kohtaa TileMappissa parametrina annettu paikka on.
123        int x = (int)(paikka.X + Level.Width / 2);
124        int y = (int)(Level.Height / 2 - paikka.Z);
125
126        if (x >= 0 && y >= 0 && x < ruudut.GetLength(1) && y < ruudut.GetLength(0))
127        {
128            // TileMapissa oleviin mustiin pikseleihin törmää.
129            return ruudut.GetTile(y, x) == Color.Black;
130        }
131
132        // TileMapin ulkopuolella ei törmätä.
133        return false;
134    }
135   
136    protected override void Update(Time time)
137    {
138        foreach (var pallo in pallot)
139        {
140            // https://en.wikipedia.org/wiki/3D_projection#Perspective_projection
141
142            Vector3 s = new Vector3((float)Math.Sin(kulma.X), (float)Math.Sin(kulma.Y), (float)Math.Sin(kulma.Z));
143            Vector3 c = new Vector3((float)Math.Cos(kulma.X), (float)Math.Cos(kulma.Y), (float)Math.Cos(kulma.Z));
144            Vector3 ero = pallo.Sijainti - kameranPaikka;
145
146            double etaisyys = Vector3.Distance(kameranPaikka, pallo.Sijainti);
147
148            Vector3 d = new Vector3(c.Y * (s.Z * ero.Y + c.Z * ero.X) - s.Y * ero.Z,
149                                    s.X * (c.Y * ero.Z + s.Y * (s.Z * ero.Y + c.Z * ero.X)) + c.X * (c.Z * ero.Y - s.Z * ero.X),
150                                    c.X * (c.Y * ero.Z + s.Y * (s.Z * ero.Y + c.Z * ero.X)) - s.X * (c.Z * ero.Y - s.Z * ero.X));
151
152            pallo.IsVisible = d.Z > 0 && etaisyys < piirtoEtaisyys;
153            pallo.Position = new Vector((Window.Width / 2.0 * d.X) / (d.Z * ihmeJuttu), (Window.Height / 2.0 * d.Y) / (d.Z * ihmeJuttu));
154
155            if (etaisyys == 0.0) etaisyys = 0.0001;
156            pallo.Size = new Vector(1, 1) * (pallo.Koko / ihmeJuttu / etaisyys);
157            pallo.Color = Color.Lerp(pallo.Vari, Color.Transparent, etaisyys / piirtoEtaisyys);
158        }
159
160        base.Update(time);
161    }
162
163    void LisaaOhjaimet()
164    {
165        // W, A, S, D liikuttaa pelaajaa, shiftillä pääsee kovempaa.
166        // Page Up ja Page Down liikuttaa pelaajaa ylös ja alas.
167        // F1 ja F2 säätää piirtoetäisyyttä.
168        // Hiirellä kääntyy.
169
170        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
171
172        Keyboard.Listen(Key.W, ButtonState.Down, Liiku, null, 1.0, 0.0);
173        Keyboard.Listen(Key.S, ButtonState.Down, Liiku, null, -0.5, 0.0);
174        Keyboard.Listen(Key.A, ButtonState.Down, Liiku, null, -1.0, Math.PI / 2);
175        Keyboard.Listen(Key.D, ButtonState.Down, Liiku, null, 1.0, Math.PI / 2);
176
177        Keyboard.Listen(Key.LeftShift, ButtonState.Pressed, () => nopeus = 5, null);
178        Keyboard.Listen(Key.LeftShift, ButtonState.Released, () => nopeus = 3, null);
179
180        Keyboard.Listen(Key.PageUp, ButtonState.Down, () => kameranPaikka.Y += 0.1f, null);
181        Keyboard.Listen(Key.PageDown, ButtonState.Down, () => kameranPaikka.Y = Math.Max(0, kameranPaikka.Y - 0.1f), null);
182
183        Keyboard.Listen(Key.F2, ButtonState.Down, () => piirtoEtaisyys += 0.1f, null);
184        Keyboard.Listen(Key.F1, ButtonState.Down, () => piirtoEtaisyys -= 0.1f, null);
185
186        Keyboard.Listen(Key.F6, ButtonState.Down, () => ihmeJuttu += 0.01f, null);
187        Keyboard.Listen(Key.F5, ButtonState.Down, () => ihmeJuttu = Math.Max(0, ihmeJuttu - 0.01f), null);
188
189        Keyboard.Listen(Key.F12, ButtonState.Pressed, LuoKentta, null);
190        Keyboard.Listen(Key.F11, ButtonState.Pressed, LuoKentta2, null);
191
192        Mouse.ListenMovement(0.1, Kaanny, null);
193    }
194}
Note: See TracBrowser for help on using the repository browser.