Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  Design/Data Structures  (Read 668 times)
0 Members and 1 Guest are viewing this topic.
Offline dime

JGO n00b
*

Posts: 40



« on: 2010-09-01 19:25:56 »

What would be a good way to code up a character class?

Right now I have this:

Entity
Character Extends Entity
Dwarf, Elf and Human all Extend Entity.

This works pretty well.  But each race can have skills (some different)
Each race can also have different classes and different classes can have different skills.

Right now I have Classes and Skills as their own classes/objects and add them to race.
Inside Character I have an "array" of skills and classes.  It's kind of muddled though because classes can add skills.

Is there a better way to design this?

A small example:


Dwarf has Defend skills.
Elf has no skills.

Fighter has Attack and Defend skill.
Mage has no skill.


A dwarf fighter would have Attack and 2+Defend.
Mage Elf would have none
Fighter Elf would have Attack and Defend.

Right now all this info is spread all over the place.


I can't extend the Classes ontop of Race cause each race could be any class.
Offline zoto

Full Member
**

Posts: 234
Medals: 7



« Reply #1 on: 2010-09-01 23:02:02 »

The way I usually approach this problem is by adding a separate class(or interface) for Race information and another for CharacterClass then these can be member variables for the Entity rather than having to extend the Entity class.
Offline Eli Delventhal
« League of Dukes »

JGO Kernel
*****

Posts: 3573
Medals: 44


Game Engineer


« Reply #2 on: 2010-09-02 00:44:47 »

The way I usually approach this problem is by adding a separate class(or interface) for Race information and another for CharacterClass then these can be member variables for the Entity rather than having to extend the Entity class.

Yeah, I typically will only use subclasses for the more abstract type of object: Entity, DrawnEntity, FriendlyEntity, MonsterEntity, etc. Stuff like that. Then you use data members to decide any specific functionality that is different across each.

Instead of making a different class for every single skill, you'd probably be better off just making most of them individual data members of CombatEntity or something - defend, attack, etc. sound pretty general. The sorts of things you would use subclasses for would be very specific functionality that needs its own way of executing.

See my work:
OTC Software
<br />
Currently Working On:
Secret project...
Quote from: _Riven
I edit JGO in production, because I simply don't waste time writing bugs
Games published by our own members! Go get 'em!
Offline Orangy Tang

JGO Kernel
*****

Posts: 2960
Medals: 37


Monkey for a head


« Reply #3 on: 2010-09-02 06:18:38 »

What would be a good way to code up a character class?

Right now I have this:

Entity
Character Extends Entity
Dwarf, Elf and Human all Extend Entity.

I suspect this is a bad approach. It'll lead you down the old-school approach of a massive inheritance hierarchy for your characters with all the usual problems that brings (some of which you're already finding with the classes/races setup). In particular it's nice to be able to swap the race/class at runtime  - the classic example being "polymorph self", where your character becomes a different race/animal for a limited period. That's easy if the race is a sub-object or data-driven, but very hard if your Character is actually a DwaftCharacter object and you want to change it into a WolfCharacter.

Ascii dreams has this rather interesting approach:

Quote
I suspect that the vast majority of games would be satisfied with five core data structures: player, enemies, playing field, pick-ups and effects. You may even be able to collapse e.g. player and enemy together.

This is exactly what I'm doing for Albion and it's working quite well so far. I have a single Character class which represents both player characters and monsters (and later, NPCs). All differentiation (skills, racial traits, stats) are either data members or attached sub objects. Your Character could reference a Class and an Race, and both would contribute objects deriving from a Skill interface.

This has parallels with the component-based entity systems that are gaining popularity. You might want to search the forum for the old threads we've had on that in the past.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Eli Delventhal
« League of Dukes »

JGO Kernel
*****

Posts: 3573
Medals: 44


Game Engineer


« Reply #4 on: 2010-09-02 16:21:38 »

One thing to consider is that you get all sorts of gameplay variety for free if you do what Orangy is describing. If the player/allies and monsters are the same class, that means that you can very easily implement a "capture" or "charm" approach. i.e. you can add any monster or player, anytime, anywhere, to your party. If you end up with an insane class hierarchy, this is not at all easy.

Usually I make everything the same class, except I give them all an integer that determines their allegiance. Then it's very simple to say if (myAlliegiance != theirAllegiance) {startBattle()} or something similar. That way you also get different factions of enemies fighting each other for free and a whole lot of fun in between. Make your system work for you!

In general, the only time I make a subclass is when I want to limit functionality for the sake of speed/memory or sanity. For example, I usually keep a BackgroundEntity separate from a CombatEntity, because it really doesn't need the insane number of stats related to combat that a player and monsters need. It also doesn't need to move, have velocity, etc. That saves me from worrying if a wall is going to start moving around for some reason, as well as adding in a lot of if (canFight) {doSomething} if (canMove) {doSomething}.

The difference between a dwarf and an elf is completely cosmetic. There is no functionality whatsoever to limit between them except for how they're drawn and perhaps some minor behavioral or stat differences. Therefore, definitely don't make them different classes!

See my work:
OTC Software
<br />
Currently Working On:
Secret project...
Quote from: _Riven
I edit JGO in production, because I simply don't waste time writing bugs
Offline princec
« League of Dukes »

JGO Kernel
*****

Posts: 8076
Medals: 91


Eh? Who? What? ... Me?


« Reply #5 on: 2010-09-02 16:27:44 »

I use pretty much the same set of classes for all my games, give or take one or two extra bits and bobs:
1  
2  
3  
4  
5  
Entity
  Gidrah
  Bullet
  Player
  Obstacle

like for example I've got Buildings in RoTT and each general classification of building has a different class depending on its specifically unique functions. Everything else is basically attributes of those Entities.

Cas Smiley

Offline dime

JGO n00b
*

Posts: 40



« Reply #6 on: 2010-09-02 18:57:16 »

I spent 8 hours re-writing this last night.

Right now I have:

Entity
Character extends
Player extends Character

Character is just a monster or whatever, player adds player specific functions.
In Character I have a hashmap of "attribute name" and int.  This stores basic things like health, xp, level, stength, etc. 
Basically anything that can be an int.  Works well.

Skill, Feat and Spells, etc are all objects.

Each character has a RaceID and an Array of Classes (I'm going to call them Casts to avoid confusion).

When a character is created with a certain RaceID, it'll look up all it's feats, skills, etc from a static final hashmap (but this could be stored in DB, XML, etc backend); it'll find it's info and add it.  Same when cast is added. it'll look up all it's info in the hashmap table and add it based on cast id.


This seems to work well.  The only problem is the info for Race, Cast, etc are stored in this huge ulgy static hashmap.  It works nice, but doesn't feel right.  Even if I stored it in a DB, xml or cvs, etc - I'd still have to load all this data into some type of structure I could easily access.  It doesn't really and everything uses the same info... so a static final hashmap is the way to store this info?  Seems a bit awkward.


One cool thing that I got working is that I can attach a method or jpython script to a feat/skills by a String.  So I have feat "Knockdown" that has a string called "RuleSetObject.knockdown(self,other)".  When player uses that feat it looks up that method by string name and executes it.  I'll have to see how fast jpython is, but with this; it'll be super easy to quickly add new functionality.  Also give modders a lot of flexibility since none of the actions are hardcoded, but will be stored in db, xml, etc.
Offline Nate

JGO Neuromancer
****

Posts: 1062
Medals: 30


mooooo


« Reply #7 on: 2010-09-02 19:44:15 »

This seems to work well.  The only problem is the info for Race, Cast, etc are stored in this huge ulgy static hashmap.  It works nice, but doesn't feel right.  Even if I stored it in a DB, xml or cvs, etc - I'd still have to load all this data into some type of structure I could easily access.  It doesn't really and everything uses the same info... so a static final hashmap is the way to store this info?  Seems a bit awkward.
YamlBeans! Smiley See sig.

Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.094 seconds with 20 queries.