Hello. First time posting on these forums as I am really stuck on my code. The language I am using is GML (Game Maker Language) and the program Game Maker: Studio. As I could not get any help on GM forums I am seeking help elsewhere.
The game I am making is a remake of a retro game called QIX.
"Qix is an old game where you are drawing boxes in order to fill in the screen with a color or image while avoiding enemies. To pass a level you must fill in a certain percentage of the screen. A more modern game series with this gameplay would be the Gals Panic series."
Youtube: http://www.youtube.com/watch?v=nBt4w3qKI6I&feature=player_detailpage#t=32
Wikipedia: http://en.wikipedia.org/wiki/Qix
I have made it work, but the problem is that it is extremely slow. It takes about a minute for larger area to be drawn. What I am doing:
-After the player finishes his move I have an array of the current lines and it adds the new lines that the player just made to the array.
-It takes two points on each side of the first line and checks a line from one point to the QIX. Depending on the lines crossed it calculates which point is in the closed area without the QIX. This can turn out wrong in some cases, not only because the check (if even number of lines crossed, QIX is in the same area) is wrong, but also the way I check if the lines crossing is wrong. Before drawing I fix this by checking if the QIX is on revealed pixel and if yes, I swap all values(explained later). So suggestions on how to check, which side of the line the QIX is on are welcomed too.
-Then it sets the point that is supposedly not on the side of the QIX to 2 in a 2D array. I also have min and max x and y values of the 2D array, which at the start also equal the point's x and y.
- After that it checks the 2D array from min to max values until there are no values that equal 2. If a value = 2, it checks if a line crosses it. If no, it sets the top, bottom, left and right points to 2, and changes min and max x and y values if needed. This one point that was checked is set to 1.
This way I have a 2D array with 0 for covered and 1 for uncovered points. And here is the code that does that:
do //This is the code after I have a starting value in the 2D array - pointd
{
enough=1
for(for1=minx; for1<=maxx; for1+=1) //min and max x and y values of the points for checking
for(for2=miny; for2<=maxy; for2+=1) //so it doesn't check everything everytime
{
if(pointd[for1,for2]=2)for(aba=1;aba<=thln;aba+=1) //If it is 2, check it with every line
{
if(((for1>=thlposx[aba] and for1<=thlendx[aba]) or (for1<=thlposx[aba] and for1>=thlendx[aba]))
and((for2>=thlposy[aba] and for2<=thlendy[aba]) or (for2<=thlposy[aba] and for2>=thlendy[aba])))
{pointd[for1,for2]=1; aba=thln+1} //If it is on a line, set it to 1, to be drawn and stop checking
}
if(pointd[for1,for2]=2) //If it is not on a line, set adjacent point for checking
{
enough=0 //stop value to 0, continue with do until
pointd[for1,for2]=1 //set point to be drawn
if(pointd[for1-1,for2]=0)pointd[for1-1,for2]=2 //set points to be checked
if(pointd[for1+1,for2]=0)pointd[for1+1,for2]=2
if(pointd[for1,for2-1]=0)pointd[for1,for2-1]=2
if(pointd[for1,for2+1]=0)pointd[for1,for2+1]=2
if(minx=for1 and for1>1)minx=for1-1 //if this is min or max x or y change it
if(miny=for2 and for2>1)miny=for2-1
if(maxx=for1 and for1<319)maxx=for1+1
if(maxy=for2 and for2<374)maxy=for2+1
}
}
}
until enough=1
if(pointd[objQIX.x,objQIX.y]=1) //if it got the wrong part of the screen (the wrong side of the line), change all
{
for(aaaa=0; aaaa<=320; aaaa+=1)
for(aaaaa=0; aaaaa<=375; aaaaa+=1)
if(pointd[aaaa,aaaaa]=1)pointd[aaaa,aaaaa]=0
else pointd[aaaa,aaaaa]=1
}
It appears that the do until cycle spins less than 100 times in simple cases and 200-400 times for more complicated ones. The problem seems to be this cycle:
if(pointd[for1,for2]=2)for(aba=1;aba<=thln;aba+=1) //If it is 2, check it with every line
{
if(((for1>=thlposx[aba] and for1<=thlendx[aba]) or (for1<=thlposx[aba] and for1>=thlendx[aba]))
and((for2>=thlposy[aba] and for2<=thlendy[aba]) or (for2<=thlposy[aba] and for2>=thlendy[aba])))
{pointd[for1,for2]=1; aba=thln+1} //If it is on a line, set it to 1, to be drawn and stop checking
}
That for cycle does over 100,000 spins in most cases, and even over 1,000,000 for bigger areas.
Any ideas or code on how to speed it up or change it to a more efficient algorithm are welcome. Thank You in advance!