Since you are only moving from left to right, all you need to do is store a two dimensional array of x coordinates and object type/parameters.
If you have an objects x position, you just need to see if it's on screen using this, if it is, put it in and work out the y coordinate of the ground at that location. The X position can simply be an index to your terrain array.
You can use bit-masking to create unique ids for objects and parameters. Then create a Factory method which will accept this id, break it down to get the type, call the constructor for that type and pass the id to it. The constructor can then use the id to work out how the object should be constructed.
As a quick example;
#include <iostream>
enum Type
{
Box = 0,
Enemy = 1,
House = 2,
Plant = 3,
Vehicle = 4,
// We want to shift value to the right hand side
// of the int. The biggest value is 4 which
// requires 3 bits to specify, so we want to
// shift the number up to 32 - 3 (29).
TypeBitShift = 29
};
enum EnemyType
{
Snake = 0,
Rhino = 1,
Shark = 2
};
void main()
{
unsigned int * IDs = new int[3];
IDs[0] = (Enemy << TypeBitShift) | Snake;
IDs[1] = (Enemy << TypeBitShift) | Rhino;
IDs[2] = (Enemy << TypeBitShift) | Shark;
for(int i = 0; i < 3; ++i)
{
// push the parameter bits off the end and convert to a type
Type T = (Type)(IDs[i] >> TypeBitShift);
if ( (int)T == Enemy )
{
// trim the type section, you can use;
// (IDs[i] - ((IDs[i] >> TypeBitShift) << TypeBitShift))
// or IDs[i] - (int) T << TypeBitShift since we already have the type
// You can also get rid of any type parameter with;
// or (IDs[i] & 0xFFFFFFFF >> (sizeof(int) * 8 - TypeBitShift))
// or (IDs[i] & 0xFFFFFFFF >> 3)
EnemyType ET = (EnemyType)(IDs[i] & 0xFFFFFFFF >> (sizeof(int) * 8 - TypeBitShift);
switch(ET)
{
case Snake:
std::cout << "I'm a snake.\n";
break;
case Rhino:
std::cout << "I'm a rhino.\n";
break;
case Shark:
std::cout << "I'm a shark.\n";
break;
}
}
}
std::cin.get();
}