2D model simulating water breaking a floodbank
Downcasting can usually be avoided by using common methods in abstract types.

    if (((DoorbraakWorld)getWorld()).stopped) return;


Is this the same as getWorld().stopped()?

    // The next line looks so incredibly ugly…
    Sandstone sandstone = (Sandstone)getOneObjectAtOffset(dx, dy, Sandstone.class);
    if (sandstone != null) {
        getWorld().removeObject(sandstone);
        getWorld().addObject(new Water(), getX() + dx, getY() + dy);
    }


You can use the Actor type: Actor sandstone = getOneObjectAtOffset(dx, dy, Sandstone.class)

    Sand sand = (Sand)getOneObjectAtOffset(0, 1, Sand.class);


Here too: Actor sand = getOneObjectAtOffset(0, 1, Sand.class);

    ((DoorbraakWorld)getWorld()).stopped = true;


How about greenfoot.stop()?