--- /dev/null
+#include <config.h>
+
+#include "unstable_tile.h"
+#include "lisp/lisp.h"
+#include "object_factory.h"
+#include "player.h"
+#include "sector.h"
+#include "resources.h"
+#include "special/sprite_manager.h"
+#include "special/sprite.h"
+
+static const float CRACKTIME = 1;
+static const float FALLTIME = 1.5;
+
+UnstableTile::UnstableTile(const lisp::Lisp& lisp)
+ : hit(false), falling(false)
+{
+ lisp.get("x", bbox.p1.x);
+ lisp.get("y", bbox.p1.y);
+ bbox.set_size(32, 32);
+ sprite = sprite_manager->create("unstable_tile");
+ flags |= FLAG_SOLID;
+}
+
+UnstableTile::~UnstableTile()
+{
+ delete sprite;
+}
+
+HitResponse
+UnstableTile::collision(GameObject& other, const CollisionHit& hitdata)
+{
+ if(hitdata.normal.y < 0.8)
+ return FORCE_MOVE;
+
+ Player* player = dynamic_cast<Player*> (&other);
+ if(player)
+ hit = true;
+
+ return FORCE_MOVE;
+}
+
+void
+UnstableTile::draw(DrawingContext& context)
+{
+ Vector pos = get_pos();
+ // shacking
+ if(timer.get_timegone() > CRACKTIME) {
+ pos.x += (rand() % 6) - 3;
+ }
+
+ sprite->draw(context, pos, LAYER_TILES);
+}
+
+void
+UnstableTile::action(float elapsed_time)
+{
+ if(falling) {
+ movement = physic.get_movement(elapsed_time);
+ if(!Sector::current()->inside(bbox)) {
+ remove_me();
+ return;
+ }
+ } else if(hit) {
+ if(timer.check()) {
+ falling = true;
+ physic.enable_gravity(true);
+ flags &= ~FLAG_SOLID;
+ timer.stop();
+ } else if(!timer.started()) {
+ timer.start(FALLTIME);
+ }
+ } else {
+ timer.stop();
+ }
+ hit = false;
+}
+
+IMPLEMENT_FACTORY(UnstableTile, "unstable_tile");
--- /dev/null
+#ifndef __UNSTABLE_TILE_H__
+#define __UNSTABLE_TILE_H__
+
+#include "special/moving_object.h"
+#include "lisp/lisp.h"
+#include "math/physic.h"
+#include "timer.h"
+
+namespace SuperTux {
+ class Sprite;
+}
+class Player;
+
+using namespace SuperTux;
+
+/** A tile that starts falling down if tux stands to long on it */
+class UnstableTile : public MovingObject
+{
+public:
+ UnstableTile(const lisp::Lisp& lisp);
+ ~UnstableTile();
+
+ HitResponse collision(GameObject& other, const CollisionHit& hit);
+ void action(float elapsed_time);
+ void draw(DrawingContext& context);
+
+private:
+ Physic physic;
+ Sprite* sprite;
+ Timer2 timer;
+ bool hit;
+ bool falling;
+};
+
+#endif
+