Forum > Beginners

What is the best/versatile/efficient etc way to describe game character?

(1/6) > >>

TomTom:
I dont' know if I'm asking good question :S but...
Finally I've decided to start (slowly) creating this simple maze-dungeon-rogue-rpg-adventure-like game. Nothing fancy, just random dungeon, player character and few monsters to slay. What I've done so far is ... almost nothing. I want to make small steps, so  I've written code which generates random dungeon. It works and it's quite easy.
My second step was to create player character and give it possibility to move around that dungeon. It works.
I did that by:
- using Array of string for Dungeon ('#' is wall and ' ' [space] is ... empty space)
- player character is

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type  TPlayer = class    private      FPosX : Integer; //position X in dungeon      FPosY : Integer; //position Y in dungeon      FPRect: TRect; //TRect for player       property PosX: Integer read FPosX write FPosX;      property PosY: Integer read FPosY write FPosY;      property PRect: TRect read FPRect write FPRect;     public   end; 
But I'm wondering if its good to do this like this.

I'm thinking about
- Creating class for every living entity in world with info about
  - FEntityType : etNPC, etEnemy, etPlayer
  - FEntityClass : ecWarrior, ecWizard, ecRogue, ecCleric etc etc.
  - FEntityHealth: integer;
  - FEntityAttitude : eaHostile, eaFriendly, etNone = for player?
  - FEntityStr : integer; //Attack strength of entity?
  - FIsQuestGiver: boolean; // I don't know if there will be quests, maybe except slay 10 rats
  - FEntityRace: erHuman, erOgre, erDwarf etc
  - FEntityRect: TRect // for image to Display
  - FPosX: integer;
  - FPosY: integer;
etc etc etc

and then create sth like this

TPlayer = class(TEntity)
TEnemy = class(TEntity)
 etc etc etc

Does it make any sense? Or am I thinking all wrong about this.

 

Handoko:
I'm not an expert in OOP. But I will do something like this:

1. Use the power of OOP - subclassing

TEntity, subclass to:
- TStaticObject
- TMovingObject

TMovingObject, subclass to:
- TNPC
- TPlayer

FEntityType, FEntityClass, FEntityRace can be omitted if you subclass them properly.

2. TEntity has these fields:

- FPosX
- FPosY
- FWidth
- FHeight
- FAnimImage
- FAnimProgress
- FAnimDelay

The FAnim* are used for doing animation. How to use it you can see the source code of FuriousPaladin I wrote.

Note:
You maybe want to try Mazer - procedural maze dungeon in 3D.
https://forum.lazarus.freepascal.org/index.php/topic,29543.msg186811.html#msg186811

TomTom:
Thanks Handoko :) I don't know if I understand it right (You wrote 'subclass to' but shouldn't it be 'subclass OF' ?):


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TEntity (BASE OF ALL)    |    |____ TStaticObject (walls?)    |____ TMovingObject (player, monsters)             |             |______ TMonster             |______ TPlayer

Why EntityType, EntityClass and EntityRace could be omitted? Im my case both Monster and Player could have same class types (warrior, mage etc), so I guess it would be convinient if TPlayer and Tmonster inherit those fields from Base (TEntity) class.

I'm not planning to do any animations for this project. This already is complicated to me and hard to understand without animations :P


lucamar:
As in all object hierarchies, you have to abstract common behaviour from specific ones. For example, your mages can launch spells, a warrior can have his weapons, etc. But both of them have certain characteristics in common: they can move through the maze, they have some health, etc.

These later characteristics, common to all type of players could go to the TGameCharacter class while characteristics proper to each kind would go into a child class like: TWarrior = class(TPlayer).

In your program then you can differentiate between each player by using for example:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if Player is TWarrior then ... so you wouldn't need to store the kind in the general TGameCharacter class: each child class already knows what it is.

Since this is valid for almost every entity in your game: enemies, plunder, etc. you create a base class TEntity with the bare minimum info & methods needed: size, position, maybe its shape (whether as a char or a bitmap), etc. and from this base class you derive one child for static objects like treasures, emergency packs, etc. which can't move themselves but can change position (by a dynamic "object" carying them, p.e.) and dynamic ones like "monsters" and players.than can move by themselves.

That's basically how it could be done.

TomTom:
And that's how I was thinking about this (more or less).


--- Quote from: lucamar on March 07, 2019, 09:07:28 am ---As in all object hierarchies, you have to abstract common behaviour from specific ones. For example, your mages can launch spells, a warrior can have his weapons, etc. But both of them have certain characteristics in common: they can move through the maze, they have some health, etc.

These later characteristics, common to all type of players could go to the TPlayer class while characteristics proper to each kind would go into a child class like: TWarrior = class(TPlayer).

In your program then you can differentiate between each player by using for example:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if Player is TWarrior then ... so you wouldn't need to store the kind in the general TPlayer class: each child class already knows what it is.

Since this is valid for almost every entity in your game: enemies, plunder, etc. you create a base class TEntity with the bare minimum info & methods needed: size, position, maybe its shape (whether as a char or a bitmap), etc. and from this base class you derive one child for static objects like treasures, emergency packs, etc. which can't move themselves but can change position (by a dynamic "object" carying them, p.e.) and dynamic ones like "monsters" and players.than can move by themselves.

That's basically how it could be done.

--- End quote ---

Navigation

[0] Message Index

[#] Next page

Go to full version