Gears, thanks for the heads-up on the security. I did a ton of reading on this and I still think it is safe to use sessions info, but, you do have to make a LOT of changes in the way you pass everything. I now see how a lot of holes can be in a php session site. Actually, now I have to go back and change one of sites to be safer.
Thanks again for making me read up on this! EA…
So I wrote the function for drawing my minimap but I have several problems with it. Like you said Gears I used a color picker to store the player’s color in my database. I then use imagecreate() to create a 1x1 pixel image and color it with imagecolorallocate() using the right rgb values.
My biggest problem is that it takes a good 30 seconds for the page to process so it’s VERY slow, and I’m not even drawing the whole minimap. My second problem is that no matter what rgb values I pass to imagecolorallocate() it always produces a white image. It’s supposed to produce a white pixel for an unclaimed tile but it does it for claimed tiles as well. So I’m not sure what’s going on, here’s the code:
[php]function MinimapDraw($XC, $YC) {
for ($y=1; $y<=101; $y++) {
for ($x=1; $x<=101; $x++) {
$X = ($XC - 51) + $x;
$Y = ($YC - 51) + $y;
// Display black pixel if edge of the world is reached
if ($X < 1 || $X > 1000 || $Y < 1 || $Y > 1000) {
$im = imagecreate(1, 1) or die("Cannot Initialize new GD image stream");
$Background_Color = imagecolorallocate($im, 0, 0, 0);
imagepng($im,"image.png");
imagedestroy($im);
echo "<img src=image.png?>";
continue;
}
// Get the tileID for query
$TID = (($X * 1000) - 1000) + $Y;
// Perform database query to find graphic information
$result = mysql_query("SELECT * FROM tiledata WHERE TileID=$TID");
if (!$result) {
die("Database query failed: " . mysql_error());
}
$row = mysql_fetch_array($result);
$Color = $row["Color"];
// Convert hex color to rgb
$rgb = hex2rgb($Color); // returns rbg values in array $rgb
$im = imagecreate(1, 1) or die("Cannot Initialize new GD image stream");
$Background_Color = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);
imagepng($im,"image.png");
imagedestroy($im);
echo "<img src=image.png>";
}
}
}[/php]
Oh and I wasn’t sure what you meant by caching the results, unfortunately I don’t have the PHP knowledge to know what that is yet hehe. But I hope you guys can help me with the above code, thanks again.
Well, I think you are going about this all wrong. You are creating a TON of images and then destroying them.
What this does is make it a lot of work for the server. I think it would be TONS faster by just creating the
minimap as ONE image. Then, just draw colored dots on it using the imagedraw functions.
What this will do for you is only require ONE image and ONE image creation/detroy call. That should speed up the work 10-fold or most likely 100-fold… Now, for your information, you can imagine the image functions as, basically, PaintShop-in-PHP… Yes, I said that! You can “paint” one image on top of another to create avatars for a game. (We did this in another thread for a gal who had a signature at the bottom of her site with two avatars around what she was doing online at the moment. really cool!) You can cut and past images, draw in shapes on them, change their colors, save them as files, just about anything you can imagine. But, all that is overhead. So, think of using just one image and “writing” on it one dot at a time. That would involve no other image creation or destroy calls which use up a lot of resources.
Here is a link to how to draw a square on an image. Perhaps that will help explain it. You can save the color in the 3-number method and just drop it into the image function and write a dot. (rectangle 1x1)… I think there is a function for one pixel somewhere. Also, look on the left of this manual and you will see all of the many many functions available for image functions. You combine them to make useful new functions…
Good luck… http://php.net/manual/en/function.imagerectangle.php
creating one big image and drawing on it the claimed spots… INGENUES!
and it would be simple, in you’re 1000x1000 you create one big img, and the x,y used in the map is used in the dots on the map, thou it would be a very large img still, since images go by xy you would have each pixel set as each tile, it works perfectly, when drawing the image u set each pixel the different color as it draws the img.
so:
[php]$x = 1;
$y = 1;
$pos = $x . ‘,’ . $y;
$img = create_img()
for($count = 0; $count <= 1000; $count++){
$rl = db_query("SELECT color,user_id WHERE tile = ‘$pos’ ")
if(value_exist($rl)){
set_pixel_color( //you will have to figer out position withing the img and compare it to the map
,$rl[‘color’], $x, $y );
} else {
set_pixel_color( white, $x, $y);
}[/php]
its kinda rough but it gets the point across.
“Elementary, my dear Watson!” LOL…
Yes, I am not sure why he is using this minimap. I mean I am not sure how he wants to have the player access it and how it interacts with the rest of the screen, but, something like that should work. The minimap can be displayed in a scrollable window if needed and the player could access it with an option to make it fullscreen. You can still click on it using the picture’s handle for the click option to read the x/y of the mouse. Should work.
I usually “see” the logical ways… All those small image creation/destroy’s take forever! Well, when he gets back he will have a lot to read and work on… LOL… One puzzle breeds another! LOL…
Thanks guys I’ve made some progress, like you said I used one image and painted on rectangles for each tile. It’s considerably faster but it still takes a second or two to execute, here’s the new code:
[php]
<?php
$im = @imagecreatetruecolor(250, 250) or die(“Cannot Initialize new GD image stream”);
$Black = imagecolorallocate($im, 0, 0, 0);
for ($y=0; $y<=49; $y++) {
for ($x=0; $x<=49; $x++) {
// Get the coordinate of the tile
$X = ($XCenter - 25) + $x;
$Y = ($YCenter - 25) + $y;
// Display black tile if edge of the world is reached
if ($X < 1 || $X > 1000 || $Y < 1 || $Y > 1000) {
imagefilledrectangle($im, $x*5, $y*5, ($x+1)*5, ($y+1)*5, $Black);
continue;
}
// Get the tileID for query
$TID = (($X * 1000) - 1000) + $Y;
// Perform database query to find graphic information
$result = mysql_query("SELECT * FROM tiledata WHERE TileID=$TID");
$row = mysql_fetch_array($result);
$Color = $row["Color"];
// Convert hex color to rgb
$rgb = hex2rgb($Color); // returns rbg values in array $rgb
$TileColor = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);
imagefilledrectangle($im, $x*5, $y*5, ($x+1)*5, ($y+1)*5, $TileColor);
}
}
imagepng($im,"image.png");
echo '<img src=image.png>';
imagedestroy($im);
?>
</div>[/php]
Whoops I submitted my post without finishing it by accident, there should really be an edit option on the forums lol. I was going to ask if there is any way to make the above code faster than it already is. Let mw know and thanks again in advance. I’m starting to get the hang of coding in PHP, in many ways it’s not much different from Vb.net which is a bonus for me
Well, one problem with that code is you are doing a complicated process in the middle of each pass.
You check for the edge of the world EVERY pass… Not needed. When you create the minimap, just
make it ALL black first. Then, remove the checks for the end of the world and the drawing of the edges.
In this manner, you save a huge amount of calculations for that checking and drawing of the edges.
Since you are already calculating where each tile goes, you will be drawing the tiles on the black background.
Should speed it up a bit!
Also, database queries are fast. But, starting them up is slow. So, when you send a query to look up a tile,
it takes a few moments for the database to get the data for you. I would do this OUTSIDE of your loop.
You could do a query like : $tiles = mysql_query(“SELECT Color FROM tiledata ORDER by row, col”);
What that would do is create an array of the colors ordered correctly. Then, INSIDE the drawing loop,
you would not have to stop and pull thousands of queries. You would just have to calculate which indices to
pull the color from the array. Something like: $color = $tiles[$row*1000+$col]; (just guessing)
This would drop thousands of queries into ONE (1) query and give you the same results. Between these
two tricks, you should see a HUGE speed increase.
Should help you a lot… Waiting for the next puzzle… LOL…
Oh, two more things… If you only need one item such as “color” from a database don’t do a (SELECT *) !
It will take all of the data for that table and will take longer for PHP to parse it. Use (SELECT Color)…
And, you can edit your text once you have become a member for a period of time and if you have made
enough posts. It tells you about that in the docs for this site…
Could not have said it better myself!
also just save the created IMG in a temp folder like
/temp/img/mini_map.png
then just use a img link to it,
then use a table to store the last time the map was created then recreate the map every 10min, this can be done at the end of every php page with a simple include to the check time file.
will save u mass amount of system time and memory. and until it becomes super popular and needs it real time, 10m is a good time wait, and its simple to do a is_owned check if someone tries to use a taken tile.
hmm Gears you just gave me an idea about how to generate the mini map. Since I’m already making a world map where the entire 1000x1000 map is shown, couldn’t I just cut out the section I need for the mini map from the world map and just display that instead? I assume this would be much faster than building the mini map tile by tile. That way I’d only have to update the world map and just use sections of it for the mini map.
I assume this could be done with the imagecopy() function, in fact I just tried it right now, but for some reason I can’t get it to display the image. Instead of the image I’m getting this gibberish where the mini map should be:
Here’s my code I wrote just to test the imagecopy() function, anyone know why I’m not getting in image?
[php]
$src = imagecreatefrompng(“world_map.png”);
$dest = imagecreatetruecolor(250, 250);
imagecopy($dest, $src, 0, 0, 0, 0, 250, 250);
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
?>
In basic terms, that code should work. Except you are using a 251x251 pix stuffed into a 250x250 version???
250 is 0-249, not 0-250… that might be the issue…
hmm played around with the image sizes, still no luck. Don’t you hate it when you get stuck on something little? lol… coding is frustrating sometimes
If you echo the input full-map does it display correctly? Make sure you are starting with a good image!
yep when I echo it shows the entire map. So the starting image is good. I’m using a 1000x1000 starting image but I’ve tried smaller ones as well. All of them display random gibberish lol. I’ve gotten pretty desperate, just playing around with the image sizes and seeing if anything changes, no luck so far
Well, going by the PHP manual, you first have to send the picture headers just before you echo the picture.
Here is the page on it… Look down to the first sample…
if you’re just copying a file, just use phps file functions silly.
It’s alright I finally figured it out. I just had to echo the output of the image that’s all. If I had a nickel for every time I get stuck on something silly… lol
On the bright side everything is much faster, instead of generating and saving the world map every 10 minutes, I simply paint on the new land whenever someone claims more land. Much Much faster.
even better!
btw I want to play this game, it sounds fun ^.^
STOP PLAY’n and get WORK’n
So, WE can play it… LOL… Sounds like you are get’n along great! ! !
may I make a suggestion?
can you add a rare chance to like, receive a mass amount of gold?
like every time someone claims land, their is a 1% chance to find 10k gold!
or add a very rare item that boost stats when fighting.
just so exploring always haves a chance to surprise you.