A first aproach could be giving a varying weight to each type of block, modifying such weight each level, decressing the probability of spawning an easy blocks and increasing the probability to spawn a harder ones.
I'm also going to suppose you have some kind of a parent Block class and different child classes for each type of block.
public Block createBlock(int level) {
double wBasic = 1.0/(1*level);
double wFast = 0.5*level;
double wShop = 0.1*level;
double wKiller = 0.05*level;
double wSafe = 1.0/(2*level);
double psum = wBasic + wFast + wShop + wKiller + wSafe;
double wBasicNorm = wBasic / psum;
double wFastNorm = wFast / psum;
double wShopNorm = wShop / psum;
double wKillerNorm = wKiller / psum;
double wSafeNorm = wSafe / psum;
double rangeBasic = wBasicNorm;
double rangeFast = rangeBasic + wFastNorm;
double rangeShop = rangeFast + wShopNorm;
double rangeKiller = rangeShop + wKillerNorm;
Random rgen = new Random();
double r = rgen.nextDouble();
if (r < rangeBasic) {
return new BasicBlock();
} else if (r < rangeFast ) {
return new FastBlock();
} else if (r < rangeShop) {
return new ShopBlock();
} else if (r < rangeKiller) {
return new KillerBlock();
} else {
return new SafeBlock();
}
}
With this we'll create a different probability for each block to spawn, and then normalize that probability giving it a value between 0 and 1 (wich is the range of the numbers returned by the random number generator).
Then we want to know the different "ranges" of probability of each block.The random number generated will fall in one of those ranges, and this is what will set the type of block created. This can be seen as placing the probabilities of each block in a line like this:
basic fast shop killer safe
0.0|-------|---------|------------|--------------|--------|1.0
^
|
random numer
PS: This is my first answer ever, hope it helps.