state_timer.start(SQUISH_TIME);
break;
case STATE_ACTIVE:
- flags &= ~FLAG_NO_COLLDET;
+ set_group(COLGROUP_MOVING);
bbox.set_pos(start_position);
break;
case STATE_INACTIVE:
if(laststate == STATE_SQUISHED || laststate == STATE_FALLING) {
remove_me();
}
- flags |= FLAG_NO_COLLDET;
+ set_group(COLGROUP_DISABLED);
break;
case STATE_FALLING:
- flags |= FLAG_NO_COLLDET;
+ set_group(COLGROUP_DISABLED);
break;
default:
break;
reader.get("fluffy",fluffy);
bbox.set_size(31.8, 31.8);
if (fluffy) sprite = sprite_manager->create("fluffy");
- else sprite = sprite_manager->create("snowball");
+ else sprite = sprite_manager->create("images/creatures/snowball/snowball.sprite");
set_direction = false;
}
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include <iostream>
assert(wrapper != 0);
#else
if(wrapper == 0) {
- std::cerr << "Tried to remove nonexistant object!\n";
- return;
+ std::cerr << "Tried to remove nonexistant object!\n";
+ return;
}
#endif
for(float x = obbox.p1.x; x < obbox.p2.x; x += cell_width) {
int gridx = int(x / cell_width);
int gridy = int(y / cell_height);
- if(gridx < 0 || gridy < 0
- || gridx >= int(cells_x) || gridy >= int(cells_y)) {
+ if(gridx < 0 || gridy < 0 ||
+ gridx >= int(cells_x) || gridy >= int(cells_y)) {
std::cerr << "Object out of range: " << gridx << ", " << gridy << "\n";
continue;
}
MovingObject* object = wrapper->object;
if(!object->is_valid())
continue;
- if(object->get_flags() & GameObject::FLAG_NO_COLLDET) {
+ if(object->get_group() == COLGROUP_DISABLED) {
object->bbox.move(object->movement);
object->movement = Vector(0, 0);
moved_objects.push_back(wrapper);
// flags
enum {
/// the tile so you can stand on it
- FLAG_SOLID = 0x0001,
- /// can be used to temporatily disable collision detection
- FLAG_NO_COLLDET = 0x0002
+ FLAG_SOLID = 0x0001
};
int get_flags() const
if(config->show_fps) {
char str[60];
- snprintf(str, sizeof(str), "%2.1f", fps_fps);
+ snprintf(str, sizeof(str), "%3.1f", fps_fps);
context.draw_text(white_text, "FPS",
Vector(SCREEN_WIDTH -
white_text->get_text_width("FPS ") - BORDER_X, BORDER_Y + 40),
try {
config->load();
} catch(std::exception& e) {
-#ifdef DEBUG
std::cerr << "Couldn't load config file: " << e.what() << "\n";
-#endif
+ std::cerr << "Using default settings.\n";
}
}
MovingObject::MovingObject()
{
+ group = COLGROUP_MOVING;
}
MovingObject::~MovingObject()
class Sector;
class CollisionGrid;
+enum CollisionGroup {
+ COLGROUP_DISABLED,
+ COLGROUP_MOVING,
+ COLGROUP_STATIC,
+ COLGROUP_MOVINGSTATIC,
+ COLGROUP_TOUCHABLE,
+
+ COLGROUP_TILEMAP /* not really used at the moment */
+};
+
/**
* Base class for all dynamic/moving game objects. This class contains things
* for handling the bounding boxes and collision feedback.
{
bbox.set_pos(pos);
}
+
+ CollisionGroup get_group() const
+ {
+ return group;
+ }
+
+ void set_group(CollisionGroup group)
+ {
+ this->group = group;
+ }
protected:
friend class Sector;
/** The movement that will happen till next frame
*/
Vector movement;
+ /** The collision group */
+ CollisionGroup group;
};
#endif
: sprite(newsprite), bouncing(false), bounce_dir(0), bounce_offset(0)
{
bbox.set_size(32, 32.1);
+ set_group(COLGROUP_STATIC);
flags |= FLAG_SOLID;
}
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "coin.hpp"
bbox.set_pos(pos);
bbox.set_size(32, 32);
sprite = sprite_manager->create("coin");
+ set_group(COLGROUP_TOUCHABLE);
}
Coin::Coin(const lisp::Lisp& reader)
reader.get("y", bbox.p1.y);
bbox.set_size(32, 32);
sprite = sprite_manager->create("coin");
+ set_group(COLGROUP_TOUCHABLE);
}
Coin::~Coin()
sprite = sprite_manager->create("fireflower");
else
sprite = sprite_manager->create("iceflower");
+
+ set_group(COLGROUP_TOUCHABLE);
}
Flower::~Flower()
sprite = sprite_manager->create("egg");
physic.enable_gravity(true);
physic.set_velocity_x(100);
+ set_group(COLGROUP_MOVING);
}
GrowUp::~GrowUp()
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "oneup.hpp"
bbox.set_size(32, 32);
sprite = sprite_manager->create("1up");
physic.set_velocity(100, 400);
+ set_group(COLGROUP_TOUCHABLE);
}
OneUp::~OneUp()
player_status->bonus = NO_BONUS;
dying = true;
dying_timer.start(3.0);
- flags |= FLAG_NO_COLLDET;
+ set_group(COLGROUP_DISABLED);
}
}
bbox.set_size(32, 32);
sprite = sprite_manager->create(sprite_name);
physic.enable_gravity(true);
+
+ set_group(COLGROUP_MOVING);
}
PowerUp::~PowerUp()
{
if(!grabbed) {
flags |= FLAG_SOLID;
- flags &= ~FLAG_NO_COLLDET;
+ set_group(COLGROUP_STATIC);
movement = physic.get_movement(elapsed_time);
} else {
physic.set_velocity(0, 0);
flags &= ~FLAG_SOLID;
- flags |= FLAG_NO_COLLDET;
+ set_group(COLGROUP_DISABLED);
}
grabbed = false;
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "skull_tile.hpp"
bbox.set_size(32, 32);
sprite = sprite_manager->create("skull_tile");
flags |= FLAG_SOLID;
+
+ set_group(COLGROUP_STATIC);
}
SkullTile::~SkullTile()
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "star.hpp"
bbox.set_size(32, 32);
sprite = sprite_manager->create("star");
physic.set_velocity(SPEED, INITIALJUMP);
+
+ set_group(COLGROUP_MOVING);
}
Star::~Star()
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#include <config.h>
#include "unstable_tile.hpp"
bbox.set_size(32, 32);
sprite = sprite_manager->create("unstable_tile");
flags |= FLAG_SOLID;
+ set_group(COLGROUP_STATIC);
}
UnstableTile::~UnstableTile()
#endif
/* Handle all possible collisions. */
- collision_handler();
+ handle_collisions();
update_game_objects();
}
Sector::update_game_objects()
{
/** cleanup marked objects */
+ for(std::vector<Bullet*>::iterator i = bullets.begin();
+ i != bullets.end(); /* nothing */) {
+ Bullet* bullet = *i;
+ if(bullet->is_valid()) {
+ ++i;
+ continue;
+ }
+
+ i = bullets.erase(i);
+ }
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); /* nothing */) {
+ MovingObject* moving_object = *i;
+ if(moving_object->is_valid()) {
+ ++i;
+ continue;
+ }
+
+#ifdef USE_GRID
+ grid->remove_object(moving_object);
+#endif
+
+ i = moving_objects.erase(i);
+ }
for(std::vector<GameObject*>::iterator i = gameobjects.begin();
i != gameobjects.end(); /* nothing */) {
GameObject* object = *i;
continue;
}
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet) {
- bullets.erase(
- std::remove(bullets.begin(), bullets.end(), bullet),
- bullets.end());
- }
-#ifdef USE_GRID
- MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject) {
- grid->remove_object(movingobject);
- }
-#endif
delete *i;
i = gameobjects.erase(i);
}
if(bullet)
bullets.push_back(bullet);
-#ifdef USE_GRID
MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject)
+ if(movingobject) {
+ moving_objects.push_back(movingobject);
+ #ifdef USE_GRID
grid->add_object(movingobject);
#endif
+ }
TileMap* tilemap = dynamic_cast<TileMap*> (object);
if(tilemap && tilemap->is_solid()) {
}
void
-Sector::collision_handler()
+Sector::handle_collisions()
{
#ifdef USE_GRID
grid->check_collisions();
#else
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* gameobject = *i;
- if(!gameobject->is_valid())
+ // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* movingobject = *i;
+ if(movingobject->get_group() != COLGROUP_MOVING
+ || !movingobject->is_valid())
+ continue;
+
+ // collision with tilemap
+ collision_tilemap(movingobject, 0);
+
+ // collision with other objects
+ for(MovingObjects::iterator i2 = i+1;
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* movingobject2 = *i2;
+ if(movingobject2->get_group() != COLGROUP_STATIC
+ || !movingobject2->is_valid())
+ continue;
+
+ collision_object(movingobject, movingobject2);
+ }
+ }
+
+ // part2: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ if(moving_object->get_group() != COLGROUP_MOVING
+ || !moving_object->is_valid())
continue;
- MovingObject* movingobject = dynamic_cast<MovingObject*> (gameobject);
- if(!movingobject)
+
+ for(MovingObjects::iterator i2 = moving_objects.begin();
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* moving_object_2 = *i2;
+ if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
+ || !moving_object_2->is_valid())
+ continue;
+
+ collision_object(moving_object, moving_object_2);
+ }
+ }
+
+ // part3: COLGROUP_MOVING vs COLGROUP_MOVING
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+
+ if(moving_object->get_group() != COLGROUP_MOVING
+ || !moving_object->is_valid())
+ continue;
+
+ for(MovingObjects::iterator i2 = i+1;
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* moving_object_2 = *i2;
+ if(moving_object_2->get_group() != COLGROUP_MOVING
+ || !moving_object_2->is_valid())
+ continue;
+
+ collision_object(moving_object, moving_object_2);
+ }
+ }
+
+ // apply object movement
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+
+ moving_object->bbox.move(moving_object->get_movement());
+ moving_object->movement = Vector(0, 0);
+ }
+
+#if 0
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* movingobject = *i;
+ if(!movingobject->is_valid())
continue;
if(movingobject->get_flags() & GameObject::FLAG_NO_COLLDET) {
movingobject->bbox.move(movingobject->movement);
collision_tilemap(movingobject, 0);
// collision with other objects
- for(std::vector<GameObject*>::iterator i2 = i+1;
- i2 != gameobjects.end(); ++i2) {
- GameObject* other_object = *i2;
- if(!other_object->is_valid()
- || other_object->get_flags() & GameObject::FLAG_NO_COLLDET)
- continue;
- MovingObject* movingobject2 = dynamic_cast<MovingObject*> (other_object);
- if(!movingobject2)
+ for(MovingObjects::iterator i2 = i+1;
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* movingobject2 = *i2;
+ if(!movingobject2->is_valid()
+ || movingobject2->get_flags() & GameObject::FLAG_NO_COLLDET)
continue;
collision_object(movingobject, movingobject2);
movingobject->movement = Vector(0, 0);
}
#endif
+
+#endif
}
bool
/** Checks for all possible collisions. And calls the
collision_handlers, which the collision_objects provide for this
case (or not). */
- void collision_handler();
+ void handle_collisions();
bool add_bullet(const Vector& pos, float xm, Direction dir);
bool add_smoke_cloud(const Vector& pos);
public: // TODO make this private again
typedef std::vector<GameObject*> GameObjects;
GameObjects gameobjects;
+ typedef std::vector<MovingObject*> MovingObjects;
+ MovingObjects moving_objects;
typedef std::vector<SpawnPoint*> SpawnPoints;
SpawnPoints spawnpoints;
TriggerBase::TriggerBase()
: sprite(0)
{
+ set_group(COLGROUP_TOUCHABLE);
}
TriggerBase::~TriggerBase()