private PInfo[,] renderLine(Line look) { PInfo[,] strip = new PInfo[1, height]; strip.Populate(); // Renderable, dist from origin, dist from player Stack <Tuple <IRenderable, double, double> > renderstack = new Stack <Tuple <IRenderable, double, double> >(); // create a list of all things List <Tuple <Line, IRenderable> > visibles = new List <Tuple <Line, IRenderable> >(); foreach (var item in SpriteObjects) { Line l = new Line(); // angle to player double changeX = Player.x_2 - Player.x_1; double changeY = Player.y_2 - Player.y_1; // get angle to player double angle = Math.Atan2(changeY, changeX); // now rotate and get cords of start and end // origin, left of player l.x_1 = item.Value.Item1 + (Math.Cos(angle - (90 / Math.PI * 2)) * item.Key.Width / 2); l.y_1 = item.Value.Item2 + (Math.Sin(angle - (90 / Math.PI * 2)) * item.Key.Width / 2); // other side right of player l.x_2 = item.Value.Item1 + (Math.Cos(angle + (90 / Math.PI * 2)) * item.Key.Width / 2); l.y_2 = item.Value.Item2 + (Math.Sin(angle + (90 / Math.PI * 2)) * item.Key.Width / 2); visibles.Add(new Tuple <Line, IRenderable>(l, item.Key)); } foreach (var item in DObjectects) { visibles.Add(new Tuple <Line, IRenderable>(item.Key, item.Value)); } // create shorter representation of line double dirX = look.x_2 - look.x_1; double dirY = look.y_2 - look.y_1; double dist = Math.Sqrt(dirX * dirX + dirY * dirY); // normalize vector dirX /= dist; dirY /= dist; // now calculate the number of pixels until first contact with a wall //PInfo wallLook = new PInfo() { hasBackground = true, background = ConsoleColor.Black }; bool reachedWall = false; look.x_2 = look.x_1 + dirX * MAXDRAWDIST; look.y_2 = look.y_1 + dirY * MAXDRAWDIST; double xInt; double yInt; if (look.y_2 == 15.3) { Debug.WriteLine(""); } var found = visibles .Where(v => doLinesIntersect(look, v.Item1, out xInt, out yInt)) .Select(i => { double atX; double atY; doLinesIntersect(look, i.Item1, out atX, out atY); return(new { Object = i, Distance = Math.Sqrt(Math.Pow(look.x_1 - atX, 2) + Math.Pow(look.y_1 - atY, 2)), XInt = atX, YInt = atY }); }) .ToList(); if (found.Count == 0) { Debug.WriteLine("empty"); } var ToRender = found .Where(f => f.Distance <= found.Where(wall => !wall.Object.Item2.isTransparent).Min(closest => closest.Distance)) .OrderBy(all => - all.Distance) .ToList(); foreach (var some in ToRender) { double distFromOrigin = Math.Sqrt(Math.Pow(some.XInt - some.Object.Item1.x_1, 2) + Math.Pow(some.YInt - some.Object.Item1.y_1, 2)); renderstack.Push(new Tuple <IRenderable, double, double>(some.Object.Item2, distFromOrigin, some.Distance)); } //Debug.WriteLine(ToRender.Count); /* * foreach (var item in visibles) * { * double xIntersect; * double yIntersect; * if (doLinesIntersect(look, item.Item1, out xIntersect, out yIntersect)) * { * * if (!renderstack.Select((x) => { return x.Item1; }).Contains(item.Item2)) * { * if (!item.Item2.isTransparent) * { * reachedWall = true; * } * // distance from object origin * double distFromOrigin = Math.Sqrt(Math.Pow(xIntersect - item.Item1.x_1, 2) + Math.Pow(yIntersect - item.Item1.y_1, 2)); * // Object, distance from object origin, distance from camera * renderstack.Push(new Tuple<IRenderable, double, double>(item.Item2, distFromOrigin, inst * 0.01)); * } * * } * }*/ renderstack.Push(new Tuple <IRenderable, double, double>( new Object3D() { isTransparent = false, pattern = new PInfo[, ] { { new PInfo() { HasBackground = true, Background = ConsoleColor.Black } } } } , 1 , MAXDRAWDIST )); while (renderstack.Count > 0) { Tuple <IRenderable, double, double> data = renderstack.Pop(); strip.Merge(data.Item1.Render(data.Item3, height, PlayerHeight, RoomHeight, data.Item2)); } return(strip); }