Mit Imagecopy mehrere Bilder in ein Bild kopieren?

Joe

Erfahrenes Mitglied
Hallo Tutorianer :)

Ich habe am Ende dieses Posts mal das gesamte Skript hingesetzt falls es den einen oder andren intressiert.
Ich denke man wird schnell erkennen um was sich diese Skript dreht.


Zu der Frage:
Kann ich diese Codezeilen
PHP:
	for ($i=0; $i < (count($PosX)); $i++) {
	$Points = array(($PosX[$i] - $UserMapX)*10+$DIVmitteX-5-1,   // Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
					($PosY[$i] - $UserMapY)*10+$DIVmitteY-5-1);  // Berechnung aller Positionen der erfassten Spieler
	$new = imageCreateFromJPEG("img/Usermaps/MAP1_$Mapowner.jpg"); //Original
		if (($PosX[$i]==$UserMapX) AND ($PosY[$i]==$UserMapY)) {
			$grafix = imageCreateFromGIF("img/list12x12-dot18.gif");        // roten Punkt zeichnen für die eigne Position
		}
		else {
		$grafix = imageCreateFromGIF("img/list12x12-dot19.gif");        // schwarzer Punkt für alle andren Spieler
		}
	imageCopyResampled($new, $grafix,
               $Points[0],$Points[1],   /* imagecopy() an berechnete Stelle ($Points) in $new, */
               0, 0,     				/* der zu kopierende Bereich beginnt in $ballgrey bei ( 0, 0) */
               12, 12,12,12);      			/* und ist x Pixel breit und y Pixel hoch */
	imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);
	}

ändern das es die Schleife so nicht benötigt? Vieleicht mit einem Array?
Das Problem ist ich möchte das Ausgangsbild nicht verändern sondern es soll ein neues Bild mit andren Namen enstehen. Das geht aber in so einer Schleife nicht da ja jede Position die dazu kommt das Bild verändert und den selben Namen des Bildes braucht.


Der Sinn warum mir das so wichtig ist, ist weil ich vorher prüfen will ob das Ausgangsbild bereits erstellt wurde so muss es nicht nochmal erstellt werden.
Das so erstellte Ausgangsbild soll aber wie oben gesehen zusätzliche kleinere Bilder bekommen und als neues ganzes Bild abgespeichert werden unter andren Namen. Das Ausgangsbild soll also nicht verändert werden.



Hier mal der Ausschnitt wo das deutlicher wird was ich meine:
PHP:
//// Alle Spieler aus Datenbank lesen und in ein Array speichern.
{
$sql = "SELECT
			Username,
			PosX,
			PosY
		FROM
			User
		WHERE
			PosX >=$NearestKoordsX1 AND PosX < $NearestKoordsX2 AND
			PosY >=$NearestKoordsY1 AND PosY < $NearestKoordsY2";
	$result = $db->query($sql);
	if (!$result) {
		die ('Etwas stimmte mit dem Query nicht: '.$db->error);
	}
	while ($row = $result->fetch_assoc()) {
		$PosX[] = $row["PosX"];
		$PosY[] = $row["PosY"];
		$koordArray[$row['PosX']][$row['PosY']]= $row['Username'];
	}
}

//// Aus der 2000*2000Px Karte den passenden KartenAusschnitt erstellen (Tiling)
	$dir= "img/Map/$SlicepointX";       
	if (file_exists($dir) == false)  { 
		mkdir("img/Map/$SlicepointX", 0700);                           // Verzeichniss erstellen wenn noch nie erstellt
	}
	$file= "img/Map/$SlicepointX/$SlicepointY.jpeg";
	$file2= "img/Usermaps/MAP1_$Mapowner.jpg";
	if (file_exists($file) == false OR file_exists($file2) == false)  {            // Prüfen ob Auschnitt (Tile) schon existiert
		//// Kartenausschnitt ohne Spielerposition
		$size = array(543,432);                        				// Breite und Höhe des Auschnitts
		$point = array($SlicepointX,$SlicepointY);     				// Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
		$image = imagecreatefromjpeg("img/MAP1.jpg") ;  			// Original einlesen
		$new = imagecreatetruecolor($size[0],$size[1]); 			// Neues Bild leer erstellen
		imagecopyresampled($new, $image, 0,0, $point[0],$point[1],
					$size[0],$size[1], $size[0],$size[1]);  // Ausschnitt rüberkopieren
		imageJPEG($new,"img/Map/$SlicepointX/$SlicepointY.jpeg",100);           	// Bild speichern
		imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);           	// Bild speichern
	}

//// Überprüfen ob sich die Positionen in der Datenbank geändert haben oder nicht
if (isset($_SESSION['Positionen']) AND $koordArray != $_SESSION['Positionen'] OR !isset($_SESSION['Positionen'])) {
	if (isset($_SESSION['Positionen'])) {
		unset($_SESSION['Positionen']);                                   
		$_SESSION['Positionen'] = $koordArray; 
	}
	else {
		$_SESSION['Positionen'] = $koordArray;
	}
        //// Positionen als Bilder in die Karte kopieren  ////
	for ($i=0; $i < (count($PosX)); $i++) {
	$Points = array(($PosX[$i] - $UserMapX)*10+$DIVmitteX-5-1,   // Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
					($PosY[$i] - $UserMapY)*10+$DIVmitteY-5-1);  // Berechnung aller Positionen der erfassten Spieler
	$new = imageCreateFromJPEG("img/Usermaps/MAP1_$Mapowner.jpg"); //Original
		if (($PosX[$i]==$UserMapX) AND ($PosY[$i]==$UserMapY)) {
			$grafix = imageCreateFromGIF("img/list12x12-dot18.gif");        // roten Punkt zeichnen für die eigne Position
		}
		else {
		$grafix = imageCreateFromGIF("img/list12x12-dot19.gif");        // schwarzer Punkt für alle andren Spieler
		}
	imageCopyResampled($new, $grafix,
               $Points[0],$Points[1],   /* imagecopy() an berechnete Stelle ($Points) in $new, */
               0, 0,     				/* der zu kopierende Bereich beginnt in $ballgrey bei ( 0, 0) */
               12, 12,12,12);      			/* und ist x Pixel breit und y Pixel hoch */
	imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);
	}
}

Es soll praktisch nur dann Rechenarbeit produzieren wenn es noch nicht erstellt wurde oder sich was geändert hat.

Ich bin sehr dankbar für eure Anregungen und die Zeit fürs lesen oder Antworten.
Hier steh ich auf dem Schlauch und allein krieg ich da nicht hin jedenfalls nicht innerhalb einiger Tage oder Wochen.



Zum Schluss nochmal das ganze Skript wenn es wer braucht oder wem intressiert. Es funktioniert soweit tadelos ist aber alles auf mein Div und dessen Grösse zugeschnitten.


PHP:
	<div id="content-pic">
	</div>
<div id=content>
<div id=mappic>
<?php
error_reporting(E_ALL);

//// Variablen und Grundwerte zur Karten und Positionsberechnung
$SlicepointX = $UserMapX*10-277;  // Auschnittspunkt X
$SlicepointY = $UserMapY*10-220;    // Auschnittspunkt Y
$DIVmitteX=271.5;
$DIVmitteY=216;                     // Mitte des Divs/ angezeigter Bereich der Karte
$NearestKoordsX1 = $UserMapX-28;
$NearestKoordsX2 = $UserMapX+28;
$NearestKoordsY1 = $UserMapY-22;    // Erfassung aller Spieler des Kartenausschnittes 
$NearestKoordsY2 = $UserMapY+22;
$Mapowner = $Username;
//// Abweichende Berechnung bei Kartenrandnähe ansonsten wird Spieler immer auf der Mitte angezeigt
if ($UserMapX<28) {                 
	$SlicepointX = 0;              
	$NearestKoordsX1 = 0;
	$NearestKoordsX2 = 56;
	$DIVmitteX=276-((28-$UserMapX)*10);
}
if ($UserMapX>172) {
	$SlicepointX = 1457;
	$NearestKoordsX2 = 201;
	$NearestKoordsX1 = 145;
	$DIVmitteX=257+(($UserMapX-172)*10);	
}
if ($UserMapY<22) {
	$SlicepointY = 0;
	$NearestKoordsY1 = 0;
	$NearestKoordsY2 = 44;
	$DIVmitteY=216-((22-$UserMapY)*10);
}
if ($UserMapY>178) {
	$SlicepointY = 1568;
	$NearestKoordsY2 = 201;
	$NearestKoordsY1 = 156;
	$DIVmitteY=206+(($UserMapY-178)*10);
}


//// Alle Spieler aus Datenbank lesen und in ein Array speichern.
{
$sql = "SELECT
			Username,
			PosX,
			PosY
		FROM
			User
		WHERE
			PosX >=$NearestKoordsX1 AND PosX < $NearestKoordsX2 AND
			PosY >=$NearestKoordsY1 AND PosY < $NearestKoordsY2";
	$result = $db->query($sql);
	if (!$result) {
		die ('Etwas stimmte mit dem Query nicht: '.$db->error);
	}
	while ($row = $result->fetch_assoc()) {
		$PosX[] = $row["PosX"];
		$PosY[] = $row["PosY"];
		$koordArray[$row['PosX']][$row['PosY']]= $row['Username'];
	}
}


	$dir= "img/Map/$SlicepointX";
	if (file_exists($dir) == false)  { 
		mkdir("img/Map/$SlicepointX", 0700);
	}
	$file= "img/Map/$SlicepointX/$SlicepointY.jpeg";
	$file2= "img/Usermaps/MAP1_$Mapowner.jpg";
	if (file_exists($file) == false OR file_exists($file2) == false)  {
		//// Kartenausschnitt ohne Spielerposition
		$size = array(543,432);                        				// Breite und Höhe des Auschnitts
		$point = array($SlicepointX,$SlicepointY);     				// Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
		$image = imagecreatefromjpeg("img/MAP1.jpg") ;  			// Original einlesen
		$new = imagecreatetruecolor($size[0],$size[1]); 			// Neues Bild leer erstellen
		imagecopyresampled($new, $image, 0,0, $point[0],$point[1],
					$size[0],$size[1], $size[0],$size[1]);  // Ausschnitt rüberkopieren
		imageJPEG($new,"img/Map/$SlicepointX/$SlicepointY.jpeg",100);           	// Bild speichern
		imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);           	// Bild speichern
	}

if (isset($_SESSION['Positionen']) AND $koordArray != $_SESSION['Positionen'] OR !isset($_SESSION['Positionen'])) {
	if (isset($_SESSION['Positionen'])) {
		unset($_SESSION['Positionen']);
		$_SESSION['Positionen'] = $koordArray;
	}
	else {
		$_SESSION['Positionen'] = $koordArray;
	}
	for ($i=0; $i < (count($PosX)); $i++) {
	$Points = array(($PosX[$i] - $UserMapX)*10+$DIVmitteX-5-1,   // Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
					($PosY[$i] - $UserMapY)*10+$DIVmitteY-5-1);  // Berechnung aller Positionen der erfassten Spieler
	$new = imageCreateFromJPEG("img/Usermaps/MAP1_$Mapowner.jpg"); //Original
		if (($PosX[$i]==$UserMapX) AND ($PosY[$i]==$UserMapY)) {
			$grafix = imageCreateFromGIF("img/list12x12-dot18.gif");        // roten Punkt zeichnen für die eigne Position
		}
		else {
		$grafix = imageCreateFromGIF("img/list12x12-dot19.gif");        // schwarzer Punkt für alle andren Spieler
		}
	imageCopyResampled($new, $grafix,
               $Points[0],$Points[1],   /* imagecopy() an berechnete Stelle ($Points) in $new, */
               0, 0,     				/* der zu kopierende Bereich beginnt in $ballgrey bei ( 0, 0) */
               12, 12,12,12);      			/* und ist x Pixel breit und y Pixel hoch */
	imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);
	}
}

//// Anzeige aller Positionen
echo "<map name=\"map\">";			//HTMLCode Anfangstag soll ein "Mouseover" zum anzeigen der Namen und Positionen gennerieren.
for ($PlayerPosX=$NearestKoordsX1; $PlayerPosX<$NearestKoordsX2; $PlayerPosX++) {
	for ($PlayerPosY=$NearestKoordsY1; $PlayerPosY<$NearestKoordsY2; $PlayerPosY++) {
		if (isset($koordArray[$PlayerPosX][$PlayerPosY]) && $koordArray[$PlayerPosX][$PlayerPosY] != "") {
			$Name=$koordArray[$PlayerPosX][$PlayerPosY];
			$Titlepos = array(($PlayerPosX - $UserMapX)*10+$DIVmitteX-6,
							($PlayerPosY - $UserMapY)*10+$DIVmitteY-6,
							($PlayerPosX - $UserMapX)*10+$DIVmitteX+4,				//Array für Title(und oder Link)-generirung Positionen
							($PlayerPosY - $UserMapY)*10+$DIVmitteY+4);
			echo "<area shape=\"rect\" coords=\"$Titlepos[0],$Titlepos[1],$Titlepos[2],$Titlepos[3]\" 
				href=\"main.php?section=erkunden\" title=\"$Name: $PlayerPosX,$PlayerPosY\">\n";   //HTMLCode Position und Titel
		}
		else {
		 $Titlepos = array(($PlayerPosX - $UserMapX)*10+$DIVmitteX-6,
						   ($PlayerPosY - $UserMapY)*10+$DIVmitteY-6,
						   ($PlayerPosX - $UserMapX)*10+$DIVmitteX+4,				//Array für Title(und oder Link)-generirung Positionen
						   ($PlayerPosY - $UserMapY)*10+$DIVmitteY+4);
		echo "<area shape=\"rect\" coords=\"$Titlepos[0],$Titlepos[1],$Titlepos[2],$Titlepos[3]\" 
			href=\"main.php?section=erkunden\" title=\"$PlayerPosX,$PlayerPosY\">\n";		//HTMLCode Position und Titel
		}
	}
}
echo "</map>"; 															//HTMLCode schliessendes Maptag.. erst hier ist die Maptabelle vollständig.
echo "<img src='img/Usermaps/MAP1_$Mapowner.jpg' width='543' height='432' border='0' alt='Karte' usemap='#map'>"; //zeigt Karte mit Positionen und Mouseover

/**
 * Formel für Positionsanzeige aller Spieler des Kartenausschnittes:
 * ($PosXOtherPlayer - $UserMapX) * 10 (Feld =10*10Pixel bei Feldgrösse 200*200 (Karte ist 2000*2000 Pixel) + 
 * $DIVmitteX(DIV/BildMittelPunktberechnung) -5 Mitte des Feldes(Feld 10*10) -1 Rest des ball.gif (teils transparent deswegen keine Überlagerung)
 * ($PosYOtherPlayer - $UserMapY) * 10 (Feld =10*10Pixel bei Feldgrösse 200*200 (Karte ist 2000*2000 Pixel) + 
 * $DIVmitteX(DIV/BildMittelPunktberechnung) -5 Mitte des Feldes -4 Mitte des ball.gif (teils transparent deswegen keine Überlagerung)
 * $Points = array(($PosXOtherPlayer - $UserMapX)*10+$DIVmitteX-5-1,
					($PosYOtherPlayer - $UserMapY)*10+$DIVmitteY-5-1); */
?>
</div>
</div>
	<div id="upper-pic">
	</div>
	<div id="uppercontent">
	<h2><?php

	echo "Benötigte Dauer: ".(microtime(true)-$start)." Sekunden";
			//unset($_SESSION['Positionen']);
			//echo "unset ";
	?></h2>
	</div>
 
In der folgenden Zeile erstellst du das Bild mit Namen.
PHP:
 imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);

Du kannst vor dem Bild erstellen auf dem Serfer mittels is_file("img/Usermaps/MAP1_$Mapowner.jpg") prüfen ob die Datei vorhanden ist. Wenn nicht, dann lass sie erstellen.
 
  • Gefällt mir
Reaktionen: Joe
Vielen Dank yaslaw,

Deine kurzer Post hat mich erst stutzig gemacht weil ich dachte genau das habe ich doch schon gemacht. Aber nachdem ichs paarmal gelesen habe merkte ich den logischen Grund dahinter :)
Das ist genau der (logische) Fehler am Skript gewesen. Und hat mich auf die richtige Idee gebracht.
Ist fast das selbe bloss etwas anders als Is_file.

Stellt sich nur noch die Frage ob das ein Server aushält wenn viele Bewegungen gleichzeitig passieren. Ein Kartenausschnitt fast nämlich ca 55*44 mögliche Positionen .. Das sind ne Menge Bilder(Positionen) zu kopieren. Ne andre Möglichkeit ist mir noch nicht eingefallen. Divs bekomme ich nicht hin und Tabellen brauchen zu lange.

PHP:
//// Alle Spieler aus Datenbank lesen und in ein Array speichern.
{
$sql = "SELECT
			Username,
			PosX,
			PosY
		FROM
			User
		WHERE
			PosX >=$NearestKoordsX1 AND PosX < $NearestKoordsX2 AND
			PosY >=$NearestKoordsY1 AND PosY < $NearestKoordsY2";
	$result = $db->query($sql);
	if (!$result) {
		die ('Etwas stimmte mit dem Query nicht: '.$db->error);
	}
	while ($row = $result->fetch_assoc()) {
		$PosX[] = $row["PosX"];
		$PosY[] = $row["PosY"];
		$koordArray[$row['PosX']][$row['PosY']]= $row['Username'];
	}
}

//// Aus der 2000*2000Px Karte den passenden KartenAusschnitt erstellen (Tiling) 
$dir= "img/Map/$SlicepointX";
if (file_exists($dir) == false)  { 
	mkdir("img/Map/$SlicepointX", 0700);						// Verzeichniss erstellen wenn noch nie erstellt 
}
$file= "img/Map/$SlicepointX/$SlicepointY.jpeg";
if (file_exists($file) == false)  {            					// Prüfen ob Auschnitt (Tile) schon existiert
	//// Kartenausschnitt ohne Spielerposition
	$size = array(543,432);                        				// Breite und Höhe des Auschnitts
	$point = array($SlicepointX,$SlicepointY);     				// Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
	$image = imagecreatefromjpeg("img/MAP1.jpg") ;  			// Original einlesen
	$new = imagecreatetruecolor($size[0],$size[1]); 			// Neues Bild leer erstellen
	imagecopyresampled($new, $image, 0,0, $point[0],$point[1],
					$size[0],$size[1], $size[0],$size[1]);  	// Ausschnitt rüberkopieren
	imageJPEG($new,"img/Map/$SlicepointX/$SlicepointY.jpeg",100);         // Bild speichern
}

//// Überprüfen ob sich die Positionen in der Datenbank geändert haben oder das erste mal abgerufen
if (isset($_SESSION['Positionen']) AND $koordArray != $_SESSION['Positionen'] OR !isset($_SESSION['Positionen'])) {
	if (isset($_SESSION['Positionen'])) {
		unset($_SESSION['Positionen']);
		$_SESSION['Positionen'] = $koordArray;                                                // Array und Kartenausschnitt neu speichern wenn
		copy("img/Map/$SlicepointX/$SlicepointY.jpeg","img/Usermaps/MAP1_$Mapowner.jpg");      //  Positionen oder Spieler sich verändert haben
	}
	else {
		$_SESSION['Positionen'] = $koordArray;                                                  // Das Positions und SpielerArray in die Session schreiben
		copy("img/Map/$SlicepointX/$SlicepointY.jpeg","img/Usermaps/MAP1_$Mapowner.jpg");		//Kartenauschnitt kopieren und das erste mal erstellen 
	}
	
	//// Positionen als Bilder in die Karte kopieren
	for ($i=0; $i < (count($PosX)); $i++) {
	$Points = array(($PosX[$i] - $UserMapX)*10+$DIVmitteX-5-1,   // Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
					($PosY[$i] - $UserMapY)*10+$DIVmitteY-5-1);  // Berechnung aller Positionen der erfassten Spieler
	$new = imageCreateFromJPEG("img/Usermaps/MAP1_$Mapowner.jpg"); //Original
		if (($PosX[$i]==$UserMapX) AND ($PosY[$i]==$UserMapY)) {
			$grafix = imageCreateFromGIF("img/list12x12-dot18.gif");        // roten Punkt zeichnen für die eigne Position
		}
		else {
		$grafix = imageCreateFromGIF("img/list12x12-dot19.gif");        // schwarzer Punkt für alle andren Spieler
		}
	imageCopyResampled($new, $grafix,
               $Points[0],$Points[1],   /* imagecopy() an berechnete Stelle ($Points) in $new, */
               0, 0,     				/* der zu kopierende Bereich beginnt in $ballgrey bei ( 0, 0) */
               12, 12,12,12);      			/* und ist x Pixel breit und y Pixel hoch */
	imageJPEG($new,"img/Usermaps/MAP1_$Mapowner.jpg",100);
	}
}
 
Divs bekomme ich nicht hin und Tabellen brauchen zu lange.

Versuche doch lieber, es mit <div>'s hinzubekommen, so schwer ist das nicht :)

wenn du bei jeder Änderung neue Bilder speicherst, müssen diese auch jedes mal vom Clienten neu geladen werden, was die Sache auch nicht schneller macht....von der Serverlast mal abgesehen. Wenn du dann noch mit CSS-Sprites arbeitest, hättest du die Anzahl der Requests auch auf ein Minimum gesenkt :)

Stell dir mal vor, ein Browsergame, wo im Sekundentakt tausende User hunderte neue Bilder in nicht unbeträchtlicher Grösse anfordern, da fliegt dir der Server sehr schnell um die Ohren :eek:
 
Ieeh Hexenwerk :D

Also wenn ich diese Technik richtig verstehe wird mit Hilfe des Listenelements <ul> und den Hoverbefehl das entsprechende SpritePic aus einer grossen vieler SpritesPics beinhaltenden Grafik geladen/angezeigt?

Ok Soweit kann ich in etwa folgen (glaube ich).
Aber wie würde ich das bei mir nun umsetzen? 55*44 Divs sind 2420 Divs die ich sagen wir mal als "Maske" im CStylesheet von Hand eintragen müsste.

Und dann? Mit PHP eine Schleife machen in der die Koordinaten abgefragt werden nach platzierten Positionen um CSS Sprite dort einzubinden. Also für die eigne Position ein roter Punkt für andre ein schwarzer.

Meintest du das so Sven?
:rolleyes: Wer sich mit solchen Projekten beschäftigt muss wohl öfter vieles umschreiben.
 
So in der Richtung hatte ich das gedacht :)

Zum Erzeugen der div's musst du auch nicht unbedingt eine Schleife nehmen, du könntest bspw. einen fertigen XML-Codeschnipsel nehmen.

Da brauchst du dann nicht 2420 Schleifendurchläufe für jede Koordinate, sondern nur soviel, wie Einträge in der DB sind...auf die einzelnen Elemente kannst du mittels DOM-Methoden auch im nachhinein bequem zugreifen und sie mit den jeweiligen Attributen versehen.

Ob du nun wirklich 2420 divs nimmst, das solltest du generell noch überdenken....das wird so oder so zumindest ein recht grosser Haufen HTML-Code.
Ich hab in Sachen BG nur Erfahrungsberichte von "die stämme" parat, und dort hatte man eine Übersicht von ca. 12*12....sicher nicht primär aus dem Grund, weniger Übersicht zu haben.

Ein lauffähiges Beispiel dessen, was ich meine:
Code:
<?php

//das Grid, könnte hardcodiert aus einer externen Datei kommen
//spart das erstellen per Schleife
$grid='<div id="grid">
        <div><a></a><a></a><a></a><a></a><a></a></div>
        <div><a></a><a></a><a></a><a></a><a></a></div>
        <div><a></a><a></a><a></a><a></a><a></a></div>
        <div><a></a><a></a><a></a><a></a><a></a></div>
        <div><a></a><a></a><a></a><a></a><a></a></div>
       </div>
      ';



//Simulation für DB
$db=array(
  array('name'=>'Uschi',  'x'=>0,'y'=>4),
  array('name'=>'Fritz',  'x'=>1,'y'=>3),
  array('name'=>'Max',    'x'=>3,'y'=>2),
  array('name'=>'Fritz',  'x'=>4,'y'=>1),
  array('name'=>'Knut',   'x'=>3,'y'=>3),
  array('name'=>'Fritz',  'x'=>4,'y'=>0),
  array('name'=>'Moritz', 'x'=>2,'y'=>2),
  array('name'=>'Uschi',  'x'=>2,'y'=>1),
);

//Name des aktuellen Spielers
$me='Fritz';

//Einfügen der Daten ins XML

$doc=new DomDocument();
$doc->loadXML($grid);
foreach($db as $item)
{
  $node=$doc->
          documentElement->
            getElementsByTagName('div')->item($item['x'])->
              getElementsByTagName('a')->item($item['y']);
  
  $node->setAttribute('title',
                      ($item['name']==$me)
                        ?'hier wohne ich '
                        :'hier wohnt '.$item['name']);
  $node->setAttribute('href',
                      'place.php?x='.$item['x'].'&y='.$item['y']);
  
  $node->setAttribute('class',
                      ($item['name']==$me)
                        ?'me'
                        :'enemy');
  
}

?>


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; 
                                charset=ISO-8859-1"   />
<meta name="author"             content="doktormolle" />
<meta name="date"               content="2010-06-07" />
<title>Test</title>
<script type="text/javascript">
<!--
//-->
</script>
<style type="text/css">
<!--
/*CSS fürs Grid*/
#grid{
  width:110px;
  height:110px;
}
#grid div{
  width:110px;
  height:20px;
}
#grid div a{
  background:green;
  display:block;
  width:20px;
  height:20px;
  float:left;
  border:1px solid #000;
}

/*CSS zur markierung der Felder, hier könnte man statt Farben Sprites einsetzen*/
#grid a.me{
  background:#fff;
}
#grid a.enemy{
  background:red;
}
-->
</style>
</head>
<body>
<?php
//Ausgabe des Grids
echo $doc->saveHTML();
?>
</body>
</html>
 
  • Gefällt mir
Reaktionen: Joe
Danke für das Super Beispiel das sagt eigentlich alles wie sowas funktioniert.
Nachdem ich mich nun auch noch über DOM-Methden informiert habe verstehe ich auch was da steht :D

Hätte sonst versucht es (die DIVS) umständlich und deutlich leistungsauffwändiger mit PHP zu realisieren. Ich befürchte sogar es wäre kaum lösbar.
Ist ne elegante und leistungsfähige Lösung die DOM-Methode.

Ob du nun wirklich 2420 divs nimmst, das solltest du generell noch überdenken....das wird so oder so zumindest ein recht grosser Haufen HTML-Code.
Ich hab in Sachen BG nur Erfahrungsberichte von "die stämme" parat, und dort hatte man eine Übersicht von ca. 12*12....sicher nicht primär aus dem Grund, weniger Übersicht zu haben.

Ja das habe ich auch bereits realisiert. Allerdings bin ich kein Grafiker so das das normale Tiling für BG-Maps bei mir aussehen wüde wie von nen 5 jährigen in Strichmänchen Manier :( .. vorgefertigt wirds wohl kaum was geben in einen Endzeitszenariosetting (Tileset).
Tja und die Karte zu vergrössern die ich mit L3DT erstellt habe ist auch nicht möglich da (glaube ich) die maximale Grösse bei 4000*4000Px liegt.
Nur wenn ich die eigentliche Map grösser machen würde könnte ich kleinere Abschnitte mit entsprechend weniger Positionen coden.
Also will sagen programmiert bekomme ichs (mit ab und zu wirklich sehr guter Hilfe) aber gezeichnet nit :)
Weitere Leute möchte ich erst dann involvieren wenn ich etwas vorzeigen kann, anders würde das nur Probleme bringen.


Back to Post:
Ich werd dein vollständiges Beispiel erstmal bei mir implementieren so wies grad ist mit den krass vielen Divs. Das ja dank dem dem grid aus deinem Bsp. nicht unmenschlich schwer ist. Und wenns mal etwas weiter und klar ersichtlich inklusive funktionell ist, werde ich ein paar entsprechend fähige Leute mit ins Projekt nehmen. So hat die Grafik vorerst den letzten Stellenwert. Das Grundgerüst ist wichtiger.
 
Hi,

Der Code sieht nun deutlich besser aus und wesentlich performanter.
Nur gelingt es mir nicht dem Grid einen Anfangswert zuzuweissen. Ich habe ja nur einen bestimmten Ausschnitt und DB-Array.
Hier mal mein Versuch:
PHP:
$node=$doc->
	documentElement->
		setAttribute('div','$NearestKoordsX1')->
			setAttribute('a','$NearestKoordsY1');

Das gesamte Script sieht nun so aus:
PHP:
	<div id="content-pic">
	</div>
<div id=content>
<div id=mappic>
<?php
error_reporting(E_ALL);

//// Variablen und Grundwerte zur Karten und Positionsberechnung
$SlicepointX = $UserMapX*10-277;  // Auschnittspunkt X
$SlicepointY = $UserMapY*10-220;    // Auschnittspunkt Y
$NearestKoordsX1 = $UserMapX-22;
$NearestKoordsX2 = $UserMapX+22;
$NearestKoordsY1 = $UserMapY-28;    // Erfassung aller Spieler des Kartenausschnittes 
$NearestKoordsY2 = $UserMapY+28;

//// Abweichende Berechnung bei Kartenrandnähe ansonsten wird Spieler immer auf der Mitte angezeigt
if ($UserMapX<22) {                 
	$SlicepointX = 0;              
	$NearestKoordsX1 = 0;
	$NearestKoordsX2 = 44;
}
if ($UserMapX>178) {
	$SlicepointX = 1457;
	$NearestKoordsX2 = 201;
	$NearestKoordsX1 = 156;	
}
if ($UserMapY<28) {
	$SlicepointY = 0;
	$NearestKoordsY1 = 0;
	$NearestKoordsY2 = 56;
}
if ($UserMapY>172) {
	$SlicepointY = 1568;
	$NearestKoordsY2 = 201;
	$NearestKoordsY1 = 145;
}

//// Alle Spieler aus Datenbank lesen und in ein Array speichern.
{
$sql = "SELECT
			Username,
			PosX,
			PosY
		FROM
			User
		WHERE
			PosX >=$NearestKoordsX1 AND PosX < $NearestKoordsX2 AND
			PosY >=$NearestKoordsY1 AND PosY < $NearestKoordsY2";
	$result = $db->query($sql);
	if (!$result) {
		die ('Etwas stimmte mit dem Query nicht: '.$db->error);
	}
}

//// Aus der 2000*2000Px Karte den passenden KartenAusschnitt erstellen (Tiling) 
$dir= "img/Map/$SlicepointX";
if (file_exists($dir) == false)  { 
	mkdir("img/Map/$SlicepointX", 0700);						// Verzeichniss erstellen wenn noch nie erstellt 
}
$file= "img/Map/$SlicepointX/$SlicepointY.jpeg";
if (file_exists($file) == false)  {            					// Prüfen ob Auschnitt (Tile) schon existiert
	//// Kartenausschnitt ohne Spielerposition
	$size = array(543,432);                        				// Breite und Höhe des Auschnitts
	$point = array($SlicepointX,$SlicepointY);     				// Koordinaten, ab wo kopiert werden soll (erst X, dann Y).
	$image = imagecreatefromjpeg("img/MAP1.jpg") ;  			// Original einlesen
	$new = imagecreatetruecolor($size[0],$size[1]); 			// Neues Bild leer erstellen
	imagecopyresampled($new, $image, 0,0, $point[0],$point[1],
					$size[0],$size[1], $size[0],$size[1]);  	// Ausschnitt rüberkopieren
	imageJPEG($new,"img/Map/$SlicepointX/$SlicepointY.jpeg",100);         // Bild speichern
}

//das Grid, hardcodiert aus einer externen Datei
include 'grid.tpl';

//Einfügen der Daten ins XML
$Mapowner = $Username;
$doc=new DomDocument();
$doc->loadXML($grid);
$node=$doc->
	documentElement->
		setAttribute('div','$NearestKoordsX1')->
			setAttribute('a','$NearestKoordsY1');
foreach($result as $item)
{
  $node=$doc->
          documentElement->
            getElementsByTagName('div')->item($item['PosX'])->
              getElementsByTagName('a')->item($item['PosY']);
  $node->setAttribute('title',
                      ($item['Username']==$Mapowner)
                        ?''.$item['Username']
                        :''.$item['Username']);
  $node->setAttribute('href',
                      'main.php?section=erkunden');
  $node->setAttribute('class',
                      ($item['Username']==$Username)
                        ?'me'
                        :'enemy'); 
}
?>

<style type="text/css">

/*CSS fürs Grid*/
#grid{
  background: url(img/Map/<? echo "$SlicepointX/$SlicepointY"; ?>.jpeg) no-repeat;
  width:543px;
  height:432px;
}
#grid div{
  width:543px;
  height:10px;
}
#grid div a{

  display:block;
  width:10px;
  height:10px;
  float:left;
}

/*CSS zur markierung der Felder, hier könnte man statt Farben Sprites einsetzen*/
#grid a.me{
  background: url(img/list12x12-dot18.gif) no-repeat;
}
#grid a.enemy{
  background: url(img/list12x12-dot19.gif) no-repeat;
}
</style>

<?php
//Ausgabe des Grids
echo $doc->saveHTML();
?>

</div>
</div>
	<div id="upper-pic">
	</div>
	<div id="uppercontent">
	<h2><?php
	echo "Benötigte Dauer: ".(microtime(true)-$start)." Sekunden.<br>";
	echo "Die Map wird zur Zeit optimiert.";
			//unset($_SESSION['Positionen']);
			//echo "unset ";
	?></h2>
	</div>

Und irgendwie ist mir schleierhaft wieso ich den CSS Code nicht einfach auschneiden und ins bestehende externe Stylesheet einfügen kann. Ich mein müsste es nicht so das Grid CSS formatiert zeigen?

Weiss nicht ob ich froh sein soll oder nicht, euch diesmal mit diesen einfachen Fragen zu behelligen.. Ich lerne mit jedem mal dazu.
 
Du definierst hier ja die Eckpunkte:
Code:
$NearestKoordsX1 = $UserMapX-22;
$NearestKoordsX2 = $UserMapX+22;
$NearestKoordsY1 = $UserMapY-28;    // Erfassung aller Spieler des Kartenausschnittes 
$NearestKoordsY2 = $UserMapY+28;

....wobei die fett markierten die obere linke Ecke bestimmen.

Diese ist später vonnöten beim Zugriff auf die Knoten des XML-Schnipsels:

Code:
$node=$doc->
          documentElement->
            getElementsByTagName('div')->item($item['PosX'])->
              getElementsByTagName('a')->item($item['PosY']);

Bei dem XML-Schnipsel wird aber bei der oberen Ecke von x=0 und y=0 ausgegangen.

Du musst diese Differenz also berücksichtigen, um den korrekten Knoten zu Finden:
Code:
$node=$doc->
          documentElement->
            getElementsByTagName('div')->item($item['PosX']-$NearestKoordsX1)->
              getElementsByTagName('a')->item($item['PosY']-$NearestKoordsY1);
 
  • Gefällt mir
Reaktionen: Joe
:) einfache Subtraktion .. und ich habe ewig rumüberlegt und Referenzen gelesen.

Noch eine kleine Korrektur (siehe meinen letzten Code): die Datenbankvariable muss natürlich noch extrahiert werden in ein Array.
PHP:
{
$sql = "SELECT
			PosX,
			PosY,
			Username
		FROM
			User
		WHERE
			PosX >=$NearestKoordsX1 AND PosX < $NearestKoordsX2 AND
			PosY >=$NearestKoordsY1 AND PosY < $NearestKoordsY2";
	$result = $db->query($sql);
	if (!$result) {
		die ('Etwas stimmte mit dem Query nicht: '.$db->error);
	}
	while ($row = $result->fetch_assoc()) {
	$data[] = $row;
	}	 
}

//das Grid, hardcodiert aus einer externen Datei
include 'grid.tpl';

//Einfügen der Daten ins XML
$doc=new DomDocument();
$doc->loadXML($grid);
foreach($data as $item)
{
  $node=$doc->
          documentElement->
            getElementsByTagName('div')->item($item['PosX']-$NearestKoordsX1)->
              getElementsByTagName('a')->item($item['PosY']-$NearestKoordsY1);
  $node->setAttribute('title',
                      ($item['Username']==$Username)
                        ?''.$item['Username'].': '.$item['PosX'].'/'.$item['PosY']
                        :''.$item['Username'].': '.$item['PosX'].'/'.$item['PosY']);
  $node->setAttribute('href',
                      'main.php?section=erkunden');
  $node->setAttribute('class',
                      ($item['Username']==$Username)
                        ?'me'
                        :'enemy');

Stellt sich mir als nächstes Problem wie ich es schaffe dem Dokument grid und deren divs per javascript und onMouseover die Positionen zu geben. Sinn: man soll diese Stelle dann erkunden können das heisst ein Klick auf eine Position schickt den User auf die Seite erkunden.php auf der dann abgefragt wird ob man dort erkunden will usw.

Mit Javascript hatte ich bisher noch garnix am Hut aber schaun wir mal :)
 
Zuletzt bearbeitet:
Zurück