Increase enemies attributes when round finishes

I am very much a proponent of good software practices. I’ve seen the result of not adhering to these things and how much effort it not only takes to correct it, but to change people’s minds in order to bring them around to understanding that good design principles actually do make things easier in the long run.

Having said that, no matter what environment you’re in, having something working is better than delivering nothing because you couldn’t get it “perfect”. Software (and humanity, I think) is all about iteration and learning. So I absolutely agree that it makes no sense trying to let yourself get bogged down in trying to follow the best practices and design principles, to the point where you get nothing done.

This applies to everything, really. I can’t tell you how many projects in my younger days got bogged down because I spent too much time trying to figure out the most optimized and perfect approach to something. Now I just do it however and fix it later if I have to. The upside is that I’ve learned those good software principles, so changing out a component because my initial implementation doesn’t fit my requirements anymore is super easy :wink:

1 Like

What´s your opinion on my Player classes? I think they are useless

First of all I agree to all of what you say! :slight_smile:

Yes but what is the distinctions of good practices… Today we kan say its “this” but yesterday is was “that” and tomorrow it will be someting else.

I would say that code not adhering to a good structure is a coder that probably dint understand the problem very well but deffently dint spend enough time to think/create a solution.

I think about it like this: In no other field of since do we expect the correct solution to be the first one. We have to experiment och test results. But most code i read (the ones “not adhering to a good structure”) looks more like this was the first thing that worked not the best solution for the problem.

As I’m thinking about problems today structure and other people’s practices do not concern me what is concerning me is the problem and how it effects the big picture. This becomes my “practice” and as you say my learning process.

Maybe all the practices today are the best thay will ever be and we should just learn those. I doubt it but even so, for me coding is like discovery. I want to experience why somting is right or wrong for my self.

Edit
Ps. Sorry if I’m hijacking the tread here but @Fabio_Pires this is someting you should be thinking about alot. Especially if you are to join your peers and build a career of this after school.

Your hierarchy is confusing and hard to follow. You have too many classes that do the same thing. I personally would try and separate your logic into a sinlge class for the player and classes for your enemies inheriting from one base class. Your TA is going to feel similarly and it will hurt your end mark.

When I have Update methods I always pass in a GameTime parameter because it is so useful. You might want to consider doing that.

I am trying to reduce the amount of globals variables in my project but I am having a little trouble. With lists if I do listA=listB they will share the same memory position. How can I do this with int?

In my main I got this

gameplay = new Gameplay( gameState, score, totalMonstersKilled);

And then in my Gameplay I pass that variavle to world

 public class Gameplay
    {
        protected int playState;
        protected World world;
        protected int gameState;
        protected int score;
        protected int totalMonstersKilled;
        

        public Gameplay(int _gameState,int _score,int _totalMonstersKilled)
        {
            playState = 0;
            score = _score;
            totalMonstersKilled = _totalMonstersKilled;
            gameState = _gameState;
            ResetWorld(null);
            
        }

        public virtual void Update()
        {
            if (playState == 0)
            {
                world.Update();
            }

        }

        public virtual void ResetWorld(object _info)
        {

            world = new World(ResetWorld,gameState,score,totalMonstersKilled);
        }
        public virtual void Draw()
        {
            if (playState == 0)
            {
                world.Draw();
            }
        }
    }

but when I update the value of gameState in world it doesn´t update in Main

 if (roundKills == 10 + 5 * GameGlobals.currentRound)
                {
                    gameState = 2;
                    roundKills = 0;
                }

It’s ok to hang some information off a class, just pass it in as a dependency if you don’t want to use a global.

(You can pass a ref int, but I wouldn’t advise it)

how do I pass as a depency withou passing the reference?

You need to understand the difference between value types and reference types. An int is a value type and a List is a reference types. When you set one value variable to another value variable you are overwriting the value. When you assign a reference variable to another you are pointing it at that instance. If you need to share an int between instances then you would have to use a pointer to an int instead of an int. This is a bad design idea and you should rethink what you are trying to achieve.

So in this case I should stick with the global variable?

1 Like

Globals are entirely evil if used sparingly. You can get around globals by using ref as follows. Either case has its advantages and disadvantages.

public void MethodA(ref int parameter)
{
    // do something
    parameter /= 7;
}

public void MethodB()
{
    int myVariable = 42;
    MethodA(ref myVariable);
}

is there any difference between a global variable and a static one?

I mean putting it on a class. Something like this…

public interface IScoreable
{
  int BaseScore { get; }
}

public class ScoreManager
{
  public float CurrentScore { get; } = 0;
  public void AddScore(float score)
  {
    this.CurrentScore += score;
  }
}

public class ScoreInfo
{
  public int Level { get; set; } = 1;
  public float ScoreModifier { get; set; } = 1.0;

  public float CalculateScore(IScoreable scoreable)
  {
    return scoreable.BaseScore * this.Level * this.ScoreModifier;
  }
}

...

public class Spider : Enemy, IScoreable
{
  private ScoreManager _scoreManager = null;
  private ScoreInfo _scoreInfo = null;

  public int BaseScore => 15;

  public Spider(ScoreManager scoreManager, ScoreInfo scoreInfo)
  {
    _scoreManager = scoreManager ?? throw new ArgumentNullException();
    _scoreInfo = scoreInfo ?? throw new ArgumentNullException();
  }
  
  public void Kill()
  {
    _scoreManager.AddScore(_scoreInfo.CalculateScore(this));
  }
}

Now when you create your spider, you can give it an instance of ScoreInfo and ScoreManager. When it gets killed, instead of doing the work itself, it asks those objects to handle updating the score.

Be careful with internet advice on programming, think about the different ways you could do something and decide for yourself which is better.

Why get rid of globals (statics) if you are just going to have to pass the variables into every function?

Does having a player class really make your code easier to read?

Inheritance always seems like a trap to me because if you have a fast enemy and a big enemy that inherit from an enemy base class then what do you do when you want a fast AND big enemy?

There’s so much disagreement about how to program that I think the best thing to do is to take the advice and try it out and decide for yourself what you like. Though you will also want to look at how your teachers want you to do it.

Globals couple you tightly to that implementation, and now for your code to run, it has to be there. If you want to reuse that component elsewhere, in another part of your game or in another game entirely, you also have to recreate the global. Additionally, it’s not always obvious that the code in question depends on that global… especially if you use a lot of different ones. When you use dependency injection, it’s generally much more clear where your data is coming from, local to the object using it.

This is a great question! Inheritance can definitely lead you down the wrong path. It’s extremely useful if you want to have common code between multiple objects, but it definitely should be used with caution. A more flexible approach is to prefer composition… build your object out of several different dependencies. In the case you suggest, where you want an enemy that is both fast and big, pass in behaviours that control an enemy, or manipulate its data in the ways that you want. Now you want an enemy that can fly? Pass in another behaviour that adds flying.

For the most part, I absolutely agree! Programming, at it’s core, is a creative process. There is freedom in how things are assembled and, at the end of the day, the most important thing is that it functions correctly. It’s important to take a look at all of the different styles people use and think critically about them. What advantages do they bring, what disadvantages? How will they impact your project?

On the other hand, and please keep in mind that I’m not talking about you specifically here, programmers are fundamentally lazy. I’ve seen way too many developers reject these newer practices and methodologies because they don’t know them, or they’re not what they’re used to. It’s not easy to change your approach to software development and time and again I see people resist good design practices because of the additional time and effort it takes to either learn, or to implement. I’m not innocent of this either… the first time someone came to me and said, “Hey, SOLID principles are going to generate far more stable and maintainable code, we’re going to use them now.” I was like, “But why? My code works great!” Here’s the big secret… my code was full of maintenance issues and once I got really honest with myself, I just didn’t want to effectively relearn how to code.

It’s a fine line to walk. There’s sooooo many different approaches out there that it can be overwhelming to consider them all, but it’s also extremely easy to fall into a trap of putting the blinders on and thinking you don’t need need to change anything because “that’s how we’ve always done it!”

:slight_smile:

2 Likes