Reusable IceCream Utilities and Components

Since the IceCream library seems to be somewhat abandoned (though they graciously committed an XNA4-compatible version) I’ve created my own private repository for my own changes and fixes. If I continue to add-on, I’ll contact the original authors and see if they want the changes to be official or what, but for now I’m keeping it private so the authors don’t feel like I’m trying to take credit for their great work. (It really is great stuff.)

Anyway, one of the first things I did was add a Utility directory and drop in IceTimer, which is a rip of timer code in Advanced 2D Game Development (a great book!, though written for C++ programmers). I’ve used it in previous game demos with great success. Here’s the code for IceCream:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>
/// To use, instantiate new IceTimer(). Then call Stopwatch() with ms intervals. It will auto-reset, so
/// just call/monitor return value of Stopwatch().
/// </summary>
public class IceTimer
{
	public IceTimer() {
		timer_start = TimeGetTime();
		Reset();
	}
 
	private long TimeGetTime() {
		return DateTime.Now.Ticks / 10000; //convert ticks to milliseconds. 10,000 ticks in 1 millisecond.
	}
 
	public long GetTimer() {
		return (long)(TimeGetTime());
	}
 
	public long GetStartTimeMillis() {
		return (long)(TimeGetTime() - timer_start);
	}
 
	public void Sleep(int ms) {
		long start = GetTimer();
		while (start + ms > GetTimer()) { }
	}
 
	public void Reset() {
		stopwatch_start = GetTimer();
	}
 
	public bool Stopwatch(int ms) {
		if (TimeGetTime() > stopwatch_start + ms) {
			Reset();
			return true;
		}
		else
			return false;
	}
 
	long timer_start;
	long stopwatch_start;
}

All you have to do is instantiate it and then call something like:

1
if (myTimer.Stopwatch(1000)) { /* this code will fire once every second */ }

Next up, a couple highly reusable components. In fact, I was surprised their functionality wasn’t already built-in to the IceCream framework. Maybe it is and I missed it? Anyway, here’s a component to destroy a scene item after a user-provided number of seconds (useful for, say, bullets flying off-screen that you don’t want to zoom into infinity).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[IceComponentAttribute("LifeComponent")]
public class LifeComponent : IceComponent
{
	[IceComponentProperty("Life in Seconds")]
	public int LifeInSeconds { get; set; }
 
	public LifeComponent() {
	}
	public override void CopyValuesTo(object target) {
		base.CopyValuesTo(target);
		if (target is LifeComponent) {
			LifeComponent targetCom = target as LifeComponent;
			targetCom.LifeInSeconds = this.LifeInSeconds;
		}
	}
	public override void OnRegister() {
		Enabled = true;
		LifeTimer = new IceTimer();
	}
 
	public override void Update(float elapsedTime) {
		if (LifeTimer.Stopwatch(LifeInSeconds * 1000))
			this.Owner.MarkForDelete = true;
	}
 
	private IceTimer LifeTimer;
}

And here’s another for moving a SceneItem given an X and Y velocity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[IceComponentAttribute("VelocityComponent")]
public class VelocityComponent : IceComponent
{
	[IceComponentProperty("Velocity Vector")]
	public Vector2 Velocity { get; set; }
 
	public VelocityComponent() {
	}
	public override void OnRegister() {
		Enabled = true;
	}
 
	public override void CopyValuesTo(object target) {
		base.CopyValuesTo(target);
		if (target is VelocityComponent) {
			VelocityComponent targetCom = target as VelocityComponent;
			targetCom.Velocity = this.Velocity;
		}
	}
 
	public override void Update(float elapsedTime) {
		this.Owner.PositionX += Velocity.X;
		this.Owner.PositionY += Velocity.Y;
	}
}

Let me know if you use these! So far I think most of my objects will be having these components.

Leave a Reply

Your email address will not be published. Required fields are marked *