Skip to content

Commit e250a45

Browse files
Merge pull request #7 from jacuzzicoding/feature-daynight
Feature - day/night
2 parents 3082e29 + b3d320d commit e250a45

File tree

16 files changed

+1222
-33
lines changed

16 files changed

+1222
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ msbuild.wrn
3939
!.vscode/launch.json
4040
!.vscode/extensions.json
4141
obj/Debug/net8.0/MyIslandGame.AssemblyInfo.cs
42+
States/PlayingState.cs.bak

Content/Content.mgcb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@
1313

1414
#---------------------------------- Content ---------------------------------#
1515

16+
#begin Fonts/DebugFont.spritefont
17+
/importer:FontDescriptionImporter
18+
/processor:FontDescriptionProcessor
19+
/processorParam:PremultiplyAlpha=True
20+
/processorParam:TextureFormat=Compressed
21+
/build:Fonts/DebugFont.spritefont
22+

Content/Fonts/DebugFont.spritefont

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
3+
<Asset Type="Graphics:FontDescription">
4+
<FontName>Arial</FontName>
5+
<Size>12</Size>
6+
<Spacing>0</Spacing>
7+
<UseKerning>true</UseKerning>
8+
<Style>Regular</Style>
9+
<CharacterRegions>
10+
<CharacterRegion>
11+
<Start>&#32;</Start>
12+
<End>&#126;</End>
13+
</CharacterRegion>
14+
</CharacterRegions>
15+
</Asset>
16+
</XnaContent>

Game1.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Game1 : Game
1010
private GraphicsDeviceManager _graphics;
1111
private SpriteBatch _spriteBatch;
1212
private GameStateManager _stateManager;
13+
private TimeManager _timeManager; // Add TimeManager field
1314

1415
public Game1()
1516
{
@@ -27,6 +28,9 @@ protected override void Initialize()
2728
// Create the state manager
2829
_stateManager = new GameStateManager(this);
2930

31+
// Initialize TimeManager
32+
_timeManager = new TimeManager();
33+
3034
base.Initialize();
3135
}
3236

@@ -35,7 +39,7 @@ protected override void LoadContent()
3539
_spriteBatch = new SpriteBatch(GraphicsDevice);
3640

3741
// Create and add game states
38-
var playingState = new PlayingState(this, _stateManager);
42+
var playingState = new PlayingState(this, _stateManager); // Fix the constructor call - use only the parameters required for your PlayingState constructor
3943
_stateManager.AddState<PlayingState>(playingState);
4044

4145
// Set the initial state

README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
An island-based survival and ecosystem simulation game where players explore procedurally generated islands, interact with evolving wildlife, gather resources, and build structures. Built with MonoGame and C#.
44

5-
![Current Version](https://img.shields.io/badge/version-0.0.1-blue)
5+
![Current Version](https://img.shields.io/badge/version-0.0.2--alpha-blue)
66
![License](https://img.shields.io/badge/license-MIT-green)
77
![Status](https://img.shields.io/badge/status-early%20development-orange)
88

@@ -19,12 +19,16 @@ MyIslandGame combines resource management with deep ecosystem simulation. Your a
1919

2020
## Current State
2121

22-
The game is in very early development (v0.0.1). Current features include:
22+
The game is in early development (v0.0.2-alpha). Current features include:
2323
- Entity Component System architecture
2424
- Basic movement and collision detection
2525
- Simple rendering of placeholder graphics
2626
- Input management system
2727
- Game state management
28+
- Camera system with zoom and player following
29+
- Tile-based procedural map generation
30+
- Day/night cycle with visual effects
31+
- Simple UI framework and debug display
2832

2933
See the [RELEASE_NOTES.md](RELEASE_NOTES.md) for detailed information about the current version.
3034

@@ -34,11 +38,12 @@ See the [RELEASE_NOTES.md](RELEASE_NOTES.md) for detailed information about the
3438

3539
## Development Roadmap
3640

37-
### v0.0.2 (In Progress)
38-
- Camera system
39-
- Tile-based world representation
40-
- Day/night cycle
41-
- Basic UI framework
41+
### v0.0.2 (Released)
42+
- Camera system with zoom and player tracking
43+
- Tile-based procedural world generation
44+
- Day/night cycle with lighting effects
45+
- Basic UI framework with debug information
46+
- Player movement and world boundaries
4247

4348
### v0.0.3 (Planned)
4449
- Simple ecosystem with basic entities
@@ -60,16 +65,23 @@ See the [RELEASE_NOTES.md](RELEASE_NOTES.md) for detailed information about the
6065
### Installation and Running
6166
```bash
6267
# Clone the repository
63-
git clone https://github.com/yourusername/MyIslandGame.git
68+
git clone https://github.com/jacuzzicoding/MyIslandGame.git
6469
cd MyIslandGame
6570

71+
# Install dependencies (Mac users)
72+
# Mac users may need to install freetype6 library
73+
brew install freetype
74+
6675
# Build and run
6776
dotnet build
6877
dotnet run
6978
```
7079

7180
### Controls
7281
- **WASD/Arrow Keys**: Move player
82+
- **+/-**: Zoom in/out camera
83+
- **T**: Speed up time (5x)
84+
- **R**: Reset time to 8:00 AM
7385
- **ESC**: Quit game
7486

7587
## Architecture

Source/Core/TimeManager.cs

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
using System;
2+
using Microsoft.Xna.Framework;
3+
4+
namespace MyIslandGame.Core
5+
{
6+
/// <summary>
7+
/// Manages game time, including day/night cycles.
8+
/// </summary>
9+
public class TimeManager
10+
{
11+
/// <summary>
12+
/// Represents a time of day in the game world.
13+
/// </summary>
14+
public enum TimeOfDay
15+
{
16+
/// <summary>Daytime.</summary>
17+
Day,
18+
19+
/// <summary>Sunset time.</summary>
20+
Sunset,
21+
22+
/// <summary>Nighttime.</summary>
23+
Night,
24+
25+
/// <summary>Sunrise time.</summary>
26+
Sunrise
27+
}
28+
29+
private float _totalGameMinutes;
30+
private readonly float _minutesPerSecond;
31+
private readonly float _minutesPerDay;
32+
private bool _isPaused;
33+
34+
/// <summary>
35+
/// Gets the current time of day in game minutes (0 to MinutesPerDay).
36+
/// </summary>
37+
public float CurrentTimeMinutes => _totalGameMinutes % _minutesPerDay;
38+
39+
/// <summary>
40+
/// Gets the number of in-game minutes per real-time second.
41+
/// </summary>
42+
public float MinutesPerSecond => _minutesPerSecond;
43+
44+
/// <summary>
45+
/// Gets the number of minutes in a full game day.
46+
/// </summary>
47+
public float MinutesPerDay => _minutesPerDay;
48+
49+
/// <summary>
50+
/// Gets the current in-game hour (0-23).
51+
/// </summary>
52+
public int CurrentHour => (int)(CurrentTimeMinutes / 60f) % 24;
53+
54+
/// <summary>
55+
/// Gets the current in-game minute (0-59).
56+
/// </summary>
57+
public int CurrentMinute => (int)(CurrentTimeMinutes % 60f);
58+
59+
/// <summary>
60+
/// Gets the current in-game day number, starting from day 1.
61+
/// </summary>
62+
public int CurrentDay => (int)(_totalGameMinutes / _minutesPerDay) + 1;
63+
64+
/// <summary>
65+
/// Gets the current time progress as a normalized value (0.0 to 1.0).
66+
/// </summary>
67+
public float NormalizedTime => CurrentTimeMinutes / _minutesPerDay;
68+
69+
/// <summary>
70+
/// Gets or sets whether the time is paused.
71+
/// </summary>
72+
public bool IsPaused
73+
{
74+
get => _isPaused;
75+
set => _isPaused = value;
76+
}
77+
78+
/// <summary>
79+
/// Gets the current time of day phase.
80+
/// </summary>
81+
public TimeOfDay CurrentTimeOfDay
82+
{
83+
get
84+
{
85+
float normalizedTime = NormalizedTime;
86+
87+
// Dawn hours (5:00 - 7:00)
88+
if (normalizedTime >= 5f / 24f && normalizedTime < 7f / 24f)
89+
{
90+
return TimeOfDay.Sunrise;
91+
}
92+
// Day hours (7:00 - 19:00)
93+
else if (normalizedTime >= 7f / 24f && normalizedTime < 19f / 24f)
94+
{
95+
return TimeOfDay.Day;
96+
}
97+
// Dusk hours (19:00 - 21:00)
98+
else if (normalizedTime >= 19f / 24f && normalizedTime < 21f / 24f)
99+
{
100+
return TimeOfDay.Sunset;
101+
}
102+
// Night hours (21:00 - 5:00)
103+
else
104+
{
105+
return TimeOfDay.Night;
106+
}
107+
}
108+
}
109+
110+
/// <summary>
111+
/// Gets the sun intensity factor (0.0 to 1.0).
112+
/// </summary>
113+
public float SunIntensity
114+
{
115+
get
116+
{
117+
float normalizedTime = NormalizedTime;
118+
119+
// Night (0.0)
120+
if (normalizedTime < 5f / 24f || normalizedTime >= 21f / 24f)
121+
{
122+
return 0.0f;
123+
}
124+
125+
// Sunrise transition (0.0 to 1.0)
126+
if (normalizedTime >= 5f / 24f && normalizedTime < 7f / 24f)
127+
{
128+
return (normalizedTime - 5f / 24f) / (2f / 24f);
129+
}
130+
131+
// Daytime (1.0)
132+
if (normalizedTime >= 7f / 24f && normalizedTime < 19f / 24f)
133+
{
134+
return 1.0f;
135+
}
136+
137+
// Sunset transition (1.0 to 0.0)
138+
if (normalizedTime >= 19f / 24f && normalizedTime < 21f / 24f)
139+
{
140+
return 1.0f - (normalizedTime - 19f / 24f) / (2f / 24f);
141+
}
142+
143+
return 0.0f;
144+
}
145+
}
146+
147+
/// <summary>
148+
/// Gets a color representing the ambient light based on the time of day.
149+
/// </summary>
150+
public Color AmbientLightColor
151+
{
152+
get
153+
{
154+
TimeOfDay timeOfDay = CurrentTimeOfDay;
155+
float sunIntensity = SunIntensity;
156+
157+
switch (timeOfDay)
158+
{
159+
case TimeOfDay.Day:
160+
return Color.White;
161+
162+
case TimeOfDay.Sunrise:
163+
// Sunrise: Blend from dark blue to white with orange tint
164+
return Color.Lerp(
165+
Color.Lerp(new Color(20, 20, 70), new Color(255, 200, 150), sunIntensity),
166+
Color.White,
167+
sunIntensity);
168+
169+
case TimeOfDay.Sunset:
170+
// Sunset: Blend from white to dark blue with orange tint
171+
return Color.Lerp(
172+
Color.White,
173+
Color.Lerp(new Color(255, 150, 100), new Color(20, 20, 70), 1f - sunIntensity),
174+
1f - sunIntensity);
175+
176+
case TimeOfDay.Night:
177+
// Night: Dark blue with slight moonlight
178+
return new Color(20, 20, 70);
179+
180+
default:
181+
return Color.White;
182+
}
183+
}
184+
}
185+
186+
/// <summary>
187+
/// Initializes a new instance of the <see cref="TimeManager"/> class.
188+
/// </summary>
189+
/// <param name="minutesPerDay">Number of minutes in a game day.</param>
190+
/// <param name="minutesPerSecond">Number of game minutes per real second.</param>
191+
/// <param name="startTimeMinutes">Starting time in minutes.</param>
192+
public TimeManager(float minutesPerDay = 1440f, float minutesPerSecond = 24f, float startTimeMinutes = 480f)
193+
{
194+
_minutesPerDay = minutesPerDay;
195+
_minutesPerSecond = minutesPerSecond;
196+
_totalGameMinutes = startTimeMinutes; // Start at 8:00 AM by default
197+
_isPaused = false;
198+
}
199+
200+
/// <summary>
201+
/// Updates the time manager.
202+
/// </summary>
203+
/// <param name="gameTime">The game time.</param>
204+
public void Update(GameTime gameTime)
205+
{
206+
if (!_isPaused)
207+
{
208+
float deltaSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
209+
float deltaMinutes = deltaSeconds * _minutesPerSecond;
210+
211+
_totalGameMinutes += deltaMinutes;
212+
}
213+
}
214+
215+
/// <summary>
216+
/// Sets the time to a specific hour and minute.
217+
/// </summary>
218+
/// <param name="hour">The hour (0-23).</param>
219+
/// <param name="minute">The minute (0-59).</param>
220+
public void SetTime(int hour, int minute)
221+
{
222+
hour = MathHelper.Clamp(hour, 0, 23);
223+
minute = MathHelper.Clamp(minute, 0, 59);
224+
225+
float currentDay = (float)Math.Floor(_totalGameMinutes / _minutesPerDay);
226+
_totalGameMinutes = (currentDay * _minutesPerDay) + (hour * 60f) + minute;
227+
}
228+
229+
/// <summary>
230+
/// Gets a formatted time string (HH:MM).
231+
/// </summary>
232+
/// <returns>The formatted time string.</returns>
233+
public string GetTimeString()
234+
{
235+
return $"{CurrentHour:D2}:{CurrentMinute:D2}";
236+
}
237+
238+
/// <summary>
239+
/// Gets a formatted date and time string (Day X - HH:MM).
240+
/// </summary>
241+
/// <returns>The formatted date and time string.</returns>
242+
public string GetDateTimeString()
243+
{
244+
return $"Day {CurrentDay} - {GetTimeString()}";
245+
}
246+
}
247+
}

Source/ECS/Components/ColliderComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class ColliderComponent : Component
3131
/// <summary>
3232
/// Gets or sets a value indicating whether collision is enabled.
3333
/// </summary>
34-
public bool Enabled { get; set; } = true;
34+
public new bool Enabled { get; set; } = true;
3535

3636
/// <summary>
3737
/// Gets the bounding rectangle in world space based on the entity's position.

Source/ECS/Components/VelocityComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class VelocityComponent : Component
2626
/// <summary>
2727
/// Gets or sets a value indicating whether physics calculations should be applied.
2828
/// </summary>
29-
public bool Enabled { get; set; } = true;
29+
public new bool Enabled { get; set; } = true;
3030

3131
/// <summary>
3232
/// Initializes a new instance of the <see cref="VelocityComponent"/> class.

0 commit comments

Comments
 (0)