Passing a class that use a method as a member - c#

I've been learning C# for the past 6 months or so and am currently stuck on a turn-based battle system for a game.
I have tried a couple of different things and watched loads of videos about it but I didn't find what I was looking for. Maybe it's impossible but here it is. Also, I'm not looking for someone to write the code or anything, I am mainly looking for pointers.
switch (currentBattleState)
{
case (BattleState.WAIT):
{
if (heroesToManage.Count > 0)
currentBattleState = BattleState.ACTION_SELECT;
break;
}
case (BattleState.ACTION_SELECT):
{
foreach(Button button in buttons)
button.interactable = true;
break;
}
}
This is the current status of the battle state machine. I have two buttons at the moment, one that will attack and one that will open a spellbook to choose which spell to cast.
What I would need is something like this pseudocode:
void OnClicked()
{
ChooseSpell(); // If it's the "magic" button
ChooseTarget();
// And this Action will pass the target to the Attack() or Cast()
// function on the HeroStateMachine
listOfActions.Add(new Action(origin, target, Attack() or Cast())
}
and then when each Action is processed by the BattleStateMachine, like so, again in pseudocode because I have no idea how to do it:
void ProcessAction(Function action, int index = 0)
{
// This would result in Cast(origin, target) or Attack(origin, target)
action(listOfAction[index].origin, listOfAction[index].target);
}
// And then call it like this ?
ProcessAction(listOfActions[0].function)
we remove it from the list so, basically, this would be a first-in first-out type of thing.
The issue is that I haven't found a way to do that. So far, the videos I've watched are creating a derived class for every single type of attack, spell or item (all derived from a BaseAction)... Which I don't want to do since this seems like really wet code... Also, I wouldn't want to create a whole new class every time I want to add something to the game...
As I said, I'm not looking for full code but so far you've all been helpful so maybe just a pointer to what I could use to do what I want? Or just tell me if I'm approaching this whole thing from the wrong angle.

Related

C# Variable Scope Question, and Text-based RPG Attempt

I am trying to write a text-based RPG in C#. I am having issues understanding how I could make the character data accessible to many other objects in an effective manner.
I am fairly new to programming, and I certainly lack information. I've been reading guides and questions online and it got me so far, but I feel like I am either thinking about this the wrong way or missing something completely.
I am trying to write everything as flexible as possible since I am planning on adding a lot to this project if I can get past this stage. But it seems difficult for me to allow all of these objects to actively communicate with each other. Would using Unity help with this? I am mostly doing this to learn the language so I can later use it w/ Unity, but I wanted to learn the language directly so I opted out of starting with Unity. If there are any suggested resources to learn about the language I could really use recommendations.
I am sorry if the question is too open ended, but I can't really find anything regarding the mindset behind how I should be building a system like this. The last thing I've learned is ref but I feel like that isn't the best answer.
namespace GameMain
{
public class Game
{
static void Main()
{
MainMenu Game = new MainMenu();
Game.Menu();
return;
}
}
public class MainMenu
{
Character CurrentPlayer = new Character();
public void Menu()
{
Music MusicPlayer = new Music();
LocationEngine Location = new LocationEngine();
Tester Testman = new Tester();
MusicPlayer.Track("0");
while (true)
{
Menu:
Console.WriteLine("Welcome to the main menu. Enter 'create' to create a character and begin the game. Enter 'play' to log in.\r\nSaving features are to be implemented.\r\n");
while (true)
{
string MenuSelection = Console.ReadLine();
if (MenuSelection == "create")
{
CurrentPlayer.Creation();
goto Menu;
}
else if (MenuSelection == "play")
{
if (CurrentPlayer.CharacterPass != "")
{
Console.Write("\r\nEnter your password: ");
string Password = Console.ReadLine();
bool Check = CurrentPlayer.Login(Password);
if (Check == true)
{
Console.WriteLine("\r\nAdd transition to location here.");
break;
}
else
{
break;
}
}
else
{
Console.WriteLine("Please create a character first.\r\n");
break;
}
}
}
while (true)
{
Console.WriteLine("\r\nPress any key to continue.\r\n");
Console.ReadKey();
string TownSelection = "";
Console.WriteLine("\r\nYou are in Town.\r\n\r\nYou can 'explore' for encounters\r\nYou can use 'stats' to check your character\r\nOr you can 'sleep' to return to the main menu\r\n");
TownSelection = Console.ReadLine();
if (TownSelection == "sleep")
{
Console.WriteLine("");
break;
}
else if (TownSelection == "stats")
{
CurrentPlayer.CharacterStats();
}
}
}
}
}
}
I don't know how I can make the CurrentPlayer object accessible to the other objects such as Location. Is it better to pass every relevant bit as reference all the way down the rabbit hole?
I have posted the entire thing on github here if you are feeling extra patient: https://github.com/Slocknog/rpgproject
...and thank you for the help. Please do comment on anything else that you think I should be doing differently or reading up on.
I would take a step back and make sure you understand the purpose of each class you write. (This may sound patronizing, but it's really not trying to be. This is a difficult part of design.)
The purpose of each class should be clear and constrained: it should be reasonably obvious whether any piece of functionality belongs in a particular class or not, and no class should take on too much responsibility. I'd encourage you to write documentation comments on each class to explain its purpose - this will make it easier for you to come back and ask yourself whether some aspect of state and functionality really makes sense for that class.
Next, think about three ways data can be available to the class:
Through static variables. This is effectively global state, and is best restricted to natural constants. Global state should usually be immutable (unless it's something like a cache) as otherwise it can make testing and reasoning about your code fairly difficult.
Through instance variables. This is the state for an instance of the class (an object). It should be state that feels like it naturally belongs to an instance for its whole lifetime.
Through method parameters. This is information that is useful just for the duration of a single method call. For example, I don't think a LocationEngine should really know about the Character as part of global or instance state, but it might make sense to pass a Character reference into a method. (It might make more sense to pass a Location reference into the method, which might be obtained from a Character - it's hard to say without effectively trying to do a large portion of design for you.)
It's definitely worth putting significant thought into these decisions early on - although you should still expect to make mistakes. If you find yourself having to write code that feels ugly quite a lot of the time, in terms of how it accesses information, think about whether that information currently "lives" in the right place.
(Oh, and you're wise to separate "learning C#" from "learning Unity" in my view. Quite a lot of Unity uses idioms/techniques/conventions that would raise eyebrows in other C# codebases. Learning about them only when you move into Unity means you're less likely to carry them over to writing C# code elsewhere. Additionally, debugging "regular" C# code, particularly console applications, is somewhat simpler than having to worry about the Unity editor etc.)
you could have all those "other objects" Constructors accept a Character object to which you'll provide CurrentPlayer
supposing you have the following Character class
class Character
{
public string Name { get; set; }
}
then your LocationEngine class would be:
class LocationEngine
{
Character _player;
public LocationEngine(Character player)
{
_player = player;
}
public void SomeMethod()
{
string playerName = _player.Name;
}
}
and in your MainMenu class you'd code:
public class MainMenu
{
Character CurrentPlayer = new Character();
LocationEngine location = new LocationEngine(CurrentPlayer);
...
}

Checking a private value in another class [C#]

I'm making a simple dart game in the console for an assignment where I am to practice using private lists and variables everywhere. The basic flow of the program for some context is as follows:
User lands in a menu
User chooses from 1-4. (1 = Add player, 2 = Add CPU, 3 = Start game, 4 = Quit)
Game starts. Players manually add their 3 throws per turn, and CPU gets theirs randomly.
When a player or CPU reaches 301 score, the loop ends and you now see every throw made by the winner.
UML diagram for class structure context: https://i.imgur.com/bL5pZV5.png
Everything is pretty much complete. I've made the program to such an extent that both players and CPUs are getting random values (are treated as CPU players), it prints out everything correctly and follows the flow to the end.
My issue now is that I want to be able to reach the is_CPU variable which is private in the Player class from the Game class and use it in an IF check, directing whether or not the values are manually added or randomly generated.
Pseudo-code:
FOREACH (var player in player_list)
IF (is_CPU == TRUE)
THEN Assign random values
ELSE
THEN Manually enter values
I tried messing around with the get-set stuff, but I don't fully understand how to use them and how they work. I have looked around on here and still don't see how I should be using them in this case, if at all.
I can think of one way to work around this and that is by making a method just for this where it checks that value and returns true/false, but that seems like a 'lazy' or improper way to do this, and comes with several downsides. I feel like there should be a better way to do this, one that won't come back to bite me in the ass later. Hopefully there is, and I can learn it by asking here.
EDIT: The variables and lists HAVE to be private. It is part of the exercise where we learn how to handle these.
I think you just want a get property on your player class.
public bool IsCpu { get { return is_CPU; }}
See also c# properties
In order to access private members of a class instance, you either have to define properties on that class with a public getter, as follows:
public class Player
{
private Boolean m_IsCPU;
public Boolean IsCPU
{
get { return m_IsCPU; }
}
// ...
}
or to change these members in order to make them public, as follows:
public class Player
{
public Boolean IsCPU;
// ...
}
Whatever you choose (I suggest you to go for the first approach), in any part of your code in which you have to check the IsCPU property/member for each instance of the Player class, you can just do as follows:
foreach (Player player in players)
{
if (player.IsCPU)
// Do Something...
else
// Do Something Else...
}
Some interesting links:
Access Modifiers
C# Properties
Why prefer Properties to public variables?
Redesign your app like this:
Class Game
List<IPlayer> Players
ShowMenu()
AddPlayer()
StartGame()
IsGameOver(): boolean
Interface IPlayer
Turn() : Score
CpuPlayer: IPlayer
Player: IPlayer
Split your logic into two different classes: you dont need to check. Treat every player the same in the game. Later if you come up with 'NetworkPlayer', 'AIPlayer', 'SuperPlayer' you can easily add to your system.
In your menu:
switch (userInput) {
case AddUser:
AddPlayer(new Player());
break;
case AddCpuPlayer:
AddPlayer(new CpuPlayer());
break;
In your gameplay:
while (!IsGameOver)
{
var nextPlayer = ... next player
nextPlayer.Turn() ...
}

How to deal with two game modes in the same script?

If for instance I have a game which consists of just a single scene, and in that scene I make the user chose between the normal play mode or the tutorial play mode. The game has 4 different objects: a ball, 4 squares and a squarecontroller. In the tutorial mode i want to provide the user with a pointing arrow while pausing the game and continue after the user pressed the object being pointed at. Should I make a script for the normal mode and another one for the tutorial mode, make one script and check if a tutorial boolean is true or false in every function (boolean should be true if user pressed the tutorial button) or do some kind of preprocessing?
In the squarescript for example:
void OnCollisionEnter2D () {
if (isTutorial) {
PauseGame();
arrow.position = GetRelativePosition();
arrow.setActive(true);
} else {
if (canCollide) {
score++;
} else {
GameOver();
}
}
In the ballscript:
void OnMouseDown () {
if (!isTutorial) {
return;
}
ResumeGame();
}
We know nothing of your game so it's hard to answer. But as a rule of thumb: The less you have to type, the better. Also consider what will happen if you need to add new functionality to the game, will you have to go back and change tons in your code?
If so, you are most likely not writing good code.
As an attempt to give a concrete answer I'd say you should make an inheritance, create a class Level and make sub classes Tutorial and FreePlay or similar, that inherits from Level.
Then you can add all "general" functionality in the base class and the specific things goes in the sub classes
By structuring these behaviours inside if statements, it makes the code hard to understand and work with. Imagine what this will look like if you decide you want one of the squares to increase the players score AND show a tutorial arrow.
Split the behaviours into separate objects. For the square it could be something like a TutorialCollisionHandler, ScoreCollisionHandlerand HazardCollisionHandler. Then you can create different squares simply by changing which collision handlers are added to them, you don't even need to write any code!
Now depending on which mode the user picks, you can just use a different mix of squares. The same principle can be used with other tutorial or game specific behaviour.

Farseer 3.3 Checking if a non enabled body will collide if it were to be enabled (spawning)

I am using Farseer 3.3 and XNA.
I have a problem that i just cant solve in a nice way.
I have a situation where there is a world with bodys in it all working away doing there thing.
I then have an object thats body is set to not enabled, is there a nice way of checking if the body is currently colliding with anything? i.e. to know if it would be a clean spawn should I make it enabled and set it to dynamic?
Thanks in advance.
For anyone else finding this post while trying to solve the same kind of problem here is how I did it in the end.
In this example I use the word Item to represent the class that contains a body etc, this could be your player / bullet / whatever.
In your Item class subscribe to the bodies on collision and on separation events.
this.Body.OnCollision += Body_OnCollision;
this.Body.OnSeparation += Body_OnSeperation;
then setup a member for the item to hold a count of collisions and separations.
private int _canBePlacedCounter = 0;
On the event handler methods, increase of decrease the member count. In the code below there are extra conditions as for myself, I only want to perform these operations when an item is being placed into the "world".
private bool Body_OnCollision(Fixture fixturea, Fixture fixtureb, Contact contact)
{
if(this.IsBeingPlaced)
{
_canBePlacedCounter++;
}
return true;
}
private void Body_OnSeperation(Fixture fixturea, Fixture fixtureb)
{
if (this.IsBeingPlaced)
{
_canBePlacedCounter--;
}
}
We then can setup a simple public property (this really should be a method if we want to get into coding standards but this is not the time or place)
public bool CanBeDropped
{
get
{
if (_canBePlacedCounter == 0) return true;
else return false;
}
}
The reason for this implementation is, I originally had a bool which I set to true or false whenever I got one of the events. The problem is... If your item collides with item A, then collides with item B then leaves item A you get a reading of not colliding. So... using a counter like this we can count in and count out all of the collisions and separations. Belive me this works like an absolute charm.
Hope it is of use to someone out there.
UPDATE: I have found that this only works well with basic rectangles. If you get into bodies with many polygons such as those automatically generated from images its very unreliable as for whatever reason farseer regularly raises less separation events than it does collision events meaning the counter often does not return to 0.

Help on implementing how creatures and items interact in a computer role playing game

I am programming a simple role playing game (to learn and for fun) and I'm at the point where I'm trying to come up with a way for game objects to interact with each other. There are two things I am trying to avoid.
Creating a gigantic game object that can be anything and do everything
Complexity - so I am staying away from a component based design like you see here
So with those parameters in mind I need advice on a good way for game objects to perform actions on each other.
For example
Creatures (Characters, Monsters, NPCs) can perform actions on Creatures or Items (weapons, potions, traps, doors)
Items can perform actions on Creatures or Items as well. An example would be a trap going off when a character tries to open a chest
What I've come up with is a PerformAction method that can take Creatures or Items as parameters. Like this
PerformAction(Creature sourceC, Item sourceI, Creature targetC, Item targetI)
// this will usually end up with 2 null params since
// only 1 source and 1 target will be valid
Or should I do this instead?
PerformAction(Object source, Object target)
// cast to correct types and continue
Or is there a completely different way I should be thinking about this?
This is a "double dispatch" problem. In regular OO programming, you "dispatch" the operation of a virtual method call to the concrete type of the class implementing the object instance you call against. A client doesn't need to know the actual implementation type, it is simply making a method call against an abstract type description. That's "single dispatch".
Most OO languages don't implement anything but single-dispatch. Double-dispatch is when the operation that needs to be called depends on two different objects. The standard mechanism for implementing double dispatch in OO languages without direct double-dispatch support is the "Visitor" design pattern. See the link for how to use this pattern.
This sounds like a case for polymorphism. Instead of taking Item or Creature as an argument, make both of them derive (or implement) from ActionTarget or ActionSource. Let the implementation of Creature or Item determine which way to go from there.
You very rarely want to leave it so open by just taking Object. Even a little information is better than none.
You can try mixing the Command pattern with some clever use of interfaces to solve this:
// everything in the game (creature, item, hero, etc.) derives from this
public class Entity {}
// every action that can be performed derives from this
public abstract class Command
{
public abstract void Perform(Entity source, Entity target);
}
// these are the capabilities an entity may have. these are how the Commands
// interact with entities:
public interface IDamageable
{
void TakeDamage(int amount);
}
public interface IOpenable
{
void Open();
}
public interface IMoveable
{
void Move(int x, int y);
}
Then a derived Command downcasts to see if it can do what it needs to the target:
public class FireBallCommand : Command
{
public override void Perform(Entity source, Entity target)
{
// a fireball hurts the target and blows it back
var damageTarget = target as IDamageable;
if (damageTarget != null)
{
damageTarget.TakeDamage(234);
}
var moveTarget = target as IMoveable;
if (moveTarget != null)
{
moveTarget.Move(1, 1);
}
}
}
Note that:
A derived Entity only has to implement the capabilities that are appropriate for it.
The base Entity class doesn't have code for any capability. It's nice and simple.
Commands can gracefully do nothing if an entity is unaffected by it.
I think you're examining too small a part of the problem; how do you even determine the arguments to the PerformAction function in the first place? Something outside of the PerformAction function already knows (or somehow must find out) whether the action it wants to invoke requires a target or not, and how many targets, and which item or character it's operating upon. Crucially, some part of the code must decide what operation is taking place. You've omitted that from the post but I think that is the absolute most important aspect, because it's the action that determines the required arguments. And once you know those arguments, you know the form of the function or method to invoke.
Say a character has opened a chest, and a trap goes off. You presumably already have code which is an event handler for the chest being opened, and you can easily pass in the character that did it. You also presumably already ascertained that the object was a trapped chest. So you have the information you need already:
// pseudocode
function on_opened(Character opener)
{
this.triggerTrap(opener)
}
If you have a single Item class, the base implementation of triggerTrap will be empty, and you'll need to insert some sort of checks, eg. is_chest and is_trapped. If you have a derived Chest class, you'll probably just need is_trapped. But really, it's only as difficult as you make it.
Same goes for opening the chest in the first place: your input code will know who is acting (eg. the current player, or the current AI character), can determine what the target is (by finding an item under the mouse, or on the command line), and can determine the required action based on the input. It then simply becomes a case of looking up the right objects and calling the right method with those arguments.
item = get_object_under_cursor()
if item is not None:
if currently_held_item is not None:
player_use_item_on_other_item(currently_held_item, item)
else
player.use_item(item)
return
character = get_character_under_cursor()
if character is not None:
if character.is_friendly_to(player):
player.talk_to(character)
else
player.attack(character)
return
Keep it simple. :)
in the Zork model, each action one can do to an object is expressed as a method of that object, e.g.
door.Open()
monster.Attack()
something generic like PerformAction will end up being a big ball of mud...
What about having a method on your Actors (creatures, items) that Perform the action on a target(s). That way each item can act differently and you won't have one big massive method to deal with all the individual items/creatures.
example:
public abstract bool PerformAction(Object target); //returns if object is a valid target and action was performed
I've had a similar situation to this, although mine wasn't Role playing, but devices that sometimes had similar characteristics to other devices, but also some characteristics that are unique. The key is to use Interfaces to define a class of actions, such as ICanAttack and then implement the particular method on the objects. If you need common code to handle this across multiple objects and there's no clear way to derive one from the other then you simply use a utility class with a static method to do the implementation:
public interface ICanAttack { void Attack(Character attackee); }
public class Character { ... }
public class Warrior : Character, ICanAttack
{
public void Attack(Character attackee) { CharacterUtils.Attack(this, attackee); }
}
public static class CharacterUtils
{
public static void Attack(Character attacker, Character attackee) { ... }
}
Then if you have code that needs to determine whether a character can or can't do something:
public void Process(Character myCharacter)
{
...
ICanAttack attacker = null;
if ((attacker = (myCharacter as ICanAttack)) != null) attacker.Attack(anotherCharacter);
}
This way, you explicitly know what capabilities any particular type of character has, you get good code reuse, and the code is relatively self-documenting. The main drawback to this is that it is easy to end up with objects that implement a LOT of interfaces, depending on how complex your game is.
This might not be something that many would agree upon, but I'm not a team and it works for me (in most cases).
Instead of thinking of every Object as a collection of stuff, think of it as a collection of references to stuff. Basically, instead of one huge list of many
Object
- Position
- Legs
- [..n]
You would have something like this (with values stripped, leaving only relationships):
Whenever your player (or creature, or [..n]) wants to open a box, simply call
Player.Open(Something Target); //or
Creature.Open(Something Target); //or
[..n].Open(Something Target);
Where "Something" can be a set of rules, or just an integer which identifies the target (or even better, the target itself), if the target exists and indeed can be opened, open it.
All this can (quite) easily be implemented through a series of, say interfaces, like this:
interface IDraggable
{
void DragTo(
int X,
int Y
);
}
interface IDamageable
{
void Damage(
int A
);
}
With clever usage of these interfaces you might even ending up using stuff like delegates to make an abstraction between top-level
IDamageable
and the sub-level
IBurnable
Hope it helped :)
EDIT: This was embarassing, but it seems I hijacked #munificent's answer! I'm sorry #munificent! Anyway, look at his example if you want an actual example instead of an explanation of how the concept works.
EDIT 2: Oh crap. I just saw that you clearly stated you didn't want any of the stuff that was contained in the article you linked, which clearly is exactly the same as I have written about here! Disregard this answer if you like and sorry for it!

Categories

Resources