Beispiel #1
0
        public Wall(Vector2f point1, Vector2f point3, Bitmap WallTexture)
        {
            this.Point1 = point1;
            this.Point3 = point3;

            //  I worked this out on my notepad, points 1, 2, 3, and 4 are ordered clockwise.
            //  1 ----------------- 2
            //  |                   |
            //  4 ----------------- 3

            this.Point2 = new Vector2f(point1.y, point3.x);
            this.Point4 = new Vector2f(Point1.x, Point3.y);
            this.Barycenter = new Vector2f((point1.x + point3.x) / 2, (point1.y + point3.y) / 2);
            this.WallTexture = WallTexture;
        }
Beispiel #2
0
 public float DotProduct(Vector2f inputVector)
 {
     return x * inputVector.x + y * inputVector.y;
 }
Beispiel #3
0
 public Vertex(Vector3f pos3d, Vector2f pos2d)
 {
     this.Pos3D = pos3d;
     this.Pos2D = pos2d;
 }
Beispiel #4
0
 public Player(Vector2f position, float angle)
 {
     this.Position = position;
     this.Angle = angle;
 }
Beispiel #5
0
        private void pnlDraw_Paint(object sender, PaintEventArgs e)
        {
            SolidBrush brush = new SolidBrush(Color.FromArgb(50, 50, 50));
            Pen pen = new Pen(brush);
            Map TransformedMap = new Map();
            TransformedMap.Walls = new Wall[map.Walls.Length];
            float[] DepthBuffer = new float[map.Walls.Length];

            // Draw floor
            e.Graphics.FillRectangle(brush, 0, pnlDraw.Height / 2 - 25, pnlDraw.Width, pnlDraw.Height);
            
            for (int i = 0; i < map.Walls.Length; i++)
            {
                Wall wall = map.Walls[i];
                Vector2f Point1Translated = new Vector2f(0, 0);
                Vector2f Point3Translated = new Vector2f(0, 0);

                // Translate the verticies around the player
                Point1Translated.x = wall.Point1.x - player.Position.x;
                Point3Translated.x = wall.Point3.x - player.Position.x;
                Point1Translated.y = wall.Point1.y - player.Position.y;
                Point3Translated.y = wall.Point3.y - player.Position.y;

                Wall TranslatedWall = new Wall(Point1Translated, Point3Translated, StoneWall);

                Vector2f Point1Rotated = new Vector2f(0, 0);
                Vector2f Point3Rotated = new Vector2f(0, 0);

                // Rotate the verticies around the player
                Point1Rotated.y = (float)(Point1Translated.x * Math.Cos(player.Angle) + Point1Translated.y * Math.Sin(player.Angle));
                Point3Rotated.y = (float)(Point3Translated.x * Math.Cos(player.Angle) + Point3Translated.y * Math.Sin(player.Angle));
                Point1Rotated.x = (float)(Point1Translated.x * Math.Sin(player.Angle) - Point1Translated.y * Math.Cos(player.Angle));
                Point3Rotated.x = (float)(Point3Translated.x * Math.Sin(player.Angle) - Point3Translated.y * Math.Cos(player.Angle));

                Wall TransformedWall = new Wall(Point1Rotated, Point3Rotated, StoneWall);

                #region Intersect
                // Thanks bisqwit!
                Intersect(TransformedWall.Point1.x, TransformedWall.Point1.x, TransformedWall.Point3.x, TransformedWall.Point3.y, -0.0001f, 0.0001f, -20f, 1f, true);
                Intersect(TransformedWall.Point1.x, TransformedWall.Point1.x, TransformedWall.Point3.x, TransformedWall.Point3.y, 0.0001f, 0.0001f, 20f, 1f, false);

                if (TransformedWall.Point1.y == 0)
                {
                    TransformedWall.Point1.y = 1;
                }
                if (TransformedWall.Point3.y == 0)
                {
                    TransformedWall.Point3.y = 1;
                }
                if (TransformedWall.Point1.y < 0)
                {
                    if (iz1 > 0)
                    {
                        TransformedWall.Point1.x = ix1;
                        TransformedWall.Point1.y = iz1;
                    }
                    else
                    {
                        TransformedWall.Point1.x = ix2;
                        TransformedWall.Point1.y = iz2;
                    }
                }
                if (TransformedWall.Point3.y < 0)
                {
                    if (iz1 > 0)
                    {
                        TransformedWall.Point3.x = ix1;
                        TransformedWall.Point3.y = iz1;
                    }
                    else
                    {
                        TransformedWall.Point3.x = ix2;
                        TransformedWall.Point3.y = iz2;
                    }
                }
                #endregion

                TransformedMap.Walls[i] = TransformedWall;
                DepthBuffer[i] = TransformedWall.Barycenter.y;
            }

            TransformedMap.SortWallsbyDepth();
            SolidBrush TextBrush = new SolidBrush(Color.FromArgb(250, 250, 250));

            for (int i = 0; i < TransformedMap.Walls.Length; i++)
            {
                Wall TransformedWall = TransformedMap.Walls[i];
                float TransformedWallDepth = TransformedWall.Barycenter.y;
                int IndexOfWall = Array.IndexOf(DepthBuffer, TransformedWallDepth);
                Wall wall = map.Walls[IndexOfWall];

                // These are 2D screen coordinates that represent the 3D drawing of the wall in perspective
                // Don't look at these nasty prototypey variables. Pay attention to the vectors below.
                float XLeft = -TransformedWall.Point1.x * 100 / TransformedWall.Point1.y;
                float YTopLeft = -WALL_HEIGHT / TransformedWall.Point1.y;
                float YBottomLeft = WALL_HEIGHT / TransformedWall.Point1.y;
                float XRight = -TransformedWall.Point3.x * 100 / TransformedWall.Point3.y;
                float YTopRight = -WALL_HEIGHT / TransformedWall.Point3.y;
                float YBottomRight = WALL_HEIGHT / TransformedWall.Point3.y;

                Vector2f TopLeft = new Vector2f(XLeft, YTopLeft);
                Vector2f TopRight = new Vector2f(XRight, YTopRight);
                Vector2f BottomLeft = new Vector2f(XLeft, YBottomLeft);
                Vector2f BottomRight = new Vector2f(XRight, YBottomRight);

                bool IsWallNotInScreenBounds = (TopLeft.Add(400).x < 0 && TopLeft.Add(400).x > 800 && BottomRight.Add(400).x < 0 || BottomRight.Add(400).x > 800);

                // Only render the wall if it's in the screen.
                if (!IsWallNotInScreenBounds)
                {
                    YLScsDrawing.Imaging.Filters.FreeTransform filter = new YLScsDrawing.Imaging.Filters.FreeTransform();
                    filter.Bitmap = wall.WallTexture;

                    filter.VertexLeftTop = TopLeft.ToPoint();
                    filter.VertexTopRight = TopRight.ToPoint();
                    filter.VertexBottomLeft = BottomLeft.ToPoint();
                    filter.VertexRightBottom = BottomRight.ToPoint();
                    // Looks way nicer.
                    filter.IsBilinearInterpolation = true;
                    System.Drawing.Bitmap perspectiveImg = filter.Bitmap;

                    // Draw image on the Y axis of the tallest point on the wall
                    // This is because, well, trust me, it makes sense.
                    // http://i.imgur.com/jgp8faz.png this is why.
                    float LeftLineHeight = BottomLeft.y - TopLeft.y;
                    float RightLineHeight = BottomRight.y - TopRight.y;

                    if (RightLineHeight > LeftLineHeight)
                    {
                        Vector2f DrawPoint = new Vector2f(TopLeft.x, TopRight.y);
                        e.Graphics.DrawImage(perspectiveImg, DrawPoint.Add(400).ToPoint());
                    }
                    else
                    {
                        e.Graphics.DrawImage(perspectiveImg, TopLeft.Add(400).ToPoint());
                    }

                    // Lighting calculation
                    float Barycenter = map.Walls[IndexOfWall].Barycenter.y;
                    int LightDensity = (int)Math.Abs((Barycenter * 150 % 255 - 100));
                    if (LightDensity > 255)
                    {
                        LightDensity = 255;
                    }
                    // Draw a semi-transparent polygon on the wall using an ARGB value
                    Brush LightingBrush = new SolidBrush(Color.FromArgb(90, LightDensity, LightDensity, LightDensity));
                    PointF[] PolyPoints = {
                                          TopLeft.Add(400).ToPoint(),
                                          TopRight.Add(400).ToPoint(),
                                          BottomRight.Add(400).ToPoint(),
                                          BottomLeft.Add(400).ToPoint() 
                                          };
                    e.Graphics.FillPolygon(LightingBrush, PolyPoints);

                    // Ceiling
                    e.Graphics.DrawLine(pen, TopLeft.Add(400).ToPoint(), TopRight.Add(400).ToPoint());
                    // Floor
                    e.Graphics.DrawLine(pen, BottomLeft.Add(400).ToPoint(), BottomRight.Add(400).ToPoint());
                    // Connect ceiling and floor
                    e.Graphics.DrawLine(pen, TopLeft.Add(400).ToPoint(),BottomLeft.Add(400).ToPoint());
                    e.Graphics.DrawLine(pen, TopRight.Add(400).ToPoint(), BottomRight.Add(400).ToPoint());
                }
            }

            // Draw player
            // e.Graphics.DrawLine(pen, player.Position.Add(400).ToPoint(), player.Position.Add(400).ToPoint());
            // e.Graphics.FillRectangle(new SolidBrush(Color.Red), 100, 100, 2, 2);
        }