I had a somewhat amusing day at work. I arrived this morning just before 9AM, and noticed something out of the corner of my eye.
There, on our store-front window, was a swarm of bees clustered together, about the size of a grapefruit.I hate bees, and being stung. Fortunately, these bees were not interested in me in the slightest. Still, as a precaution, we kept the doors closed for most of the day and put a sign up "CAUTION: Door closed due to bees" with an arrow pointing to the swarm.Most people thought it was a joke, until they looked. Some of them jumped pretty far.We don't know why they were hanging there, but they stayed that way all day while we waited for some beekeeper or other to show up. He didn't, and my boss was getting tired of waiting. The bees were hurting (literally in some cases) our business.So she grabbed a can of Doom (Insecticide), sprayed some quickly and dashed back inside. The bees didn't die, but they did start to fall apart. One of the last 'pieces' of the swarm that fell off had the queen in it, surrounded by a ball of other bees. Reminded me of Katamari…The funny thing is, there wasn't anything there for the bees to make a hive in. They were literally gripping onto a tiny bit of dried paint that had formed a small bump in the paintwork, on the underside of the window lintel (Concrete and metal construction). That was certainly the last thing I imagined happening today; would've taken a photo, but I kinda forgot. :PLudum DareI kinda flunked this. Not intentionally, nor because I didn't have time. The whole country has been going through rolling blackouts, and they were particularly bad on the weekend. I lost quite a bit of work to the first one, and had a lot of trouble getting back on track after that.I didn't upload my 'final' product, but here's what I had at the end:The theme for this LD was "The entire game on one screen". I decided to make something arcade-like. Waves of enemies would be beamed in by that contraption in the middle, and you'd have to survive for as long as possible, collect randomized powerups and possibly have a second player join in.Somewhat low-key for me, but that's because of what I coded this in. What I do have, I made entirely from scratch in C++. I was originally planning to use one of my existing frameworks to accelerate the workflow, but decided to test the difficulty of doing something like this from scratch.Turns out, not too long.All I really have here is animation, running and jumping (And collision, of course). I had started on an enemy, projectile and health system when the power went out. And of course I hadn't saved. I did stream a bit. Potato quality if you want to take a look: http://www.twitch.tv/64mega/profile/past_broadcastsUhh… Impulse post mortem, I guess?Overall 'engine' designI decided to use a system that was a hybrid of my old Exile system, and a newer one I have been working on.In Exile, all GameObjects are spawned into a single list. Every frame, this list is traversed, dead objects are culled and the update() method for each object is called.This is great, when you're dealing with a small number of objects.It's also great when you don't need any information about the type of object.Oh, and it becomes a bloody mess when you need to do collision detection/object interaction. Loops within loops within loops…Exile worked though. :3My 'new' system uses a few different techniques. Here's the base game object class:class GObject {
public:
static GRegistry registry;
std::string id = "object";
GSprite* sprite = nullptr;
float x = 0.0F, y = 0.0F;
bool dead = false;
GObject();
virtual ~GObject();
virtual void update();
};
class GRegistry {
public:
void add(GObject* obj);
void cull();
void iterateOver(std::function<bool(GObject&)> func);
void update();
void cullAll();
private:
std::vector<GObject*> objects;
};
registry.add(this);
class EBlock : public GObject
{
public:
static GRegistry registry;
EBlock(int tx = 0, int ty = 0);
virtual ~EBlock();
virtual void update();
};
EBlock::EBlock(int tx, int ty) :
GObject()
{
this->registry.add(this);
}
EBlock::registry.iterateOver([&](GObject& object) {
EBlock* block = (EBlock*) &object;
// Do collision stuff with block
});
if(object->id.find_first_of("c") != string::npos) {
// Collide with this object
}
if(object->id.find_first_of("d") != string::npos) {
// Get damaged by this object
}
// Partial class definition
class GObject {
private:
Damage *damage = nullptr;
Collider *collider = nullptr;
public:
void DoCollision(std::function<void(GObject&)> func);
void DoDamage(std::function<void(GObject&)> func);
};
// Will use like this:
void Player::update()
{
Player *self = this;
EEnemyProjectile::iterateOver([&](GObject& obj) {
// Check if colliding and perform following
obj.DoDamage([&](GObject& obj) {
TDamage* damage = (TDamage*) &obj;
self->hp -= damage->value;
});
});
}
Beads?
Too bad you couldn't finish Ludum. It looked like it could be a fun arcady shooter. Everytime i see dark city backgrounds, I'm reminded of Contra ]|[.
I didn't finish my entry either, but I entered what I had. http://ludumdare.com/compo/ludum-dare-31/?action=preview&uid=40112 (turn v-sync if the effects move to fast.) From scratch in C, source included. Obvs, seriously rushed, don't judge me! :-O A game object registry and query like that would have come in handy.Nice, giving it a try and taking a look at your source. :P
I like reading engine source code, no matter what it looks like. You always glean ideas from doing it. Also, props for actually submitting something. I probably would have if the power had remained stable.Oh yeah, I forgot I'd written about that before :P
Not at all. I probably borrowed it from somewhere else anyway, and forgot where :P
It's a very natural feeling management mechanism, and also basically makes objects easier to delete. At the end of the game, I can just call GObject::registry.cullAll() to delete all Game Objects, for instance.Exile had several lists for different objects. There was the Projectile list, EnemyProjectile list, Enemy list, Item list, PlayerInventory list, DoorList, and so on. Each of those I had to delete (And I recently noticed that I was forgetting to delete the Projectile list, causing a subtle memory leak that I wouldn't have found normally).This is, essentially, a simplified Garbage Collection system. Objects that flag themselves as dead can trigger a sweep for dead objects, starting in their class and cascading 'up' the destructor chain to remove them from all registries. There are a few complexities to take into account with this, such as how to deal with the parent destructor, how to decide who ultimately deletes the object, and so on.Another little idea I added recently, back to the topic of getting the object to initiate a sweep of its own registry, I'm using an EventBus:I use static members specifically for instances where it makes logical sense for functionality or data to be associated with the entire class of an object, over a single instance of an object.