<?php
/************************************************************************
* Battle script *
* version 2.0 beta *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/> *
* *
* Copyright <makesite.de> 2011 *
************************************************************************/
private $type = self::duel; // type set
private $random_skills = true;
/*
* @function __construct
* @var $type
* @var $random_skills
*
* Initialisierung des gesamten Kampfes und Festlegung des Kampftypes. Als option kann festgelegt werden,
* ob die Angriffs- und Verteidungswerte konstant oder mit einem kleinen Zufallseinluss genereriert werden
* sollen.
*/
function __construct($type=self::duel, $random_skills=true) {
$this->type=$type; // set type of battle
$this->random_skills=$random_skills; // set random manupilation
}
/*
* @function attack
* @var $stack
*
* Diese Funktion berechnet den endgültigen Angriffswert des Angreifers. Alle Waffen, Fähigkeiten
* sowie Rüstungen werden zusammengerechnet und als Zahl zurückgegeben.
*/
function attack(array $stack) {
if($this->random_skills) // check if attack is random
$attack = ($stack[self::warrior_off] * $stack[self::warrior_off_m]) * (rand(1,5)/10);
else
$attack = $stack[self::warrior_off] * $stack[self::warrior_off_m];
return round($attack);
}
/*
* @function defence
* @var $stack
*
* Diese Funktion berechnet den endgültigen Verteidigungswert des Verteidigers. Alle Waffen, Fähigkeiten
* sowie Rüstungen werden zusammengerechnet und als Zahl zurückgegeben.
*/
function defence(array $stack) {
if($this->random_skills) // check if defence is random
$attack = ($stack[self::warrior_def] * $stack[self::warrior_def_m]) * (rand(1,5)/10);
else
$attack = $stack[self::warrior_def] * $stack[self::warrior_def_m];
return round($attack);
}
/*
* @function add_group
* @var $name
* @var $color
*
* Gruppe wird hinzugefügt und es werden nur Krieger nur zu dieser Gruppe zugeordnet, bis eine neue
* erstellt wird.
*/
function add_group($name,$color) {
$this->group_current = count($this->group_set); // set current group
$this->group_num++;
array_push($this->group_set, array("name"=>$name,"color"=>$color,"warriors"=>array())); // add group
}
/*
* @function add_warrior
* @var stack
*
* Krieger wird hinzugefügt. Standardwerte und aktualisierte Werte werden zusammengefügt und
* übermittelt.
*/
/*
* @function start
* @var $random
* @var $random_offender
* @var $max_alive
*
* Kampf wird gestartet. $random bietet entweder abwechselnde Angreifer oder zufällige Angreifer.
* Mit $random_offender wird festgelegt ob der erste Krieger oder ein zufälliger Krieger als Erster
* angreift.
*/
function start($random=false, $random_offender=false, $max_alive=1) {
$this->save_log['type'] = $this->type; // save type of match
$this->save_log['group'] = $this->group_set; // save set of groups
$this->save_log['warriors'] = $this->warrior_set; // save set of groups
switch($this->type) { // check which type
case self::duel: // duel
if($this->warrior_num == 2)
$this->duel($random, $random_offender);
break;
case self::deathmatch: // deathmatch
$this->deathmatch($random,$random_offender,$max_alive);
break;
case self::team_deathmatch: // team_deathmatch
$this->team_deathmatch($random, $random_offender, $max_alive);
break;
$this->warrior_set[($turn==1)?0:1][self::warrior_hp] = $defender[self::warrior_hp]-$damage; // update hp
//////////////////////////////////////////////////////////////////////////////////////////////////////
// SAVE LOG OF FIGHT // save log
//////////////////////////////////////////////////////////////////////////////////////////////////////
if($this->warrior_set[($turn==1)?0:1][self::warrior_hp]<=0) // check whether the defender is dead
{
$this->warrior_num = 1; // warrior count to 1
$this->save_log['log'] =&$log; // save log
$this->save_log['winner']=$offender[self::warrior_name];
}
$this->warrior_set[$rand_def][self::warrior_hp] = $defender[self::warrior_hp]-$damage; // update hp
//////////////////////////////////////////////////////////////////////////////////////////////////////
// SAVE LOG OF FIGHT // save log
//////////////////////////////////////////////////////////////////////////////////////////////////////
$this->warrior_set[$rand_def2][self::warrior_hp] = $defender[self::warrior_hp]-$damage; // update hp
//////////////////////////////////////////////////////////////////////////////////////////////////////
// SAVE LOG OF FIGHT // save log
//////////////////////////////////////////////////////////////////////////////////////////////////////
if($log['log'][$i]['def_hp']<=0) {
echo "<b>".$log['log'][$i]['defender'][self::warrior_name];
echo " ist tot.</b><br>";
}
echo "<br>";
}
break;
}
}
/*
* @function getLog
*
* Gibt den gespeicherten Log der geöffneten Instanz zurück.
*/
function getLog() {
return $this->save_log;
}
}
Tutorial
Schritt 1: Klasse instanzieren
Üblicherweise wird die Klasse zunächst instanziert. Als Parameter werden Kampftyp und ein Boolean für den Zufallseinluss im Angriffs- und Verteidigungswert an den Konstruktor __construct() übergeben.
In dieser Version sind zwei neue Kampftypen dazugekommen. Ich liste also alle drei Möglichkeiten auf:
Duel (Battle::duel)
Ein Kampf zwischen zwei Gegnern. Es gewinnt derjenige, der am Leben bleibt.
Deathmatch (Battle::deathmatch)
Kampf zwischen mehreren Spielern. Kampf endet, sobald die Anzahl der maximal Überlebenden erreicht ist.
Team Deathmatch (Battle::team_deathmatch)
Kampfzwischen mehreren Spielern. Die darin enthaltende Diplomatie Funktion ermöglicht Kämpfe mit mehreren Teams gegeneinander. Auch hier hört der Kampf erst auf, sobald die Anzahl der maximal Überlebenden erreich ist.
Ein sinnvolles Beispiel für die Instanzierung wäre sowas:
PHP
1:
2:
<?php
$battle = new Battle(Battle::team_deathmatch, true);
Deutung:
Der Kampftyp ist Team Deathmatch und die Angriffs und Verteidigungswerte sind nicht konstant, also mit einem kleinen Zufallseinfluss versehen.
Zitat:
TIPP: Empfehlenswert ist es den Zufallseinfluss zu aktivieren, andernfalls könnte ein Kampf sich zu einer endlosschleife bilden, wenn die Gegner gleichstarke Fähigkeiten haben.
Schritt zwei: Krieger bilden
Um neue Krieger zu erstellen, reicht schon ein Array aus. Die klassenbezogenen Konstanten helfen beim Programmieren, die richtige Fähigkeiten zu setzen.
Ein Krieger hat 7 optionale Eigenschaften:
Name (Battle::warrior_name) Standardwert: "Warrior"
Der Name des Kriegers
Gruppe (Battle::warrior_group) (nur im Team Deathmatch Modus benötigt) Standardwert: null
Das Team, in dem sich der Krieger befindet
Lebenspunkte (Battle::warrior_hp) Standardwert: 100
Die Lebenspunkte des Kriegers.
Attacke (Battle::warrior_off) Standardwert: 10
Der normale Angriffswert des Spielers.
Attacke Multiplikator (Battle::warrior_off_m) Standardwert: 1
Der Multiplikator, mit dem der Angriffswert multipliziert wird. Diese Eigenschaft dient hauptsächlich der Balanzierung.
Verteidigung (Battle::warrior_def) Standardwert: 10
Der normale Verteidigungswert des Spielers.
Verteidigung Multiplikator (Battle::warrior_def_m) Standardwert: 1
Der Multiplikator, mit dem der Verteidigungswert multipliziert wird. Diese Eigenschaft dient hauptsächlich der Balanzierung.
Hinweis: Die Angriffs und Verteidigungswerte werden nicht automatisch ausbalanziert. Das bedeutet, dass bei einer schlechter Balanzierung es zu vielen Runden kommen kann.
Zitat:
Tipp: Je höher die Angriffswerte und je kleiner die Lebenspunkte, desto kürzere Logs.
Schritt drei: Krieger hinzufügen und Diplomatie zuordnen
Nachdem die Instanzierung durchgeführt worden ist, und die Krieger erstellt wurden, folgt nun die Einstellung des Kampfes.
Grundsätzlich werden Krieger über die funktion $battle->add_warrior() hinzugefügt. Wenn aber der Modus Team Deathmatch verwendet wird, wie in diesem Fall, müssen die Krieger in Gruppen zugeordnet werden.
Über die Methode ->add_group() erstellt man ein neues Team und alle Krieger, die als nächstes hinzugefügt werden, kommen in dieses Team.
Hinweis: Die Namen der Teams müssen bei den Kriegern und den Gruppen übereinstimmen.
Zitat:
Tipp: Die Farben der Teams können sowohl über die klassenbezogenen Konstanten (Battle::red, Battle::blue, Battle::green, Battle::yellow) als auch eigene Farbcodes (#FFFFFF, #000000, s.o.) festgelegt werden.
Schritt vier: Kampf starten
Als nächstes wird der Kampf über die Methode ->start() durchgeführt.
Als Parameter kann man 3 Variablen übergeben:
Zufällige Angreifer ($random) empfohlen: false
Über diese Variabel lässt es sich festlegen, ob die Krieger nacheinander konstant nach ihrer Reihenfolge sich gegenseitig angreifen oder nach jeder Runde zufällig ein Angreifer ausgewählt wird.
Zufälliger erster Angreifer ($random_offender) empfohlen: false
Hier geht es um den ersten Angreifer in der ersten Runde. Wird der Wert auf false gesetzt, greift der erst hinzugefügte Krieger an. Wenn nicht, wird irgendein Krieger ausgewählt.
Maximal Überlebende ($random) (nur in (Team) Deathmatch) empfohlen: 1
Die Zahl, die angibt, wann der Kampf aufhört, d.h. wie viele am Ende überleben bleiben sollen. Gewöhnlicherweise ist der Wert 1.
Der letzte Schritt ist einfach, wenn man die vorprogrammierte Methode benutzt. Der Log wird als Array gespeichert. Das Array enthält alle Informationen der Runden, Krieger, Gruppen und mehr. Diese Informationen können über ->debug() ausgegeben werden. Das Log ist über ->getLog() erreichbar.
Deine Frage ist ziemlich abstrakt ausgedrückt, bzw. für mich nicht ganz klar eindeutig. Meinst du konkret die Darstellung oder die Menge an Inhalt, die ausgegeben wird?
Ganz klar, wenn du viele Spieler hast, die gegeneinander kämpfen, kannst du nicht ausschließen, dass die Liste lang wird. Es dauert nun einmal, bis alle "sterben". Allerdings gibt es eine Technik, die Runden zu reduzieren - sie heißt Balancing. Im Prinzip ist es vom Namen her schon klar: Du balancierst die Werte der Spieler zu einem guten Verhältnis zu den Lebenspunkten, damit die Spieler schneller sterben.
Kurz gesagt: Am besten erhöhst du einen der beiden Multiplikatoren, wie zum Beispiel der des Angriffwertes (Battle::off_m). Wenn du ihn schon auf 2 oder 2.5 stellst, verdoppeln sich fast alle Angriffswerte.
Balancing ist allgemein sehr schwer, und erfordert Zeit und Geduld. Das ist so ziemlich das wichtigste bei einem Kampf Script.