×
Das Spiel benutzt die
JavaScript-SVG-Bibliothek Raphael und wurde von einem
Tutorium der Uni Augsburg übernommen.
Ich verzichte hier auf den kompletten Quellcode (wer sich dafür interessiert, kann das auf
https://glossar.hs-augsburg.de/HTML-Tutorium:_SVG:_MiniPong nachschauen), und beschränke mich auf meine Modifikationen, insbesondere bezüglich PHP.
MySQL:
Via phpMyAdmin in einer Datenbank die Tabelle "pong" erstellen und die Anzahl der Felder auf 4 festlegen:
- "id" - stellen Sie sicher, dass es auf INT gesetzt ist und markieren Sie es als PRIMARY (setzen Sie es auch auf auto_increment)
- "spieler" - in VARCHAR mit einer Länge von 20
- "punkte" - INT mit einer Länge von 10
- "bild" - VARCHAR mit einer Länge von 100
PHP - HTML (der Hauptdatei):
<!--
Einbindung von Javascript-Dateien welche das Spiel programmieren. raphael-min.js (SVG-Bibliothek Raphael), CONSTANT.js (dazugehörige Konstanten) und main.js (die eigentliche Spiel-Programmierung): -->
<script type="text/javascript" src="js/raphael-min.js"></script>
<script type="text/javascript" src="js/CONSTANT.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<?php
//
Datenbankabfrage der aktuell gespeicherten Bestenliste:
$pdo = new PDO ("mysql:host=localhost; dbname=
Datenbankname;charset=utf8", "
Benutzername", "
Passwort");
$sql = "SELECT * FROM pong ORDER BY punkte DESC";
$rang = 1;
foreach ($pdo->query($sql) as $row) {
if ($rang == 1) {
$highscore = $row['punkte'];
}
$rang++;
}
$topten = $row['punkte'];
$rang = $rang - 1;
?>
<script>
//
Die PHP-Variablen highscore, rang, und topten werden an Javascript übergeben:
var high = <?=$highscore?>;
var topten = <?=$topten?>;
var rang = <?=$rang?>;
</script>
<!--
DIV-Container festlegen welche dann dynamisch über JavaScript befüllt werden: -->
<div id="d_page">
<p id="d_info" align="center">
<!--
Platzhalter für Punktestand -->
<input class="pongbutton" id="d_start_stop" type="button">
</p>
<div id="d_canvas"><!--
Platzhalter für das Spielfeld --></div>
<div align="center">
<!--
Buttons "links" und "rechts" um das Spiel auch mit Maus und Touchscreen spielen zu können: -->
<button id="links" class="pongsteuer" type="submit"> < </button>
<button id="rechts" class="pongsteuer" type="submit"> > </button>
</div>
</div>
<div align="center" id="punktestand">
<script>
document.write("Highscore: " + high + " Punkte; " + rang + ". Platz: " + topten + " Punkte<br><br>");
</script>
<a href="pong.php">Bestenliste anzeigen</a>
</div>
JavaScript - SVG:
//
Die Initial-Funktion, bei der das SVG-Spielfeld gezeichnet wird, wurde durch Event-Listener für Maus- und Touch-Ereignisse ergänzt, da im Original nur mit Tasten gespielt werden kann:
function f_init() {
......
//
Ereignisse mousedown, mouseup, touchstart und touchend sollen auf den Links-Rechts-Buttons überwacht werden:
const elements = document.querySelectorAll(".pongsteuer");
elements.forEach(function (element) {
element.addEventListener("mousedown", o_start_paddle_moving, false);
element.addEventListener("mouseup", o_stop_paddle_moving, true);
element.addEventListener("touchstart", o_start_paddle_moving, false);
element.addEventListener("touchend", o_stop_paddle_moving, true);
});
}
}
//
Entsprechend wurde die Ereignisbearbeitung ergänzt: Reaktion auf Links-(p_event.target.id == "links") und Rechts-Button (p_event.target.id == "rechts"):
function o_start_paddle_moving(p_event) {
if (g_paddle.vx == 0) { //
Reaktion nur wenn sich der Balken noch nicht bewegt
if ((p_event.keyCode == KEY_LEFT) || (p_event.target.id == "links"))
g_paddle.vx = -PADDLE_VX_START;
else if ((p_event.keyCode == KEY_RIGHT) || (p_event.target.id == "rechts"))
g_paddle.vx = +PADDLE_VX_START;
};
}
//
Spielstart wurde ergänzt durch das Befüllen des "punktestand"-div-Containers unterhalb des Spiels:
function o_start_game() {
......
erfolg = "Highscore: " + high + " Punkte; " + rang + ". Platz: " + topten + " Punkte<br><br>";
erfolg += "<a href=\"pong.php\">Ganze Bestenliste anzeigen</a>"
document.getElementById("punktestand").innerHTML = erfolg;
......
}
//
Spielende wurde ergänzt durch das Aendern des "punktestand"-div-Containers, je nach Spielausgang (g_score speicherte die erreichte Punkteanzahl):
function o_stop_game() {
......
if (g_score) {
if (g_score >= high) { //
wenn der Highscore geknackt wurde kann nebst Spielername auch ein Bild hochgeladen werden:
erfolg = "<b>Gratulation!</b> Sie haben den Highscore geknackt. Sie können sich in die Bestenliste eintragen und ein Bild von sich hochladen:<br><br>";
erfolg += "<form action=\"pong.php\" method=\"post\" enctype=\"multipart/form-data\"><input type=\"text\" size=\"14\" placeholder=\"Spielername...\" name=\"nickname\"><br><br>";
erfolg += "Bild hochladen (max. 500KB): <input type=\"file\" name=\"fileToUpload\" id=\"fileToUpload\">";
erfolg += "<input type=\"hidden\" name=\"points\" value=" + g_score + "><br><br><button type=\"submit\" class=\"sbutton\">In Bestenliste eintragen</button></form>";
document.getElementById("punktestand").innerHTML = erfolg;
} else if (g_score > topten) { //
wenn man die Top Ten erreicht hat:
erfolg = "<b>Gratulation!</b> Sie sind in die Top Ten eingedrungen und können sich in die Bestenliste eintragen:<br><br>";
erfolg += "<form action=\"pong.php\" method=\"post\"><input type=\"text\" size=\"14\" placeholder=\"Spielername...\" name=\"nickname\" required>";
erfolg += "<input type=\"hidden\" name=\"points\" value=" + g_score + "><br><br><button type=\"submit\" class=\"sbutton\">In Bestenliste eintragen</button></form>";
document.getElementById("punktestand").innerHTML = erfolg;
} else { //
Topten nicht erreicht:
erfolg = "Highscore: " + high + " Punkte; " + rang + ". Platz: " + topten + " Punkte<br><br>";
erfolg += "<a href=\"pong.php\">Ganze Bestenliste anzeigen</a>"
document.getElementById("punktestand").innerHTML = erfolg;
}
}
......
}
PHP - HTML der Auswertungsdatei (pong.php):
<?php
$datei = "nix";
//
Wenn ein Bild hochgeladen wurde:
if ($_FILES["fileToUpload"]["name"] != "") {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
//
Ueberprüfen ob es sich wirklich um ein Bild handelt:
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "Die Datei ist ein Bild - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "Die Datei ist kein Bild.<br><br>";
$uploadOk = 0;
}
}
//
Ueberprüfen ob das Bild bereits vorhanden ist:
if (file_exists($target_file)) {
echo "Ihr Bild existiert bereits auf dem Server und wurde nicht nochmals hochgeladen.<br><br>";
$uploadOk = 0;
$datei = htmlspecialchars( basename( $_FILES["fileToUpload"]["name"]));
}
//
Dateigrösse des Bildes überprüfen:
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, Ihr Bild ist zu gross und kann deshalb nicht hochgeladen werden.<br><br>";
$uploadOk = 0;
}
//
Nur Bildformate zulassen:
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, nur JPG, JPEG, PNG & GIF Dateien sind erlaubt.<br>Ihr Bild wurde deshalb nicht hochgeladen.<br><br>";
$uploadOk = 0;
}
//
Wenn alles ok ist, das Bild hochladen:
if ($uploadOk != 0) {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
$datei = htmlspecialchars( basename( $_FILES["fileToUpload"]["name"]));
} else {
echo "Sorry, Ihr Bild konnte aus einem unbekannten Grund nicht hochgeladen werden.<br><br>";
}
}
}
//
Spielername und allenfalls Bild in Datenbank hochladen, falls ein Spielername übermittelt wurde:
$pdo = new PDO ("mysql:host=localhost; dbname=Datenbankname;charset=utf8", "Benutzername", "Passwort");
if (isset($_POST["nickname"])) {
$nickname = htmlspecialchars($_POST["nickname"]);
$points = $_POST["points"];
if ($datei != "nix") {
$sql = "INSERT INTO pong (spieler, punkte, bild) VALUES ('".$nickname."', '".$points."', '".$datei."')";
} else {
$sql = "INSERT INTO pong (spieler, punkte) VALUES ('".$nickname."', '".$points."')";
}
$pdo->exec($sql);
}
//
Bestenliste aus Datenbank auslesen und ausgeben:
echo "<span class='subtitel'>Highscore: ";
$rang = 1;
$sql = "SELECT * FROM pong ORDER BY punkte DESC";
foreach ($pdo->query($sql) as $row) {
if ($rang == 1) { //
Zuerst Punkte und Bild des Erstplatzierten anzeigen:
echo $row['punkte']." Punkte</span><br><br>";
if ($row['bild'] != "") { //
Wenn Erstplatzierter ein Bild hochgeladen hatte:
echo "<img width='230' src='uploads/".$row['bild']."' alt='".$row['spieler']."'><br><br>";
} else { //
Wenn Erstplatzierter kein Bild hochlud ein Standardbild anzeigen:
echo "<img width='230' src='img/gold.jpg' alt='".$row['spieler']."'><br>";
echo "<span style='font-size:10px;'><a href='https://de.freepik.com/vektoren-kostenlos/goldene-medaille-design_948389.htm#query=medaille&position=10&from_view=keyword&track=sph'>Bild von bakar015</a> auf Freepik</span><br><br>";
}
if ($row['spieler'] != $nickname) { //
Der aktuelle Spieler hat den Highscore nicht erreicht:
echo "<span>Der Highscore wurde von ".$row['spieler']." erreicht</span><br><br>";
} else { //
Der aktuelle Spieler hat den Highscore übertroffen:
echo "<b>Gratulation! Sie sind der Beste!</b><br><br>";
}
?>
<!--
Die TopTen in einer Tabelle darstellen: -->
<b>Die Top 10:</b><br>
<table cellspacing="10" cellpadding="5">
<tr>
<th>Rang:</th>
<th align="left">Spieler:</th>
<th>Punkte:</th>
</tr>
<?php
}
if ($rang < 11) {
if ($row['spieler'] != $nickname) { //
Aktuell darzustellender Rang entspricht nicht dem aktuellen Spieler
echo "<tr><td>".$rang."</td><td>".$row['spieler']."</td><td align='center'><b>".$row['punkte']."</b></td></tr>";
} else { //
Der aktuell darzustellende Rang wurde vom aktuellen Spieler erreicht (Rang und Name fett):
echo "<tr><td><b>".$rang."</b></td><td><b>".$row['spieler']."</b></td><td align='center'><b>".$row['punkte']."</b></td></tr>";
}
$rang++;
} else { //
Wurde vom aktuellen Spieler die TopTen erreicht, wird der 11.Rang aus der Datenbank gelöscht:
$sql = "DELETE FROM pong WHERE id = ".$row['id'];
$pdo->exec($sql);
}
}
?>
</table>