Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  OOP Noob - Extending Classes, or How Else to Create Unique NPCs?  (Read 2467 times)
0 Members and 1 Guest are viewing this topic.
Offline johnnystarfish

Senior Newbie


Medals: 2



« Posted 2013-11-14 02:16:45 »

Hello,

I'm just now getting started in OOP after doing everything procedurally in a variety of languages since QBASIC. I'm working through the concepts explained in the Java book I'm reading but instead of creating the pointless business apps they want me to do, I'm trying to make simple text-based games.

So I'm writing a cage-fighting app right now, where I define an NPC class, create two identical NPC objects, and then have them hack away at each other to see whose hitpoints drop below 0 first. More of a simulation than a game.

Right now I'd like to modify it so that there are certain types of NPC. For instance humans, orcs, elves, etc, all with different stats. The next step after that will be creating an arbitrary number of NPCs and have all of them fight each other at the same time. So what I do now needs to be scalable.

What's the ideal way of going about this? I was thinking about extending the NPC class to include base stats, then overriding them with race-specific values via extension. The only problem is, right now I've got it hardcoded so that "nextEnemy = new Fighter();" but I don't know (yet) how to refer to the object that extends Fighter as anything other than Fighter (i.e. if it's an Orc, it's already hardcoded to refer to "new Fighter()", not "new Orc();").

Am I supposed to create some kind of container object and use a loop to just have the player attack anything contained within?

I'd appreciate any direction you all could give me as I try to get better at this.

Thanks!
Offline kingroka123

JGO Ninja


Medals: 35
Projects: 6
Exp: 1 year


Gamer's Helmet


« Reply #1 - Posted 2013-11-14 02:22:16 »

ok so I think what you need to do is either define different classes within the Fighter class like having different stats for different ids. This would allow one class but is probably the least efficient option

Or you can create separate classes that extend Fighter()( so you can get the variable) but you change the stats. This way you could just call nextFighter= new Orc() and it would still be counted as a Fighter

ps: mincraft kinda does the second one for blocks

Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #2 - Posted 2013-11-14 02:28:30 »

I think you're over complicating it.

What you need to do is have a base NPC class that has basic stats like health, weapon damage, defense etc... Then just have sub classes such as orc that extend NPC, and override those stats. The NPC class should only be handling the basics like rendering, updating, moving and attacking, but it should not be setting any stats. You need to super the stats up to the NPC class from sub classes. That way you can just have a array of NPCs, and loop through them all, and you can just see if a certain object in the array is an orc by saying
1  
if(npc[index] instanceof Orc)

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Troncoso

JGO Coder


Medals: 20



« Reply #3 - Posted 2013-11-14 02:30:23 »

A Fighter object can be dynamic, so you can have some sort of condition statement that dynamically sets the fighter to be any one of the Fighter subclasses you create.

So:

1  
2  
3  
4  
5  
6  
Fighter fighter;

if ( <something> )
    fighter = new Orc();
else if ( <something> )
    fighter = new Elf();


That's kind of crude, but should get the idea across. I think you should supply more code so we can get a better idea of what you are asking.
Offline johnnystarfish

Senior Newbie


Medals: 2



« Reply #4 - Posted 2013-11-14 02:40:09 »

A Fighter object can be dynamic, so you can have some sort of condition statement that dynamically sets the fighter to be any one of the Fighter subclasses you create.

So:

1  
2  
3  
4  
5  
6  
Fighter fighter;

if ( <something> )
    fighter = new Orc();
else if ( <something> )
    fighter = new Elf();


That's kind of crude, but should get the idea across. I think you should supply more code so we can get a better idea of what you are asking.


Ha! That's how I imagined the code in my head, but just couldn't come up with the syntax for it.

Am I correct in my understanding of your example that "fighter" basically becomes a container object for any given type of NPC? Thus, regardless of which condition is chosen in your example, I should be able to call fighter.getStrength() and it will show me either the strength value for an orc or elf according to their extended class?

I think you're over complicating it.

What you need to do is have a base NPC class that has basic stats like health, weapon damage, defense etc... Then just have sub classes such as orc that extend NPC, and override those stats. The NPC class should only be handling the basics like rendering, updating, moving and attacking, but it should not be setting any stats. You need to super the stats up to the NPC class from sub classes. That way you can just have a array of NPCs, and loop through them all, and you can just see if a certain object in the array is an orc by saying
1  
if(npc[index] instanceof Orc)


I think that solves my next problem. I'll plan on using arrays to keep track of multiple fighters and loop through it. Thanks!
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #5 - Posted 2013-11-14 02:52:13 »

Quote
Am I correct in my understanding of your example that "fighter" basically becomes a container object for any given type of NPC? Thus, regardless of which condition is chosen in your example, I should be able to call fighter.getStrength() and it will show me either the strength value for an orc or elf according to their extended class?

This is true. No matter what, since your subclasses such as orc extend fighter, you'll be able to call something like getStrength. Your sub classes inherit the functions that the super class has, so for instance, say Fighter looks like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
int strength, hp;

public Fighter(int strength, int hp){
      this.strength = strength;
      this.hp = hp;
}

public int getStrength(){
       return strength;
}


And then orc:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
class Orc extends Fighter

public Orc(){
       //super gives the super class the paramters it needs for its constructor
       super(20, 100);
}

public int getStrength(){
//references the getHealth function in super class Fighter
       return this.getStrength();
}


Of course, this isn't the best way of doing it as you don't entirely need that getStrength function in the Orc class. I was just trying to show you how sub classes work!

Offline johnnystarfish

Senior Newbie


Medals: 2



« Reply #6 - Posted 2013-11-14 03:00:45 »

Of course, this isn't the best way of doing it as you don't entirely need that getStrength function in the Orc class. I was just trying to show you how sub classes work!

Of course. My understanding is that the getStrength method should be in the super class, and only the race-specific stat tweaks in the sub classes.

Thanks for confirming all of this; I really appreciate it.
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #7 - Posted 2013-11-14 03:05:26 »

No problem, just as tip, the appreciate button gives the use medals, which is a very nice reward Smiley No pressure, but if anyone helps you, and you feel grateful, just hit that button!

And yeah, I was just trying to show you about sub classes and inheritance. That was kind of a poor example on my part, but I think you know what I was trying to say!

Offline johnnystarfish

Senior Newbie


Medals: 2



« Reply #8 - Posted 2013-11-14 03:36:48 »

Hey, I'm all for giving props where they're due, but I'm not seeing an appreciate button anywhere. Is that something I need to have a minimum post count/age to be able to do or am I just overlooking it?
Offline kingroka123

JGO Ninja


Medals: 35
Projects: 6
Exp: 1 year


Gamer's Helmet


« Reply #9 - Posted 2013-11-14 03:38:46 »

try far right-top on a post

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline johnnystarfish

Senior Newbie


Medals: 2



« Reply #10 - Posted 2013-11-14 03:45:06 »

Yeah I only have the option to Reply or Quote on others' posts. I'll revisit this question later and give credit where it's due.

Thanks again all.
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #11 - Posted 2013-11-14 03:47:31 »

Ah, yes you need to post more on the forums before you can appreciate anything!

Offline johnnystarfish

Senior Newbie


Medals: 2



« Reply #12 - Posted 2013-11-14 03:49:23 »

Looks like the option just popped up. I guess the magic number was 5 posts. I gave each of you a karma and it's not letting me do it any more for an hour, so there you have it Wink
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #13 - Posted 2013-11-14 03:50:52 »

Here, have your first medal, courtesy of me! Smiley

Offline HeroesGraveDev

JGO Kernel


Medals: 269
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #14 - Posted 2013-11-14 06:13:54 »

Enums anyone?

Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #15 - Posted 2013-11-14 07:35:08 »

In addition to what the other said (which were all great)

Also depending on how might flexibility you might want.

You might consider having some rand.nextInt(40)+80;  for health or something, to give some 'variety' to your particular Orc.

you can also, depending if you have their name anywhere, you can have a prefix list like
String prefix[] = {"Mighty", "Strong", "Evil", "Dastardly", "Weak"};
name = prefix[rand.nextInt(5)] + " Orc";

So you have different Mighty Orcs!  Or other variations

If your game is visual, you can add a very simple filter/shade to your texture to give it a slight color hue/tint(many libraries have a way of handling this quite easily) or scaleXY to make them slightly different in size. Depending upon your game.

"Experience is what you get when you did not get what you wanted"
Offline EliwoodL

Senior Newbie





« Reply #16 - Posted 2013-11-16 14:13:03 »

This may be a bit advanced or a jump to get into, but a component-system based approach is quite efficient, from my own experience.  Essentially, each entity is simply an ID that's assigned predefined component classes - like health, or damage, or movement - that another class, a system or handler, takes into account to make the entity do what you want it to.

The one I like currently is the Artemis Entity System.  http://gamadu.com/artemis/
Offline tberthel
« Reply #17 - Posted 2013-11-16 16:31:48 »

composition over inheritance.

Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 136
Projects: 4
Exp: 3 years



« Reply #18 - Posted 2013-11-16 17:03:01 »

composition over inheritance.
For this type of game, yeah, but let's not try to confuse him too much Grin
Offline Roquen
« Reply #19 - Posted 2013-11-18 09:04:20 »

What's confusion about using data rather than hardcoding?  It's easier to write, maintain and understand.  There's not much need even for composition...just be data driven.
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 136
Projects: 4
Exp: 3 years



« Reply #20 - Posted 2013-11-18 17:57:18 »

Well I think one should learn the basic OOP Pattern before going on to others.
Offline Roquen
« Reply #21 - Posted 2013-11-18 20:50:30 »

OO isn't a pattern.  Data-driven and design by composition is pretty much the whole point.
Online wessles

JGO Wizard


Medals: 67
Projects: 4
Exp: 3 years


Profile picture isn't relevant.


« Reply #22 - Posted 2013-11-20 04:10:10 »

Enums anyone?

Yeah. I love enums, but sometimes, I feel like it isn't enough. You can do enums, or you can make a static class like minecraft does for blocks. Like, every block extends Block, and all blocks are predefined objects in it, like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
class Block {
    public static Block grass = ((Block) new Grass());
    public static Block dirt = ((Block) new Dirt());

    public Block(float hardness, int id) {
        ...
    }

    public abstract void render(Graphics g, float x, float y);
    ...
}


It seems to give more options than enums... Instead of just defining constructors, you can define methods as well!

Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #23 - Posted 2013-11-20 04:18:51 »

But enums can have functions?

It really depends on what you want out of your program. Both are viable solutions, they both get the job done in different ways. However, you'll need an actual class to host the enum, so depending on how you want your project to be set up, you'll probably just need to go with static functions rather than an enum. If that makes sense! Typing on a phone is rather bad for going back over your post Tongue

Offline HeroesGraveDev

JGO Kernel


Medals: 269
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #24 - Posted 2013-11-20 07:06:51 »

The OP says he only needs to override data, so enums are the easiest way of doing things for this situation.
No need to worry about functions.

Offline Roquen
« Reply #25 - Posted 2013-11-20 09:49:25 »

Using enums, anonymous inner classes, etc all require learning new language feature(s) AND they don't scale very well and are pretty much only a minor step up from hardcoding (creating a sub-class for each monster).  They can all be reasonable choices if the number of monsters is small, but why not do it one of the reasonable ways from the start?

Maybe I'm crazy but even for a beginner I'd suggest mimicking what you'd do in real life with a pencil-and-paper RPG.  Let's say you have a green-and-pink polka-dotted dragon fighting 10 rabies-infested-vorpal-furry-bunnies.  You look up the "bunnies" in your Monsterz Emanuel do you expect to see:

rabies-infested-vorpal-furry-bunny
Is a vorpal-furry-bunny with "And they have rabies!" appended to the description.  "+2% of inflicting "rabies" per hit appended to the attack description, etc.

Now you go lookup: vorpal-furry-bunny and they define how they are different from "furry-bunny" which is defined how it's different from....

Nah, what you expect to see a complete description for pretty much every monster.  Now when you proceed to play out he combat do you make 10 photocopies of the bunny description?  Nope you jot down on a piece of paper the things that make each one unique (say its starting hit-points).  You refer to the book when you need the definition and the piece of paper to track the changing information.

Monsterz Emanuel in code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
/** One instance of this class per monster defination (entry in Emanuel)*/
public class MonsterDesc
{
  int maxHP;
  int ar;
  int dr;
  int exp;
  String desc;
}


An entry on the piece of paper in code:
1  
2  
3  
4  
5  
public class Monster
{
  MonsterDesc desc;  // what kind of monster am I?
  int  hp;
}


Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (5 views)
2014-10-25 15:46:29

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (45 views)
2014-10-16 15:22:06

Norakomi (34 views)
2014-10-16 15:20:20

lcass (38 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!