• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Interface and using Polymorphism (I think?) -- Game I'm making and need help.

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This post relates to this one: https://coderanch.com/t/617207/java/java/Long-list-statements (I mostly figured out and took the suggestions there but now I have another issue that is a bit different)

I've been making a game for fun/practice where the player moves around a 2-d array 'board' and encounters different spaces on that board.

I have an interface:



Various creatures (and events) implement that interface:



etc.

I then fill my board with the creatures/events:



Each creature has a doAction method, so depending on what space the player is currently on (this is controlled by other classes/methods) something happens:



I have my 'player' object contained in the same Class (encounter class) as where 'whatHappens = spaces[row][column].doAction(row, column);' takes place.

To make the code cleaner I'd like to be able to doAction() and have it effect the player object in the encounter class. However, I'm not sure how to do this. Right now doAction in a particular creature class just returns that creature to the encounter class where combat or talking or whatever happens. This causes the encounter class to be really crammed full of code and is a list kind of like this:



Is there a way to do something to the player object from within one of the creature classes? There is no player object present in the creature classes so I can do something like encounter.player.giveRope(); from there. Since I return a creature object when I doAction() I thought I might be able to get information about that object using an accessor. So, for example, if doAction(int row, int column) is in a creature class and row = something and column = something I set some attribute of that creature to lets say '1' whereas by default the vaule is 0. Then, in the encounter class I could do something like (remember whatHappens is the creature type) int thing = whatHappens.getAttribute(). Then use thing to go on and do stuff using other methods without having such a laundry list of if/else if statements. But I couldn't seem to get this to work? I was only able to whatHappens.getClass() and break it up that way. It seemed only attributes of the Super Class would be returned, not attributes of the specific Sub Class .

I hope my question makes sense...I tried not to leave out too many details while still making is mildly succinct. Still new to Java and learning my way around, trying to get these polymorphism ideas down. I appreciate any help or let me know if more details are needed.

TLDR: I have Class A. Class B holds an object of Class A. I have Classes that implement an interface. There is an array of interface objects in Class B. Can I (within the classes that implement the interface) do things to Class A?








 
Bartender
Posts: 5465
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Hans,

Most important thing to start with: do you know exactly WHAT your game is about? For instance,
if your player lands on some space, and there is a Creature there, do you know exaclt what should
happen? In all situations? Does what happens depend on say the state of the player, the specific Creature
that is on that space, and does the action of that Creature depend on what space it is? Just a few
questions...

Maybe it's best to give you some examples of what is possible. Chances are your game will be completely
different, but I hope you get some ideas.

Suppose that we have a player, like:


Now suppose we have the Creature interface, with this doAction. Let's create a Creature_Goblin:


and we have the class Bomb:


Hope tihs helps.
 
Hans Hovan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the post Piet,

Yeah I know what my game is about and what is supposed to happen on each space in all situations. I do have it set up a similar way to the examples you gave. My big problem is how I can have my creature interface do something to the player. For example, under your Creature_Goblin you have 'player.setHealth(player.health - 0.1);' but how can I do anything to the player object this way since there is no player object here? I'd get a compiler error that the variable player symbol cannot be found.

As it is right now I have have an 'encounter' class that holds the player object as well as the array of creature interface spaces. I can do things to the player from the encounter class but is there a way to do things to the player from the creature classes, like player.setHealth(player.health - 0.1);.

Thanks for the help.
 
Piet Souris
Bartender
Posts: 5465
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Hans,

the easiest thing you could do is to incorporate a Player variable in the interface's doAction, like in:


This would have the advantage that it allows you to have more than one player acting.
If you put your classes in the same package, there should be no problem.

Another solution could be to define your Creatures as


But probably many other solutions are possible. If the above isn't suitable, could you then
give me an overview of your classes, what innerclasses they contain and whether they are
in the same package? Just a description would do.

Greetz,
Piet

 
Hans Hovan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes all of the classes are in the same package (assuming I correctly understand what a package is -- they are all in the same folder).

A quick breakdown:

The Play class contains the main method and handles the player's movement around the board (spaces). The play class contains an Encounter object and the space that the player is on is passed into the encounter object's room method (think of room as meaning a space on the board):



In the encounter class is an instance of PlayerCharacter. The PlayerCharacter class has a bunch of attributes associated with it like health, damage, defense, etc. The encounter class also has the method room that takes in the row and column arguments and uses them to determine what space is encountered:



As seen in my earlier post, this then creates a long if/else if chain in the room method if I want to do something specific to the player like say give the player a weapon that makes them do more damage if they are on row 3 and column 2. What I want to do is give the player a weapon FROM the .doAction method of one of the creature types. So, in the Creature_Goblin class I'd have: if (conditions are met -- like player wins the battle!) player.giveWeapon() or something like that. But Creature_Goblin has no access to the PlayerCharacter object that is in the encounter class. The PlayerCharacter has to be constant, I cannot just create new PlayerCharacter objects (or maybe I can and I just don't know what I'm doing?) because I have to do things like add or subtract health which doesn't make sense if my health keeps getting set to the constructor default.

Maybe I'm just missing something conceptually.

In your example of incorporating a PlayerCharacter variable, say if I had spaces[row][column].doAction(row, column, player) and in the interface had doAction(int row, int column, PlayerCharacter player), if I did something like player.giveWeapon() would it give the PlayerCharacter object stored back in the encounter class a sword (so in the encounter class I could have player.hasSword == true) or only give a sword to the player existing within the interface doAction?

I hope all of that makes sense. Thanks for sticking with me. I'm still fairly novice and just trying to grasp how it all works.

Thanks again for your help.
 
Piet Souris
Bartender
Posts: 5465
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Hans,

I was asking about the structure, because I wanted to know the 'visability' of your Player class (or 'PlayerCharacter'
as you call it). The easiest way to let all of your classes know about the existence of the 'PlayerCharacter' class
is to put that class in a separate file inside your package, that is indeed the folder in which you have all
your classes. In that case you can define the interface 'Creature' safely with a reference to a 'PlayerCharacter'.

I understand this: you have a 'Play' class, and an 'Encounter' class, and by the look of it, it is an instance of the 'Encounter'
class that does the actual game:


and where 'spaces' is the actual board in use.

Please correct me if I'm wrong.

My idea was to define the board as:



And then populate this array in your initializer method, something like:

And what specific Creature this _XXX would be, well, that's up to you to decide that,
maybe based on some formula that picks a specific Creature at random from the
available Creatures that you have defined.

Now, the whole idea is that if your player lands on some space, say spaces[2, 3],
that this space, being some Creature, knows what to do! You do not need to know
what specific Creature that might be, the Creature itself knows it, and that's enough!

How does this work? Because each Creature, be it 'Creature_XXX' or 'Creature_YYY',
has a method 'doAction(PlayerCharacter player) {...}' that exactly defines what
should happen to the player in this method.

So, suppose we have two players, 'Hans' and 'Piet', playing your game in a turn based
fashion (yes, two players!). It's Hans'turn and he lands on spaces[2, 3].
Since spaces[2][3] is a Creature, it knows what to do, it has a method 'doAction', and
so we call:



and since Hans is lucky, he gets a sword. You, see, there is no need to retrieve what kind of
creature is located on spaces[2, 3].

Now it's Piets turn. The dice are cast, and he lands on spaces[4,5].
Here we go again:


You see, no long if's and else's.

Now look at your lines 09 and 10 of the 'Encouter' class.


The right hand part is okay, you call the 'doAction' methode of
whatever Creature populates that space. But there is no need to retrieve
that Creature.

Now, with this in mind, a possible set up of the game might be:



As said, this is just an example of what is possible. But I hope that the idea of using 'interfaced'
Creatures is clear, and how you could act the 'doAction' on this player.

Greetings,
Piet
 
Hans Hovan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Piet, thank you so much for all of your responses and examples. It has finally all clicked and that was extremely useful as far as my understanding of what is possible and how everything can work together. Again, thank you!
 
Piet Souris
Bartender
Posts: 5465
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome, Hans.

Please show us your game when you're ready!
reply
    Bookmark Topic Watch Topic
  • New Topic