using one class for multiple players?

I just learned how to use classes. I was thinking that I could use the same class for both player 1 and player 2 even though they would have different controls. the only way I can imagine using the same class for some of the already created code would be to use a list of objects like this:

playerlist = []

playerlist.append(PlayerClass("player1"))
playerlist.append(PlayerClass("player2"))

later, instead of using “own” (cont.owner), I would just use “playerlist[0]”. maybe I would use a variable instead of “0” to make the code universal. does this make sense? is there a better way?

With this example, it’s not clear why classes are particularly unique to your question. You’re already using the same class for both players, because that’s what classes are primarily useful for (though, not their only utility). For different control mappings (i.e keyboard mappings), a keymapping object (like a dictionary) could be used so that the same code can be used to process the inputs.

If your game is only going to ever have 2 players, you could probably just get away with storing each as an object, not in a list.
player1 = Player(‘1’)
player2 = Player(‘2’)

A list would be perfect (and required) if you had an indeterminate amount of players, or were dealing with more than just a few.

A system I’ve been adopting recently, which has worked out well for me, is to create a “Core” class which acts as the grand overlord of the game’s structure, and building a heirarchy of classes to fit in its place under Core.

So a skeleton of this might look like:


class Core:
def __init__(self,players):
self.players = players

class Player:
def __init__(self,weapon,item,beard):
self.weapon = weapon
self.item = item
self.beard = beard

class Weapon:
class Item:
class Beard:

This way, everything within Core can communicate with anything else within Core. If using my Player’s Beard decreases the second player’s Weapon’s Rate of Fire, I could put something like this in Beard’s ‘use’ method:


self.Clog(self.player.core.player2.weapon.RoF)

Terms
Please do not use the term “class” in this way. A class describes the behavior and structure of an object. You are talking about objects (an instance of a class). This is a fine but very important difference. If you mix the terms you quickly confuse the reader and yourself.

Instantiating
In terms of classes there is no problem in creating multiple instances of the same class. That is what they are used for. Otherwise you could use a module to create a singleton (you can have just one module of the same name).

Keeping References
Typically you always store a reference to your objects (class instance) into a variable. If you want to use a list, several variables, or other container depends on your situation. There is no problem to store the reference to the same object in multiple variables either.

controller.owner is just a way to get the reference to the object of class KX_GameObject from the context. You can get such references from several other sources including properties, modules, logic bricks.


objectFromProperty = controller.owner["myObject"]
objectFromModule = myModule.myObject
objectFromActuator = mySteeringActuator.target
objectFromObject = myObject.anotherObject
...

Different controls
As you do not told us how your classes are supposed to interact with the controls, we can’t give you any advice on that.

Using classes
As classes define the behavior of multiple objects, these objects will behave the same. That does not mean the all do the same thing at the same time. It means they behave the same under the same circumstances. Objects typically contain internal data which define the objects current state. These data usually is different between the different objects, while the behavior (the code) is the same.

A shared class also defines a shared interface of the objects. That means if one object has a specific attribute, the other object has the same attribute too. This makes it easy to treat such objects all the same.

Example:
Your “Player” class implements a method “run()”. That means you can call run() on any of the objects that inherit from class Player:


for player in collectionOfPlayers:
    player.run()

The user of the players does not need to care how “run()” is implemented. He just needs to know it is callable. He does not even need to know if it is player one or player two or player “I’m the good of this game”. They all can run() -> do it.

There’s a really good article on classes and inheritance here:
http://www.jesshamrick.com/2011/05/18/an-introduction-to-classes-and-inheritance-in-python/

It talks a little about subclassing, that is creating a main class and adding variants of that class. I don’t know how much you know about that already so I apologize if I’m talking about stuff you already know.

You could have a main class, Agent() which has code for animation, mesh switching, taking damage and lots of other things which are shared by every agent in the game. Then you can create a Player() class which is an instance of Agent. It shares all the same code as Agent(), but also has code for inventory management, spells or weapons or other things that only players have. You could also set up a subclass of Player, being PlayerOne() and PlayerTwo() which could be identical to the normal player class, but have different methods of movement input (one controlled by WSAD and the other by keypad for example).
The using your Agent() class you can create a subclass Enemy() which has AI control…

You can see the benefits, so much code is reused in each case it saves a lot of messy code and reduces redundancy.

You should do some research on the super() method if you decide to go down this route as it really helps to keep things clean and clear.

Another thing you can do to keep things clean is to pass the player object to the class, or even the active scene, so that class functions can call those things using self.game_object or self.active_scene. That is, unless you decide to subclass the KX_game object itself…

teoretically this is the main goal of the class -> create instances.
if we know that all gameobject has obj.worldPosition , applyRotation() is just the result of classes and subclasses.
(imagine if one use obj.pos , another obj.global_position)

anyway the player is a strange object, never understand what should do :smiley:

WOW! thanks for all the information. I’m really starting to have a firm grasp on objects and classes.