Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / Slow RTS unit search

Author
Message
Area 51
19
Years of Service
User Offline
Joined: 3rd Feb 2006
Location: UNKNOWN
Posted: 5th May 2008 01:55
I am trying to make an RTS with DBC, but to search for which unit is being clicked on, I use a FOR - NEXT command from 1 to the total units to find which unit the mouse is currently overlaying. I have found that this really slows down my game when there are more units. How can I fix this?

Are we alone?
Profit
19
Years of Service
User Offline
Joined: 19th Feb 2006
Location: United States
Posted: 5th May 2008 02:21
You can use the "pick object" command.

BN2 Productions
21
Years of Service
User Offline
Joined: 22nd Jan 2004
Location:
Posted: 5th May 2008 03:51 Edited at: 5th May 2008 03:54
Quote: "
You can use the "pick object" command."


I didn't think that command was in DBC. Thought it was just DBP.

Anyway, here is how I did it. It isn't perfect, but it works for the most part. The idea is that there is a virtual plane (there isn't a use it making it) in which the mouse exists that is far from the camera. The distance is such that when a "ray" which I just used a long box for is placed there and then pointed at the camera, it will intersect what the mouse is over (as far as the math goes, the mouse's position is below it). This example uses the camera at about 100 on the y axis looking straight down. Certain problems occur the farther you get from the center of the screen, namely that the chance to select what you are pointing at becomes less at less (when I did it, it would start to get off by a couple pixels).

In your loop:


here is the cast_ray function:



Anyway let me know if this works for you

Ever notice how in Microsoft word, the word "microsoft" is auto corrected to be "Microsoft" but "macintosh" just gets the dumb red underline?
Sinani201
18
Years of Service
User Offline
Joined: 16th Apr 2007
Location: Aperture Science Enrichment Center
Posted: 5th May 2008 03:53
He's right. The pick object command isn't in DBC.


Kirby is in my avatar because he rules. Live with it!
Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 5th May 2008 04:45 Edited at: 5th May 2008 04:51
if you map out your terrain in a grid, and only allow one unit to occupy each square (create an array to accompany the grid and store unit position data) clicking on a square would select the unit at that location by referencing the same field in the array.

If you added an extra dimension to your terrain array, you could have multiple units on one square.

The reason why many RTS games (especially old school) use a grid is that it's easy to keep track of everything.

It is far better to complete a 10 line program than to start a 10,000 line program.
Area 51
19
Years of Service
User Offline
Joined: 3rd Feb 2006
Location: UNKNOWN
Posted: 7th May 2008 23:45
Thanks guys

Are we alone?
Lord Einstein
19
Years of Service
User Offline
Joined: 22nd Oct 2005
Location: Well here, of course...
Posted: 8th May 2008 00:02
You could firstly test to see whether the object is in the screen and then only if it is do you run the rest of the code to check if the mouse is overlaying it.
bobba
17
Years of Service
User Offline
Joined: 10th Apr 2008
Location:
Posted: 9th May 2008 05:23
There is more then 1 way to skin a cat, but hear is a bit of advice regarding selecting units in an RTS game. If you find another way of getting it to work then please post an explanation of how you did it.

I assume that you have some form of array which is storing all your units. I also assume you cycle trough this array (FOR - NEXT thing) performing calculations and moving each unit then call DBSync, then repeat the process, and calculate mouse clicks etc once per cycle or turn

The unit selecting mechanism should be combined with the drag select mechanism for good efficiency.

Make it so when the mouse button is held down 1 coordinate is stored, upon releasing the mouse the 2 point is stored. Then call a function to check the coordinate are the right way round. (i.e. top right and bottom left of the selection box)

You will need crank a bit of maths to convert the mouse coordinate which are given in pixels 2D style to 3D coordinate in your game.

Then when each unit has its turn it checks whether it is between the coordinate and changes a flag to 0 if outside and 1 if inside.

This will prevent you from having to do a specific search of your unit array each time you try to select units.

Another tip is to use >= and <= when you are programming the "am i in the selection box" bit. This way it will do both drag select and single click select in one go.

Don’t try to use the pick object command in an RTS. It has its uses but is too slow for RTS selection, it also of no use with implementing drag select.

You will also want to limit the rare of user input to every 250ms or 4 times per second. Most modern RTS games use this system (including starcraft and SUPCOM). The primary reason for doing this is to limit the amount of information that will have to be sent when playing multiplayer. But it also has the additional effect of preventing repeat commands as no one on earth (except a handful of Koreans who were probably produced in labs for the sole purpose of pwning at Star Craft) can meaningfully enter more then 4 commands per second when playing RTS. When implementing this limit you will need to play some turns with user inputs and some without, otherwise your game will only play at 4 fps.

Hope my ramble helps. I am slack at re-checking threads I have posted on as there is no search mechanism so if you want anything explained in more detail I have recently started a new thread dedicated to RTS.

Ps If you have a demo of the work in progress it would be great to see.
TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 11th May 2008 05:21 Edited at: 11th May 2008 05:22
Quote: "Don’t try to use the pick object command in an RTS."


He couldn't even if he wanted to. As was stated earlier in the thread it simply isn't present in DB Classic!!

You've cleverly explained all the easy bits of the process, skipping the difficult part that people can't do with:

Quote: "You will need crank a bit of maths to convert the mouse coordinate which are given in pixels 2D style to 3D coordinate in your game."


Here's one method of selecting multiple troops, though you'll find loads more info if you use the Search button:



TDK_Man

Libervurto
18
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 12th May 2008 01:34
how the hell do you convert 2D co-ordinates to 3D co-ordinates?
it comes up so often and i've never seen an answer

It is far better to complete a 10 line program than to start a 10,000 line program.
bobba
17
Years of Service
User Offline
Joined: 10th Apr 2008
Location:
Posted: 12th May 2008 03:50 Edited at: 12th May 2008 03:55
Quote: "You've cleverly explained all the easy bits of the process, skipping the difficult part that people can't do with:"


Guilty as charged - but I fingered people could ask if they wanted to know more.

I will try to explain the 2D 3D thing better.

Now the way it will work will vary on the game style. I will explain a simple method. I will assume the game is of top down view and there is no tilt or rotate on the camera.

Now when you get the 2d coordinates with the pick mouse thingy they are given in pixels according to the screen resolution.

Now you will 1st need to know a bit of vector maths. Now a 3d vector is basically the difference between 2 points in space. i.e. the difference in x,y and z between one point and another.

So to convert the 2d to 3d you will need to use something like this

dbPickScreen (dbMouseX (), dbMouseY (), -CamZ ); // call function to generate vectors

PickingVectorX = dbGetPickVectorX ();//
PickingVectorY = dbGetPickVectorY ();//Retreving vector
PickingVectorZ = dbGetPickVectorZ ();//

the dbPickScreen get the difference between one point and another point at a depth of the 3rd parameter. Note I have passed it the mouse location as in the 1st two. CamZ is camera zoom in my program or the distance from the camera to the ground.

But we still have to scale the vectors because we have just kind of cast out a round shape. Ie we always look a set distance from the camera, so if we click off centre it will not hit the ground. Its like holding a bit of string from a peg in the ground and pulling it tight until it just touches a wall. If the string is pivoted round it will have to be extended to stay touching the wall.

So divide all vectors by the z vector. note anything divided by its self is 1.

PickingVectorX = PickingVectorX /PickingVectorZ;// scaling vector
PickingVectorY = PickingVectorY /PickingVectorZ;//
//PickingVectorZ = 1; //(PickingVectorZ / PickingVectorZ = 1)

Then you will need to multiply them by the actual distance from the camera to the ground:

PickingVectorX = PickingVectorX * -CamZ;// rescaling vector for
PickingVectorY = PickingVectorY * -CamZ;// distance
//PickingVectorZ = PickingVectorZ * -CamZ;// always = -CamZ

Then remember a vector is a difference between 2 points so you must add it to your camera position to get the final location.

AbsoluteX = PickingVectorX + dbCameraPositionX(); //canculating
AbsoluteY = PickingVectorY + dbCameraPositionY ();//final position

I hope this explains it!
TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 14th May 2008 08:19
Quote: "Now when you get the 2d coordinates with the pick mouse thingy"


And what would that 'pick mouse thingy' be?

As has already been said a number of times, this is DBC we are talking about here, not DB Pro or Dark GDK - hence the difficulty in doing what the OP originally asked for.

DBC has Object Screen X() and Object Screen Y() and that's it! They are the only two available native functions of any use for doing this task - apart from MouseX() and MouseY().

Your explanation, correct as it may be still relies on functions not available in DBC.

I've already posted a code snippet which shows one way to do what was asked - assuming I understood what was being asked correctly.

Quote: "how the hell do you convert 2D co-ordinates to 3D co-ordinates?"


I posted a code snippet to do it not long ago in another thread. I'm not sure, but wasn't it you who asked how to do it with maths anyway? Actually, now I come to think of it, it might have been INH...

TDK_Man

bobba
17
Years of Service
User Offline
Joined: 10th Apr 2008
Location:
Posted: 16th May 2008 03:01
Hi,

Its good that you have provided code for solving the problem but sometimes some explanation of how it works is also nice. As can be gauged by the inquiry from OBese87.

I was not aware DGDK and DBC are so different and i can now appreciate how a few of the things I said could confuse DBC users.

In response to OBese87s comment and seeing you had provided a code solution I was trying to explain the method behind the maths so that people will understand the principles. I believe a good understanding of maths is critical to advancing in programming and vectors are the most efficient way of solving the problem.

Listening to what you said about the differences between the versions I will be more careful what I say referring to particular functions etc.
TDK
Retired Moderator
22
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 17th May 2008 06:33
Quote: "but sometimes some explanation of how it works is also nice"


Agreed - as long as there is a way to implement the explanation. I was only trying to make the point that in DBC we are missing the essential command to make what you explained possible!

Quote: "I was not aware DGDK and DBC are so different"


Crikey yes - chalk and cheese if you ignore the core BASIC elements. A lot of advanced commands have been added to DB since DBC came out.

Dark GDK is effectively DBPro for C++, whereas DB Classic (think of it as DB V1) is getting on for 10 years old now!

DBPro has had literally hundreds of new commands added, as well as support for all things DX9 whereas DBC is officially still DX7, has no native particle system, shaders, advanced terrains... the list is endless!

DBC is good for learning with or if you are on a tight budget and still capable of producing pretty decent games. More importantly, anything written in DBC is compatible with DBP with little or no tweaking - but not the other way around...

TDK_Man

Login to post a reply

Server time is: 2025-06-05 21:16:13
Your offset time is: 2025-06-05 21:16:13