Should I use multiple classes for game?
I'm considering making a text-based RPG-type program in PHP as both a holiday project and a chance to learn more about PHP and OOP. (Maybe not the best choice in language, I know, but I didn't want to have to learn another language from scratch at the same time as OOP.)
Anyway, I'm just beginning the design process and thinking about '开发者_StackOverflow社区monsters'. Each monster type (ya know, orc, goblin, rat, etc) will have its own stats, skills and what not. At first I though I could just have a single monster class and set the properties when I instantiate the object. But then I figured that might be a little inefficient, so I'm considering having a class for each type of monster.
Is this the best way to approach the problem, considering that the methods in each class will likely be the same? Is there a better way of doing things that I don't yet know about?
Any help is appreciated.
You could create an abstract class, say Monster, and then extend that class for each of the different types of monsters. So
<?php
abstract class Monster {
private $health;
public function attack() {
//do stuff
}
}
class Orc extends Monster {
private $damage_bonus;
}
?>
edit Orc would extend Monster and then inherit the attribute $health and the function attack().
What you should do is get some real organization into the game.
I've never built a PHP Game before but i have a pretty good idea how the structure should be.
A Entity / Monster should be built up of several class defining its characteristics
Here's an small example of the top of my head:
abstract class NonHuman implements Strengh,Weapons,Vehicles
{
var $strength;
}
abstract class Vermin implements Strengh,Chemicals
{
var $strength = 20;
var $poisonous = true;
}
abstract class Humanoid implements Strengh,Weapons,Vehicles,Arms,Legs
{
}
Basic layout for the abstract classes are like so:
abstract class <BeingType> implements < Characteristics , Weapons , Etc>
{
// Depending on < Characteristics , Weapons , Etc> you should
// Build the methods here so that theres less work in the long run.
}
Then once you have your base being types you can do things like
class Rat extends Vermin
{
public function __construct($name,$strength = 50)
{
$this->strength = $strength;
}
//Any new methods here would be specific to this Being / Rat.
}
$Robert = new Rat('Robert',80);
$Andrew = new Rat('Andrew',22);
if($Robert->strength > 50)
{
$Robert->Kick($Andrew,'left',20); //20 mph lol
if($Andrew->IsAlive())
{
if($Robert->TakeWeapon($Andrew,20)) //Uses 20% force
{
$Robert->FireWeaponAt($Andrew,-1); //Use all bullets on andrew!
}
}
if(!$Andrew->IsAlive())
{
$Robert->UpdateScoreFromPLayer($Andrew,100); //Max of 100 points if andrew has them.
}
}
By doing this it would not be hard to generate characteristics for entities.
You can also set up parent destructors to save the user-names data in a database for next time, and use the __construct to update the classes data. Hope this gives you a good idea :)
There's more :)
If you make classes for SpecialMoves lets say you can always do
$Robert->AddSpecialMove('Roundhouse',new SpecialMove_Roundhouse(12));
$Robert->UserSpecialMove('Roundhouse',2);/ x2
if($Robert->_SpecialMoves->Roundhouse->Left() < 12)
{
$Robert->UserSpecialMove('Roundhouse',-1);/ Use all kicks.
}
Within SpecialMove_Roundhouse
it would have parameters such as damage, lenght of time taken to complete, how much energy it uses, how many times you can use it.
and the very first class that in the scope should always me a calculator for things such as heartrate, blood level, energy, inventory etc so you always have the essentials!
Implements Example
Implements make sure that the higher class contains certain functions and variables
interface Weapons
{
public function Fire($target,$bullets);
}
class Colt45 implements Weapons
{
var $damage = 2;
var $max_bullets = 80;
var $clip = 80;
//THIS CLASS MUST HAVE FIRE
public function fire($target,$bullets)
{
$ammo = $bullets > $clip ? $clip : $ammo;
for($shot=0;$shot<=$ammo;$shot++)
{
$target->ReduceHealth($damage);
if(!$target->IsAlive())
{
break;
}
$clip--; //Reduce ammo in clip.
}
}
}
Example here taken from php.net | http://www.php.net/manual/en/language.oop5.interfaces.php#96368
<?php
interface Auxiliary_Platform
{
public function Weapon();
public function Health();
public function Shields();
}
class T805 implements Auxiliary_Platform
{
public function Weapon()
{
var_dump(__CLASS__);
}
public function Health()
{
var_dump(__CLASS__ . "::" . __FUNCTION__);
}
public function Shields()
{
var_dump(__CLASS__ . "->" . __FUNCTION__);
}
}
class T806 extends T805 implements Auxiliary_Platform
{
public function Weapon()
{
var_dump(__CLASS__);
}
public function Shields()
{
var_dump(__CLASS__ . "->" . __FUNCTION__);
}
}
$T805 = new T805();
$T805->Weapon();
$T805->Health();
$T805->Shields();
echo "<hr />";
$T806 = new T806();
$T806->Weapon();
$T806->Health();
$T806->Shields();
/* Output:
string(4) "T805"
string(12) "T805::Health"
string(13) "T805->Shields"
<hr />string(4) "T806"
string(12) "T805::Health"
string(13) "T806->Shields"
*/
?>
Classes are about behaviour, so if different types of monsters in your game behave differently, then model them as different objects. If all monsters basically share the same behaviour (e.g. all having a shared set of properties, all can attack or defend and move), then you can save yourself lots of work if you model them as a single monster class. You can always extend the monster class into specialized classes for monsters that can, e.g., talk.
OOP lets you extend classes, reusing your the code. Here's a simple example. Check out the PHP docs for Inheritance.
class Monster
{
public $size = 'average';
public $color = 'grey';
public function scare()
{
return "Bo!";
}
}
class Rat extends Monster
{
public $size = 'small';
public function scare()
{
return parent::scare() . " (runs away)";
}
}
class Mouse extends Rat
{
public $color = 'white';
}
And the output would be:
$rat = new Rat();
echo $rat->scare(); //output: Bo! (runs away)
echo $rat->size; //output: small
echo $rat->color; //output: grey
You should read about S.O.L.I.D.
These are the 5 basic principles of OOD (Object Oriented Design):
S ingle Responsibility Principle
O pen Closed Principle
L iskov Substitution Principle
I nterface Segregation Principle
D ependency Inversion Principle
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
By the way, if you want to use inheritance just to extend some properties and methods, you can do this by using Composition instead of Inheritance. Inheritance should be used to add polymorphic behaviour to you class structure.
精彩评论