Archived

This topic is now archived and is closed to further replies.

-Fruz-

Directdraw - top-down game, limited vision?

Recommended Posts

hmmm.. how would i go about adding limited "vision" in my top-down shooter. like, everything is black, exept a triangle wich is your "sight field"? hmm.. do i create a triangle, and just blit a hole with it? hmm.. but then, how would i rotate it? as far as i know, only d3d suports rotating/has it built in, and i figured any rotation done by pixel manipulation is too slow? JFK

Share this post


Link to post
Share on other sites
Firstly, you were right about pixel stuff being way too slow, and that triangle thing was a good thought but completely out of the question.
You''d better hope you are doing a tile-based game, or you only want your los to apply to objects and not the enviorment. Basicly, it is very simple... every time you want to blit something (perhaps a tile or an enemy or whatever) you first check to see if the pleyer can ''see'' it. If he can, then go ahead and blit. How do we know if the player can see something? Like this...
Two ways, I sugest you use a combination of both for what you want.
For that triangle thing, for each object or tile you blit you check the difference between the dirrection the player is facing and the direction from the player to the thing we are blitting. If the angle difference is bellow, say, 45 degrees, then we go ahead and blit. This is how I would do the triangle thing.
The other way is to check if a straight line between the player and the object/tile is blocked. If it is, then the player cannot ''see'' the thing so we do not blit it. However, I suggest checking if the lines are blocked on a tilemap based level for the sake of speed, and if your not using a tilemap I''m sure you''ll think of something.
For what you want, I suggest using a combination of both methods - first check the angle difference, the go on to check the straight line thing.
Of course, your line of sight will be totally ''blocky'' ie you see something one moment then the next it is completely gone, but that is about the best you can do in DDraw.
Note that this is how I do it, and there is quite possibly a better way, considering that this method comes straight from my own creation.
If you need help, post back. I have all the code you would need. And for God''s sake, checking the difference between two angles does NOT mean simply subtracting one from the other.

Share this post


Link to post
Share on other sites
thanx jack, that was really helpfull. i would be lying if i said i havent thought of similar ways, but i never thaught they were good enough, ie, fast enough and looked nice enough. but now i''m convinced. thanx for taking the time to post such a big and informative post.
JFK

Share this post


Link to post
Share on other sites
Well it certainly doesnt look great... but it works well speed-wise. I use the strait-line-blocked thing in my tile based game and it works perfectly with no drop in the framerate whatsoever. I blit about 300 tiles to my screen at once and, as I said, no speed cost - suiprising when I have a 450 mhz PC with less than 64 megs of ram.
To disguise the blockyness of los on tiles, you could hold the los thing in an array, run a check, and blit edges for the los onto the back buffer.

Share this post


Link to post
Share on other sites
mkey, hmm.. you said you had some code, if i needed more help. hmm, i dont need help with the code, but, it would be great to see an example of it in action, i can only imagine, and.. imagination is often wrong :\ hmm.. so, willing to share?

JFK

Share this post


Link to post
Share on other sites
Geee... my game that I am working on (with my los) is getting fairly large... uses DDraw. I suppose I could give you some screenshots demonstrating los. E-Mail adress? I use hotmail, and maximum sending thing is 1 meg, see why I cant send the whole thing?

Share this post


Link to post
Share on other sites
heh, i guiess i was just dumb not thinking of ascreenshot. that would be just as goood, thanx. if you would mail me one, you could either click my little mail icon, or use this address: jfk-post@online.no
i will be very thankfull. thanx

JFK

Share this post


Link to post
Share on other sites
Just sent the screenshots. The only thing I ask is that you dont take any of my graphics... not that you would, but I should cover myself. Let me know if you need any more help.

Share this post


Link to post
Share on other sites
heh, i goto say, that game look so darn much like mine, except mine is "totally" top-down. you were right about it not looking too good, but.. hmmm, it's fair, atleest for a game like this.
anyway, i just want to say thanx, both for screenies and help.
thanx (no, offcoarse i wouldnt steal gfx, that only creates a kind of "this aint mine" feeling.. hmm.. besides that it's just plain "low".)

this is how i planned it;
an angle loop, going from the facing angle, - 45 to + 45 (angle - 45 to angle + 45) (to create a 90 degree field of view), and a loop inside, counting tiles. like drawing lines of tiles out of my character. hmm.. how does that sound? way off?

JFK

[edited by - -Fruz- on July 31, 2003 2:21:23 AM]

Share this post


Link to post
Share on other sites
Well, that sounds... unsusal. Drawing lines out from your character would work, but it would be difficult to do and I dont thing you''d get any speed advantages cause you''d be alot of complicated calculations. For instance, how may of the tile-lines would you draw from the player? Alot, and it seems you''d be bliting the same tiles many times just to reach the final ones.
Here is how I do it (changed a little to suite you ''triangular'' los. It is very simple, and my guess is that you could do it in five minutes... it simply adds to your tilemap drawing loop with a calculation before each blit. You still do the same loop to render your tiles in rows and coloms.
I assume you have a tile-blitting loop that looks something like this:

for(int i=0;i{
for(j=0;j
{
//Draw tile appropriatly
}
}

Only it would be much more complicated to account for views, offest etc.
Keep this, but before blitting each tile, check if we can ''see'' it. Use these functions:

int angle_difference(int A,int B)
{
if ((A+180)B)
{
if(A A = A+360;
else
B = B+360;
}
int D = abs(A-B);
return D;
}

int angle(int ax, int ay, int bx, int by)
{
int result;
int dx=bx-ax;
int dy=by-ay;
result = (atan2(dx , dy)) * 180 / 3.14;
result = result - 90;
if (result < 0)
{
result = result + 360;
}
return result;
}

and have your code do this:

for(int i=0;i{
for(j=0;j
{
if( angle_difference(player.direction , angle( player.x/32, player.y/32, i/32, j/32))<45)
{
//Draw tile appropriatly
}
}
}

Simple! Obviously, if you want you los to be blocked by objects you will need an additional fuction check to find out if the los to a certain tile is blocked. I could give you the code for that if you want.
As for that drawing lines of tiles out of the player, I personally do not think that is a very good idea. Hope this has helped.
And hey, you said you were doing a game like mine? Cool. Is it an action wargame? I am making a game where two sides (Allied and Axis) fight for control of ''strongpoints'' on a 2d battlefield. Each side consists of several Plattons (which the player can chose to command or fight with under a AI bot commander) and they operate independantly to defeat the enemy platoons (each platoon has 6 men).
Post again if you need help.

Share this post


Link to post
Share on other sites
Those loops are soposed to say
for(int i=0;iNo idea why they all came out like that (missing bits), and also no idea why the text came out in bold.??

Edit... Ok, this is weird. Wont show the proper text. Anyhow, I'm sure you know what a for loop looks like.

[edited by - jack_1313 on July 31, 2003 3:16:57 AM]

Share this post


Link to post
Share on other sites
thanx, really informative. hmm. i guess my game has similarities, but. it's actually a little mini version of counter-strike. 2 teams "tactically" hunting each other down.
not more to say really. heh. hmm, but as for "my" method of tile drawing. wouldnt it be just as fast as yours? concidering you do exactly that (without drawing) AND normal drawing? hmm... i know i will end up drawing some tiles multiple times, but, drawing a lil tile isnt very time consuming. hmm.. and i dont think the calculations would be too hard. take a look;

tile width and height = 20, so, the angle step would be, 90 / 20, witch is 4.5.
now i'd just start a loop, like this,

for(double a = angle - 45; a < angle + 45; a += 4.5) {
then just
for(int out; out < (sightlenght); a += 20) {
x = cos(a) * out;
y = sin(a) * out;
t = .....
bla bla..?
now i could just hop to the next angle if i stoumbled upon a wall, or some other sort of sight blockin.

this would make a maximum of 400 loops, if the sightlength is 20, but concidering there are walls and objects all over, i suggest less than 200.

hmm... i havnt exactly been programming games for too long, so, i trust your statements, but.. u know.

JFK

[edited by - -Fruz- on July 31, 2003 3:36:53 AM]

Share this post


Link to post
Share on other sites
Nox by Westwood has a nice line of sight thing, and I believe it is written in DDraw7... May be wrong though. They have "smooth" lines, not entire tiles being removed at once.

-Trond

Share this post


Link to post
Share on other sites
Having never played Nox, I don''t know what you are talking about. But I ask these questions:
Is the los in Nox similar to shroud of ''fog of war'' in games like Red Alert, where the los still takes the form of tiles, but we have curving ''edges'' where los-blocked tiles meet visible tiles? If so, this is actually very easy to do with DDraw.
Are you sure Nox is DDraw only, rather than DDraw with elements of D3D init (like many 2d games ie Starcraft). In D3D, los can look lovely because you can manipulate the shades and colors of each vertex (a sprite in D3D is a rectangle... 4 vertecis, one for each corner). Does Nox have alpha-blending? If it does, you can bet that it uses D3D.
And Fruz, let me know how you go with it.

Share this post


Link to post
Share on other sites