Recent

Author Topic: What is the best/versatile/efficient etc way to describe game character?  (Read 6684 times)

furious programming

  • Hero Member
  • *****
  • Posts: 853
I separate TPlayer and TMonster because TPlayer has code for handling user input and TMonster has code for AI.

No no no — the player's character should not be connected in any way with the input handling. The player character and creatures have common features (such as the ability to move around), which should be grouped into one base class:

Code: Pascal  [Select][+][-]
  1. TGameObject
  2.   |
  3.   |__ TStaticObject
  4.   |     |
  5.   |     |__ {..}
  6.   |
  7.   |__ TMovingObject
  8.         |
  9.         |__ TCharacter // common features for all characters
  10.         |     |
  11.         |     |__ TPlayer
  12.         |     |     |
  13.         |     |     |__ TWarior
  14.         |     |     |__ TMage
  15.         |     |     |__ TBard
  16.         |     |
  17.         |     |__ TMonster
  18.         |           |
  19.         |           |__ TOgre
  20.         |           |__ TGoblin
  21.         |           |__ TTroll
  22.         |
  23.         |__ {..}

However, data about move should be provided from outside and come from two different sources.

In this way, I have it implemented in my own platformer. Thanks to this, hero is displayed inside the level and controlled by the player, and the second hero (of the same class) is displayed on the counters bar. Controlling the hero is in no way associated with these characters, so it is possible to perform a separate logic for the hero controlled by the player and separate for the hero visible at the lives counter (see attachment).
« Last Edit: March 07, 2019, 06:42:46 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Did you mean to use it as an avatar? I think I can understand your reason. But I instead will has a method DrawAvatar on each subclass of TPlayer.

My plan is each TPlayer may have different play style. For example:
Click -> move walk to the location
[Shift] + click -> run to the location (not applicable on TMage)
[Ctrl] + click -> cast a spell on the location (not applicable on TWarrior)
« Last Edit: March 07, 2019, 06:47:58 pm by Handoko »

TomTom

  • Full Member
  • ***
  • Posts: 170
EDIT: And one thing... No mouse clicking and GoTo :) ... Just arrow keys and move one cell at a time :) ... Yeah.. pathfinding will be ... never mind :P.. small steps :P

Wow! Thanks guys for help :)

At first I thought that for my needs Lucamar's solution would be good since I'm not planning making detailed game.

Then there's furious programming solution and that what Handoko said. Since I'm using array for my dungeon it could would be array of TGameObjects (i guess). TGameObject with PosX, PosY and Sprite/Image. StaticObject would be hm either just collectable(boolean) or it could also have subclasses for TCollectables and TDecoration (Walls, pillars etc).
Just wondering do I need subclasses of TPlayer or simple properties will be enough.

Well Now I have a clue what I should do (that doesn't mean that I know how though :P)

Thanks Guys :) 
 
« Last Edit: March 07, 2019, 07:00:29 pm by TomTom »

furious programming

  • Hero Member
  • *****
  • Posts: 853
Did you mean to use it as an avatar? I think I can understand your reason.

If we assume that every object in the game (movable and static) is only a packet storing data about its state (without any logic which depends on the style of movement), it will be very easy to manage and control from outside. Each object can be treated as you like at any time.

Quote
But I instead will has a method DrawAvatar on each subclass of TPlayer.

And what if the non-playable character (as in the case of the hero on the couters bar in my game) is not to be static and it must be animated based on some data? The method to paint a sprite is not enough.
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Just wondering do I need subclasses of TPlayer or simple properties will be enough.

It's all depend on how much details you want to put. If there are no much differences then use simple properties. Also if you plan to maintain the code or there will be version 2 of the game, you should consider to start the basic detail earlier. So it will be easier for you in the future to improve the code.

I usually will avoid doing subclassing if there is no good reason for it. For example the TGoblin.

If you think you will later add more details on each of the monster (maybe on your version 2 release), you may need to consider to subclass TGoblin to TCommonGoblin and TMagicGoblin. Each of them may have different image, behavior, etc. But if it's just for a simple learning purpose and you don't think you will maintain/improve the code in the future, simply use FMagicUser and FSpell is good enough.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
@furious programming

I already said I understand your reasons. But how will you solve the playing style issue I mentioned?

furious programming

  • Hero Member
  • *****
  • Posts: 853
@Handoko: creating a separate class or set of classes that will deal with moving objects around the level (will make the logic universal). Thanks to this, any algorithm can be used for any object.

And thanks to this, the source of data on moving objects will be arbitrary (input for hero control, AI algorithms for controlling monsters, predefined list of moves for the hero in cutscenes, etc.).
« Last Edit: March 07, 2019, 07:18:33 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
I can't understand.

If I disconnect TPlayer with the input handling code, how can I do the different play style for different members of TPlayer?

furious programming

  • Hero Member
  • *****
  • Posts: 853
If you do not separate this logic from the hero class, how will you control it, for example in cutscenes, in which input is not taken into account? Will you simulate key pressing?

And the more complex example — what if you want to use the game engine, for example to render the background of the game menu in form of level (with player and monsters, controlled by AI), in which the input is used to navigate the menu options? You will not be able to simulate keys.

If you separate this logic then you can do anything you want.


I will use my platformer again as an example.

During the game, inside the level, the hero is controlled by the keyboard (video). In contrast, in the main menu, the background is the level with the hero, whose movement is not dependent on the keys pressed, and yet after accepting the menu (ie, pressing the jump button), the hero will be outside the screen (video). The background in the form of a level is also used in the staff screen, where the hero is moved in another way, also independent of the input.

I would not be able to do it if I did not separate this logic (because after pressing the spacebar, the hero would jump, and should not).
« Last Edit: March 07, 2019, 07:40:23 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
I can temporary disconnect the input handling from TPlayer, by add FDetectUserInput: Boolean. But if I totally remove the input handling code from TPlayer, how can I do the different play style?

Okay, I understand. It's all language barrier fault. I used wrong word "user input". What I meant for the "user input" is not direct reading the user input as what you think. My fault, I should choose better words. Sorry.

I can communicate better using Pascal code, not English.  :D
« Last Edit: March 07, 2019, 07:42:28 pm by Handoko »

furious programming

  • Hero Member
  • *****
  • Posts: 853
Maybe you're right and this is a problem with the language barrier.  :D

In spite of everything, I still think that separating the logic of moving from object classes is an important thing. Certainly, a concrete example of implementation would be helpful here, but unfortunately I do not have time to prepare it.
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

 

TinyPortal © 2005-2018