Effects?

In my game, I’ve gotten a lot of things figured out. At the moment, I’m working on making an “itemdrop” which will be something players can pick up. I think all of this works (untested, but coded), but the thing I’m not knowing how to do is… potion effects? I guess that’s the idea of what I’m trying to do. So for example, a player picks up an item… and gets a health boost for the duration specified by the itemdrop. In each itemdrop, I have a method called giveEffect(Creature collided).

	public void giveEffect(Creature collided)
	{
		//do effect here
		
	}

and I have a length set by default for 10 seconds. So, for example, if I wanted to double the damage of a person’s weapon, I know how to do this… but not for like a certain amount of time only.

Should I make an Effect object, and in each creature, give it a list to hold that effect, loop through them every frame, and apply it. Then when the time runs out, remove it from the list? That’s my only thought, but before I go and spend a little making it, I just didn’t know if there was another good way to do this.

Thanks in advance :slight_smile:

Here is a simple time keeper

public class TimeKeeper {

	private long cachedTime;

	public TimeKeeper() {
		reset();
	}

	public void reset() {
		cachedTime = System.currentTimeMillis();
	}

	public long elapsed() {
		return System.currentTimeMillis() - cachedTime;
	}
	
}

To use:


final TimeKeeper timer = new TimeKeeper();
if (timer.elapsed() > 1000) {
      update();
      timer.reset();
}

Thanks for that, but it’s not really what I’m asking. I know how to keep track of time, but it’s more so when a player runs into an item, the item is removed, but the player has something for a certain amount of time.

I would do exactly as you said.

All creatures can have a list with effects, every tick (or render frame) loop through them all, apply the effect, reduce the timer on the effect, if the effect is out of time remove it from the list.

Even Minecraft does this. You don’t need to be too creative with the simple things.

In your game loop : player.checkEffects();

In the Player class, have an ArrayList of active Effects
public void checkEffects() {
for (Effect e : effects) {
e.update();
}
checkForExpiredEffects();
}

The Effect class has a lengthOfTime, and a timeLeft.


public class Effect {
    private int lengthOfTime;
    private int timeLeft;
    private boolean expired = false;

      //it also has an update() method.
   public void update() {
      if (timer.elapsed() > 1000) {
         setTimeLeft(getTimeLeft - 1);
         if (getTimeLeft() <= 0) {
            setExpired(true);
         }
         timer.reset();
      }
   }
}

In the Player class


public void checkForExpiredEffects() {
    for (int i = 0; i < effects.size(); i++) {
         Effect e = effects.get(i);
         if (e.getExpired()) {
             effects.remove(e);
         }
    }
}

Rather than making Effects player-only, make them apply only to entities with health.

Instead of doing two loops (one for effects working and another for removing), just loop through the effects list backwards.


for(int i = effects.size - 1; i <= 0; i--){
   effects.act();
   if(effects.isExpired()){ // check if it's done, this implementation is up to you as you stated that you know how to do this
      effects.remove(i);
   }
}

Looping through the array backwards prevents errors when the array shifts while looping.

Thanks for correcting me, I wrote this all in the reply box and thought of it on the spot, I didn’t test it haha

Shouldn’t it be:


for(int i = effects.size - 1; i >= 0; i--){
   if(effects.isExpired()){ // check if it's done, this implementation is up to you as you stated that you know how to do this
      effects.remove(i);
   } else {
      effects.act();
   }
}

EDIT: Updated with Jesse’s observation below.

Other issues aside, it also looks like the conditional should be >= rather than <=:

for(int i = effects.size - 1; i >= 0; i--){

Okie. thanks for all the help and advice. I just got my wisdom teeth out, so once I’m at a point where I feel like I can program, I’ll try it out :D. On another note, I was running into an issue with finding a good texture. I don’t have photoshop, and I just wanted to get premade images that aren’t a full rectangle, but like everything other than the actual image (like a coin) is see through. I think you can do tthis in photoshop, but I didn’t know if there was an easier way to do this.

You can do that in pretty much any image editor I’ve ever used. What you’re modifying is called the ‘alpha channel’, which basically represents the ‘transparency’ of a pixel (in very high level terms). You could think about it as the lack of anything at the pixel position. What you do in most programs is select the area and then hit the ‘Delete’ key, that should take care of it. I can’t remember what graphics library you’re using, but I believe most have alpha blending on by default, so you should just be able to load up your image and go!

I’m just using paint cause yolo, but I know gimp is an option… but i don’t really like it.

Have you tried paint.NET? It might change your mind. ;D