Whenever I question myself questions like this I try to look at existing examples. In about every game you get a loading screen before the actual game starts -> the loading starts before the actual has started. So all the loading should preferably happen before the gameloop.
When your running a game and a new object is created, which also needs a new resource(let's say a png file for a sprite). You could refer to the already loaded file to prevent loading at run time. Which files should be loaded before beginning a level should be defined somewhere in your level data.
There are scenarios where you are unsure which assets you will use though (dynamically created world for example). I use the following method for this:
[pseudo code]
Class ContentManager()
{
Array assets = new Array();
public static Sprite getSprite(string spritename ){ //or sprite id or whatever unique identifier
for (Sprite sprite : assets){
if(sprite.name == spritename){
return sprite;
}
}
//it's not found in the list, so let's load it
Sprite newsprite = Loader.load(spritename);
assets.push(newsprite);
return newsprite;
}
}
In short: add every loaded asset to an array. When you need to use an asset, check if it's in the list. Return the sprite if it's there, or load it and add it to the array if it's not found.