Score being triggered/changed

So, I’m jut wondering about something.

I know there are different ways to do diffferent things when programming, and I know there isn’t a “right” or “wrong” way to do things also.

I’ve been going through my game, and understanding a lot of things that I need to change, mainly to be more “object-oriented”.

Before, I was checking the score all through the level, and at the same time I checked if an enemy had 0 or less health, and what to do pretty much. So… remove from arraylist… clear screen if game is over… add score based on what is killed… ya.

My new idea was for each creature to detect if it is alive, and if it died, remove it from the arraylist through itself (being a creature).

So, my question is, if I want to keep track of the score of an individual player, and I want to do this through the player (map), would it be good practice to keep track of health/creatures dying/adding score to the player all within the level?

Here’s an example:

Level - creates all objects, draws all objects, checks for triggers to end the game (player dying).

Each Creature other than Player and other triggers - Checks if alive when being drawn, and if alive is drawn, otherwise is removed from arraylist.

At the moment I’m checking the helath for every creature through the level, but I’m just wondering if it’s good or bad practice to do everything through the level or through each object.

Again, the situation I’m referring to is this.

Player shoots enemy, enemy dies. What is the better way (better practice) to then add score to the player based on what score value that creature had.

There is no better way, as you seem to know, but your question has a very simple solution. Store a “score value” field in the enemy class and when the enemy dies, increment the score field that is stored in the player class by the “score value” which is in the enemy class.

I feel like I don’t entirely understand your question, though, or that I missed something. Is what you were asking?

So in a way yes that is my question, but also no at the same time.

I thought of doing that, but my whole goal here is to keep each thing separated from another object. I just came up with the idea that whenever a weapon/bullet does damage to the enemy so that it kills it, I could then add the score to the creature. I feel like I’m asking a question without giving all the info, but I just didn’t know if there was a better practice to deal with certain situations.

So like if I have a player shoot an enemy, and the bullet is what is dealing the damage to the enemy, what would be best to keep track of the score? I don’t know if that makes sense, but if every bullet is linked with a creature, then I guess the bullet is what should add a score to that given creature. The player, in this case, is the creature. Lol I guess I figured my own issue out just by writing all of this out, but the whole thing I’m in the process of understanding is how to keep a game entirely object oriented.

To a point, object orientated programming is great. But only when used correctly, you don’t want to fall down the hole of making everything an object and creating a complex web of objects and which ones interact with which and this one can’t interact with that one and this one has this field while this one doesn’t etc…

Your bullet definitely could add a “score” to the enemy in question, however I would keep the bullet as “dumb” as possible. It’s simply a vessel of destruction; therefore it should only keep track of it’s position, damage modifier, and maybe a state (currently in flight, hit a player etc…).

The player class should be “smarter”, it will react to the bullet when it is hit and then it will add the score. The bullet should have nothing to do with the score, it’s a dumb object. The enemy is the smarter object and should perform the logic. If that makes sense at all, I’m struggling to turn my ideas into words right now for some reason :confused:

That’s actually exactly what my question was.

So, you’re saying All the bullet should do is hit something and deal damage.

But, if I did this, I’m struggling to know how I could have the player check if it killed something… unless I ran through a check every time it drew checking like a “killer” variable in every creature, and seeing if it’s the player.

Would this be a time to use events? Cause I’m a scrub with them, and if it is I could really use some advice there.

As of right now I was going to make the bullet really smart, so it’s a good thing I stopped to figure this out.

Personally for your bullet, I’d simply set a variable called ‘parent’ inside the bullet class that allows you to check who fired it. Might be better ways but this seems easy enough. I know this goes against what opiop65 said though D: but it doesn’t seem that you’re over-complicating things with this variable.

EDIT: Though I do stress that this logic can be done inside of the enemy/a handler. You can simply check if a bullet hits, find out who fired it and then set the score accordingly

That’s how I was going to do it, but I really feel like there’s a better way to do this within player/the creature.

I’m currently changing my code to have a weapon and attack with that instead of always having a bullet, but whatever the attack may be, that’s what will do damage.

Same concept will be here, but I don’t know if there’s a better way to do it through the player/creature.


public class Enemy{

int health = 100;
int pointsToGive = 5;

    public void takeDamage(Bullet bullet){
        health -= bullet.damage;
        if (health <= 0){
               bullet.parent.takePoints(pointsToGive);
               removeMeFromList();
        }
    }
}

public class Bullet{

      int damage = 10;
      Player parent;

      public void checkForCollisions(){
             for (int i =0; i < enemiesList.size(); i++){
                   if (thisCollides.with(enemiesList.get(i)){
                         enemiesList.get(i).takeDamage(damage);
                   }
             }
      }
}


public class Player{

    int points = 0;

    public void takePoints(int amount){
           points += amount;
    }
}

Just one of many examples I could write up, but it sounds like you wanted something similar to this.

As I was getting lunch a moment ago I thought of doing it like this, and funny enough you were able to give a similar answer to what I thought of. Thanks, this helps solve my issue.

Having a object which represents the “owner” of the bullet isn’t complicating things at all, so long as you keep it simple and don’t try to do much logic within the actual bullet class.

The way I see it, the bullet is simple and “dumb” because it exists for a couple seconds at most, and it’s only purpose is to convey damage. As such, it should only contain the necessary fields to alert the shooter, and the victim how much damage they dealt/took, and, like others suggested, which player actually made the shot. The bullet is only responsible for passing these fields along to the end objects, not for actually modifying the enemy’s health.

But, that’s just my take on it and there are plenty of other ways to do it!

Yep, I completely understand what you’re saying now. Thank you for the help, as I think I get yet another component of how object oriented programming should work in games.

No problem, just remember KISS and you’ll be fine! :wink:

:-* but seriously, KISS? O.O I feel like I should know that

Keep It Simple Stupid!

Go ham on Object Oriented Programming all you want now while you’re learning, but realize you’ll have to ‘un-learn’ a good bit later, or at least develop judgment as to when to ease off.

‘Simple’ and ‘OOP’ are often at odds: http://www.infoq.com/presentations/Simple-Made-Easy
(one of my favorite talks, maybe I should just put it in my sig by now…)

Quick observation on how to decouple (read: simplify) Soul Foam’s example, keep in mind technique like this, not everything has to or should be chains of (stateful!) method calls:

-public class Enemy{
+public class Enitity { // everything is built on one common base for uniformity later
    int health = 100;
    int worth = 5;

-    public void takeDamage(Bullet bullet){ // why should entity know anything about all the surrounding machinery?
-        health -= bullet.damage;
-        if (health <= 0){
-               bullet.parent.takePoints(pointsToGive);
-               removeMeFromList();
-        }
-    }

+    Runnable onDeath = DEFAULT_ONDEATH; // whatever action is common to all entities without custom behavior
                                         // perhaps a bit much in this example, but consider being able to 
                                         // customize behavior (even on the fly!) without having to subclass.
}

-public class Player{
+public class Player extends Entity { // could also use component system or others means of overkill for this example

    int points = 0; // 'points' in this case is a Player-specific thing that specialized Entity

-    public void takePoints(int amount){
-           points += amount;
-    }

+    onDeath = PLAYER_DEATH; // stops the game, shows 'You Died' etc.
}

public class Bullet { // bullets could also potentially be Entities, but that may complicate collision detection


      // again, specializations
      int damage = 10;
      Player parent;

-      public void checkForCollisions(){ // again, let's try to do this in a bit more data driven way...
-             for (int i =0; i < enemiesList.size(); i++){
-                   if (thisCollides.with(enemiesList.get(i)){
-                         enemiesList.get(i).takeDamage(damage);
-                   }
-             }
-      }
}

// finally:

// in game loop, or some kind of 'update()' or 'processEntities()' method called from the game loop:

// since we're not using a component architecture and we have bullet specific computations, we have a separate bullet list
for bullet in bullets {
    // or loop if multiple entities should be able to be hit by the same bullet for the bullet dies
    Entity target = getFirstEntityCollidingWith(bullet); // not going to mention method of collision detection
    if (target != null) {
        entity.health -= bullet.damage;
        // annoying, probably more elegant way of doing this, could even be a killedBy field
        // used in onDeath in Entity if killing/scoring should be so general
        if (entity.health <= 0) {
             bullet.parent.points += entity.worth;
        }
        remove(bullet); // also not ruling how this is done
        // that's it!
    }
}

// now on to general things:
for entity in entities {
    if (entity.health <= 0) {
        remove(entity); // again, figure this out elsewhere
        entity.onDeath.run();
    }
}


// notice now that all those classes are pure data and easy to reason about.
// also there's no weird inversion of control flip-flopping around all over the place in classes
// that have no business working directly with other classes.
// instead everything is handled uniformly by the controlling layer above in the game loop.
// the puppets do not chose to interact with each other, the puppet master directs the show.

If you wanted to go farther here if actions on collision events are common, instead of that bullet-specific loop you could have a collidedWith(Enitity) field-method similar to onDeath.