Well, I will try a step-by-step way, to make an easy full picture. The final part is not finished yet.
Instead of cast a ray every angle, just look for the vertices, and cast a ray to them.
STEP 01 - Schematic view.
Note: All
shadable objects MUST be contained in the
same list.
Pl = player;
Wall is a shadable object;
STEP 02 - The basic structure of things.Code:
class TPointFloat
{
X, Y : float;
};
class TLine
{
XStart, YStart : float;
XEnd, YEnd : float;
Angle : double; // I'm not sure if double(C++ and C#) is the one used for angles.
};
class TPlayer
{
FCenterPosition : TPointFloat;
};
class TObjectShadable
{
VerticesList : List of TPointFloat; // for security and flexibility, let's say that this list is dynamic.
FListOfProcessingLines : List of TLine
FListPolygonShadows : List of TLine;
};
class TDarkArea
{
FLine1, FLine2, FLine3, FLine4 : TLine;
};
class TWall (TObjectShadable)
{
VerticesList : List of TPointFloat; // it is just the same list of TObjectShadable.
MyWallSprite : CBitmap;
};
class TMap
{
FObjectsList : list of TObjectShadable; // what includes TWall.
};
Your wall, for example, is like this(1 bmp, 4 vertices):

Global declarations:
Code:
FThePlayer : TPlayer;
FTheMap : TMap;
FListOfProcessingLines : List of TLine
STEP 03 - The beginning of the algorithm.What we must know is that there are 2 loops. One inside the other. You could put this code inside a function in the class TMap, for example.
The outer loop make a scanning from the first shadable object to the last:
Code:
SOIndex : Integer;
for SOIndex := 0 to (FObjectsList.count - 1) do
{
// The second loop here;
};
the variable
count is the number of elements inside FObjectsList, since the loop
begins from 0, the final index must be the
count - 1The second loop will scan every vertex of the object indicated by SOIndex:
Code:
SOIndex : Integer;
VerticeIndex : Integer;
for SOIndex := 0 to (FObjectsList.count - 1) do
{
// FObjectsList.item[SOIndex] is the current object.
for VerticeIndex := 0 to (FObjectsList.item[SOIndex].VerticesList.count -1) do
{
// Now we will store the lines that begins from the player center and ends at the vertices of the object.
BTheNewLine : TRLineS;
BTheNewLine.XStart := FThePlayer.FCenterPosition.X;
BTheNewLine.YStart := FThePlayer.FCenterPosition.Y;
BTheNewLine.XEnd := FObjectsList.item[SOIndex].VerticesList.item[VerticeIndex].X;
BTheNewLine.YEnd := FObjectsList.item[SOIndex].VerticesList.item[VerticeIndex].Y;
BTheNewLine.Angle := GetAngle(BTheNewLine.XStart, BTheNewLine.YStart, BTheNewLine.XEnd, BTheNewLine.YEnd); // I'm still looking for a good implementation.
FObjectsList.item[SOIndex].FListOfProcessingLines.add(BTheNewLine); // now we add the new line to the list of processing;
};
};
IMPLEMENTATION!We want to scan only objects inside the scene, so:
Code:
SOIndex : Integer;
VerticeIndex : Integer;
for SOIndex := 0 to (FObjectsList.count - 1) do
{
// FObjectsList.item[SOIndex] is the current object.
// If any of the vertices of the object is inside the scene, proceed.
if VerticesInsideTheScene(FObjectsList.item[SOIndex].VerticesList) then
{
for VerticeIndex := 0 to (FObjectsList.item[SOIndex].VerticesList.count -1) do
{
// Now we will store the lines that begins from the player center and ends at the vertices of the object.
BTheNewLine : TLine;
BTheNewLine.XStart := FThePlayer.FCenterPosition.X;
BTheNewLine.YStart := FThePlayer.FCenterPosition.Y;
BTheNewLine.XEnd := FObjectsList.item[SOIndex].VerticesList.item[VerticeIndex].X;
BTheNewLine.YEnd := FObjectsList.item[SOIndex].VerticesList.item[VerticeIndex].Y;
BTheNewLine.Angle := GetAngle(BTheNewLine.XStart, BTheNewLine.YStart, BTheNewLine.XEnd, BTheNewLine.YEnd); // I'm still looking for a good implementation.
FObjectsList.item[SOIndex].FListOfProcessingLines.add(BTheNewLine); // now we add the new line to the list of processing;
};
};
};
Let's see what this code does:

The objects containing vertices(
in yellow).

This is how the loop see the list of objects, beginning from 0.

This is what the code inside the loops does. The
RLineS-01 is the
first resulting line from scanning added in the list of lines wich will be processed. In the second image you see the resulting lines taken from the scanning of the second object and its vertices.
Note: the
resulting lines from scanning are not the lines wich will make the shadow polygon.
STEP 04 - Creating the shadow polygons.Now, we will create the new global variable:
Code:
FListPolygonShadows : list of TLine;
This is a step-by-step scheme:

We are in the step 3 inside "Create shadow polygon".
Look the following picture:

The pink area is the outside of the screen. Outside of the screen we have 4 vertices, a square rounding the screen.
Now we create a loop, that creates a new shadow line for each resulting line we got before:
Code:
for SOIndex := 0 to (FObjectsList.count - 1) do
{
for BLineIndex := 0 to FListOfProcessingLines.count -1 do
{
//Create the new shadow line:
BTheNewShadowLine : TLine;
// The following code says that the shadow line start where the resulting line ends, and get its angle:
BTheNewShadowLine.XStart := FListOfProcessingLines.item[BLineIndex].XEnd;
BTheNewShadowLine.YStart := FListOfProcessingLines.item[BLineIndex].YEnd;
BTheNewShadowLine.Angle := FListOfProcessingLines.item[BLineIndex].Angle;
// Now we call a raster functions, that increases the end value of the shadow line until it find the outsidescreen square:
ProcessEndPointOfShadowLine(BTheNewShadowLine);
// The increment process uses the angle to know the direction to increase the line.
// Add the new shadow line to the list of shadow lines:
FObjectsList.item[SOIndex]..FListPolygonShadows.add(BTheNewShadowLine);
};
};
This is what happens in the first index of the loop:
STEP 05 - How the function ProcessEndPointOfShadowLine knows if the end point collided with the outside square.Well, the functions ProcessEndPointOfShadowLine will check( for each increment ) if there is a intersection between the shadow line and the lines of the square. This process may be slow if we make a small incrementation, then, we must make a median or high incrementation.
Note - Check Line Intersection Function examples:
http://www.ucancode.net/faq/C-Line-Inte ... rawing.htmhttp://www.i-logic.com/utilities/trig.htmThe result of the high incrementation may be something like this:
Now, I'm studying how to merge the vertices to create the polygon. 
Links I used to make the concept:
http://flassari.is/2008/11/line-line-in ... cplusplus/http://cboard.cprogramming.com/contests ... tions.htmlhttp:// paulbourke. net/geometry/insidepoly/
http:// forums.tigsource. com/index.php?topic=8803.0
http:// en.wikipedia. org/wiki/General_Polygon_Clipper
[HAVE YOU SEEN THIS?!]http://
http://www.saltgames. com/2011/2d-shadow-effects/