Page 1 of 1

[56K WARN] Help speed up my imagecreatefromgif()

Posted: Tue Oct 25, 2005 3:32 pm
by comrad
Greetz, PHPDN, and thanks for reading this post. I have a working script that could use a little cleaning up to boost performance. Long story short: I'm writing an online RPG in PHP/MySQL and the world map is layed out in tiles 100 X 108.
To travel the map, I use a line of sight idea. Your character can see 6 tiles in each direction while standing in the middle of the image. When you take a step, your character stays in that location while the contents of the surrounding tiles relocate to reflect the movement.
The final output is sent to the browser as a newly generated image.
Here are some pieces:

Image
The base tile. Anything that is not grass is added on, like
Image forest trees,
Imagewater,
Imageand mountains.[/img]
----------------------------------------------------
Queries are made to locate your position and surrounding landscape and the final output is a single image file like this one.
Image
----------------------------------------------------
----------------------------------------------------
As you can see, the script works. But I don't think my methods are as fast as they could be.
Here's that part of my script:

Code: Select all

// The base image of grassland
$background = imagecreatefromgif("los7.gif"); 

// Each player generates his/her own image to view. This overwrites any previous with a blank glassland.
$zpic= imagegif($background,"los/$_COOKIE[username].gif",100);


// $player is known at this point. $tarcol (Target Column), and $tarrow used in the final function calls
$tarcol=$player[col];
$tarrow=$player[row];

// map is in hexagons, so odd columns return different data from even. Rows are zig-zagged.
// this limit the queries to what is applicable. These turn into function argument ($wide).
if ($tarcol % 2 == 0){
$cm6=0;$cm5=2;$cm4=4;$cm3=6;$cm2=6;$cm1=6;$cr=6;$cp1=6;$cp2=6;$cp3=6;$cp4=5;$cp5=3;$cp6=1;
} else {
$cm6=1;$cm5=3;$cm4=5;$cm3=6;$cm2=6;$cm1=6;$cr=6;$cp1=6;$cp2=6;$cp3=6;$cp4=4;$cp5=2;$cp6=0;}

/////////////////////////////
//Finally,  the function.
// It runs 13 times! Once per visible map row.
// a sample call from the bottom: los("-6","$cm6",$tarcol,$tarrow);
//  arguments: ('my row minus 6','determined width','my col','my row')


function los($rownum, $wide,$tc,$tr){
$background = imagecreatefromgif("los/$_COOKIE[username].gif"); 

// scopes query
$row=($tr + $rownum);
$west=($tc-$wide);
$east=($tc+$wide);

// some pixel placement
$centeroffsetcol=($tc-7);
$centeroffsetrow=($tr-6);

//Query
$getthere=mysql_query("select * from map where (row='$row') and (col >= $west) and (col <= $east) order by id");



//more pixel placement
$tx=0;$lx=0;$tinc=27;$linc=30;$coloff=14;

while ($item=mysql_fetch_assoc($getthere)){
//////////////////////////////////////////////////////////terrain
if ($item[terrain] != 'land'){

//final pixel placement
if ($item[col] % 2 !=0){$offset=0;}else{$offset=$coloff;}
if ($tc % 2 == '0'){$offset=$offset+14;}else{$offset=$offset+27;}
$top= ($tx + (($item[row]-$centeroffsetrow) * $tinc) - $tinc + $offset -1);
$left=($lx + (($item[col]-$centeroffsetcol) * $linc) - $linc );


  $insert = imagecreatefromgif("$item[terrain].gif"); 
  imagecopymerge($background,$insert,$left,$top,0,0,40,29,100); 

			    } // if !land

					} // while contents of row

//Save the updated image
$zpic= imagegif($background,"los/$_COOKIE[username].gif",100);  


} // func

los("-6","$cm6",$tarcol,$tarrow);
los("-5","$cm5",$tarcol,$tarrow);
los("-4","$cm4",$tarcol,$tarrow);
los("-3","$cm3",$tarcol,$tarrow);
los("-2","$cm2",$tarcol,$tarrow);
los("-1","$cm1",$tarcol,$tarrow);
los("0","$cr",$tarcol,$tarrow);
los("1","$cp1",$tarcol,$tarrow);
los("2","$cp2",$tarcol,$tarrow);
los("3","$cp3",$tarcol,$tarrow);
los("4","$cp4",$tarcol,$tarrow);
los("5","$cp5",$tarcol,$tarrow);
los("6","$cp6",$tarcol,$tarrow);


echo "<img src=los/$_COOKIE[username].gif id=map>";
Creating this image is currently demanding the creation of 14: the basemap, and 13 updates!
Trying to tighten it up is going to be on my mind all day, so even if no replies, at least I shared some code.

Is it worth it to store my east/west variables to compound a single GIANT query and let ifs work it out?
Or does the creation of 14 images really take that long as compared to one?

Thanks for reading! I look forward to replies.
To play the current build , follow the image urls..

Posted: Tue Oct 25, 2005 4:01 pm
by onion2k
One thing you could do that would have an effect is to create an array of all the different tile types to start off with instead of opening the gifs over and over again.

You're doing..

Code: Select all

$insert = imagecreatefromgif("$item[terrain].gif");
  imagecopymerge($background,$insert,$left,$top,0,0,40,29,100);
.. once for every hexagon. That's a hell of a lot of work considering the number of hexagons.

I would do..

Code: Select all

$tiles['water'] = imagecreatefromgif("water.gif");
$tiles['trees'] = imagecreatefromgif("trees.gif");
$tiles['mountains'] = imagecreatefromgif("mountains.gif");
.. at the beginning, and then..

Code: Select all

$insert = $tiles[$item[terrain]];
imagecopymerge($background,$insert,$left,$top,0,0,40,29,100);
..later in the script. Also, don't call your los function 13 times .. that means you're opening and saving the big gif 13 times more than you should.

Also, if you're interested, there's a pretty good page of info about hex map game programming here: http://www-cs-students.stanford.edu/~am ... g.html#hex

Posted: Tue Oct 25, 2005 5:08 pm
by comrad
feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]


THANKS for this link!

I like the array.  For a time, I was still adding terrain types,    flowers,snow,frost, swamp, blah blah.
But now that it's solid, I could open them all.

I could do this with 1 query I guess,   but it'd be wicked long...

Code: Select all

$getall="select * from map where (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz') || (row='xxx' and col>='yyy' and col<='zzz')";
mmmmmmmm.... but it'd work.


feyd | Please use

Code: Select all

and

Code: Select all

tags where appropriate when posting code. Read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]

Posted: Tue Oct 25, 2005 9:58 pm
by comrad
Whoops. Sorry feyd. Won't let it happen again.
---------------------
I'm happy to say that with the 'terrain array' and the 'mega query' , things are running a lot faster now.