Showing posts with label 2d. Show all posts
Showing posts with label 2d. Show all posts

Tuesday, 27 August 2013

LD#27 (10 seconds) - 10s Paparazzi

Time flies, and the 27th Ludum Dare took place this weekend. The theme? 10 seconds.
Play it here...

...or check the LD entry

Of course, here is the postmortem.

Also, take a look at some friends's Jam entry, Bloody Bob.
It looks this cool:

Monday, 17 December 2012

LD #25 - You are the villain

This is my entry for Ludum Dare 25 (Theme: You are the Villain).

Behold...Conquer all the castles!!



Link to the entry

Tuesday, 28 August 2012

It's evolution, baby! Ludum Dare #24




Long time no see!

I've come back to life to....eat your braaaaainz!!!.

Well, not really.

I could start with the prototype I've been coding at a ridiculously irregular rate, but I'll restrain for now until I have something that I can show or talk about. Instead, I want to talk about the Ludum Dare.

This weekend was the 24th edition, and I contributed with my first submission. For those who don't know what I'm talking about, it is a speed game development jam. There are two modes: the competition, where you have 48 hours to develop a game by yourself, and the jam. In the jam you can work in teams and have one more day to do stuff.

I've always liked  the idea, and the challenge a game jam represents, so I was considering to join one sooner or later. Since the theme for this edition was Evolution, which is a topic I've been interested in for some time, I couldn't let it go. My choice was to make a god game where you could control an evolving ecosystem sim of sorts, based in an overly simplistic implementation of genetic algorithms.



I won't delve in much detail. Instead, I'll just link to the submission and post-mortem posts, stating what went right (a couple of lessons that could be valuable for life), and what went wrong (almost everything else).

Despite this, I'm thinking that the idea is interesting, so I might give it a go and develop it in the future (once I'm done with the prototype and a full version of Wall Chaos, of course).

And, of course, the direct link. Don't dig too much into the code, please... it is embarrassing :P
Dropbox link here. Uncompress and enjoy (Windows only, sorry :S)

Tuesday, 6 July 2010

Wall Chaos (II) - Technical stuff (Run for your lives!!)

After the first post, focused on design issues, this second one will show the dirty implementation details behind the 2D version of Wall Chaos.

The language of choice was C++. Firstly, because that way I had the chance to reuse some code from the theory classes, and also because it's the language I feel most comfortable programming in excluding Python. 

If you remember, the assignment included a constraint that restricted the game to be isometric. Getting this done was probably the most challenging part, and I ended up mixing theory concepts learned in class with some ideas I got from Ernest Pazera's Isometric Game Programming with DirectX 7.0.

As you probably know, there are several subtypes of isometric maps. The most widely used ones are probably the staggered map(for example, the one used throughout the Civilization series) or the diamond map (The Age of Empires maps have this kind of layout). I was pretty sure from the beginning that I'd go with the second approach, as it seemed to fit better with the shape of the rooms.  Both types are pretty similar, but they differ in the way the map is traversed. 

This is how the x and y coordinates range in a diamond map:
This setup makes it a bit more difficult to blit a tile, since two consecutive cells aren't blitted in rows as in a typical rectangular 2d map. Besides, the cell sprites (which are rectangular) will overlap, so the traverse order matters.

This is the blitting loop (there is an outer loop for further layers, as the tiles are stackable, but for brevity's sake I will omit it)

for (int y=0;y<SCENE_HEIGHT;y++)
{
for (int x=0;x<SCENE_WIDTH;x++)
{
TTile* tile = &(gameData.scene->map[y][x][z]);
//Read the tiles' sprite sheet to get the clip rectangle
tileRect=gameData.scene->getTileRect(tile);
int tileIndex=tile->index;
if (tileIndex!=NOTILE)
g_pSprite->Draw(textures[TILESET_INDEX],&tileRect,NULL,
&D3DXVECTOR3( float((x-y-1)*(TILE_WIDTH>>1)-baseX), float((x+y)*(TILE_HEIGHT>>1)-baseY-z*TILE_HEIGHT), 0.0f),
 inkColor); 
}
}

The x,y screen coordinates are computed as follows;
x_screen = ((x_map-y_map-1)*TILE_WIDTH/2)-baseX;
y_screen = ((x_map+y_map)*TILE_HEIGHT/2 - baseY-(z_map*TILE_HEIGHT);

baseX, baseY define the offset from the screen position (0,0). This ensures that the map is rendered at the right location (at the beginning of the game, it will typically start next to the top edge and horizontally centered).

Another issue was to retrieve the cell in the map from a set of screen coordinates. One of the main uses for this is to find out which cell the player has clicked on with the mouse. As Wall Chaos was basically controlled through the keyboard -save for the GUI menus-, I used this method to quickly convert between screen and cell coordinates instead.

The algorithm consists of two parts. This time I'll just describe it:

First, get the cell's rectangle (The diamond cell and its surroundings).
To do this, from the screen coordinates we'll first get the world coordinates, taking into account the scene's offset. This means that if the mouse click resolved to position (100,200), and there is a (400,64) scene offset, the world coordinates would be, respectively, (500,264).

Then, the tentative coarse (per-cell) and fine (per-pixel) coordinates are to be retrieved. This is done in the same way as with common 2D tiled maps:

coarse = (worldX/TILE_WIDTH, worldY/TILE_HEIGHT)
fine = (worldX%TILE_WIDTH, worldY%TILE_HEIGHT)

On those maps we'd probably end the whole process here. However, there are still some more steps involved in this case. Due to the scene's offset position, there is a chance than the fine coordinates are negative and we need to adjust them, adding the tile width or height to the modulo operation result.

Then, depending on the value of the coarse coordinates, we need to adjust the pre-final map coordinates. That's achieved like this:

int mapX=0,mapY=0; //Candidate map coordinates
while(coarseY<0)//Move north
{
mapX--;
mapY--;
coarseY++;
}
while(coarseY>0)//Move south
{
mapX++;
mapY++;
coarseY--;
}
while(coarseX<0)//Move west
{
mapX--;
mapY++;
coarseX++;
}
while(coarseX>0)//...and finally, east
{
mapX++;
mapY--;
coarseX--;
}


After iterating through these loops, the first part of the procedure ends. We have a pair of coordinates corresponding to a rectangular cell (x,y). However, depending on the fine coordinates, the actual diamond cell might be one of the 4 depicted adjacent cells.



The second part's objective is, therefore, to retrieve the actual cell. Taking advantage of the fact that  the ratio width:height of the tiles was 2:1 we can use the following property:

if(fineX<(TILE_WIDTH>>1))//32
{
//Left
if(fineY<(TILE_HEIGHT>>1))//16
{
//Up
if( (TILE_HEIGHT-fineX)>>1 > fineY ) { mapX-=1;}
}
else
{
//Down
if( (TILE_HEIGHT+fineX)>>1 < fineY ) {mapY+=1; }
}
}
else
{
fineX-=(TILE_WIDTH>>1);

//Right
if(fineY<(TILE_HEIGHT>>1))
{
//Up
if( (fineX>>1) > fineY ) mapY-=1;
}
else
{
//Down
if( (TILE_WIDTH-fineX)>>1 < fineY ) mapX+=1;
}
}

After this, mapX and mapY will hold the final map coordinates.

Last, this game featured music and sound. One of the assignment requirements asked us to implement an interface to abstract and encapsulate the concrete sound library used. This was relatively simple to do. I used the old API of FMOD, which seemed good enough for my purposes, and abstracted the three kinds of supported sounds (Streams, Sounds and Samples -midis, basically) into three subclasses of a base class CSoundItem. At the resource loading time, the layer parsed the filename and, depending on the extension (*.wav, *.mid, *.mp3,...), it instanced a particular subclass.
The sound layer had an STL map indexed by an ID string containing all the loaded sounds (the load was done on a per-game-state basis), and then the application just had to keep track of the IDs to play any sound of music track. 

I could dwelve a bit more on the game's architecture (For instance, for managing the game states I defined a couple of variables to keep the current and next state IDs and then a factory to resolve and instance the particular GameState subclass to switch to next. For Once Upon a Night, the Master's final project, I opted for using a stack-based game state machine instead, which turned out to be much more flexible), but I guess I've bored you enough already. If you feel like diving a bit more into the code, you may download the sources from here.

Thursday, 15 April 2010

Wall Chaos (I)

Here is my second playable game, although due to the post's massive length, I've had to split it into two separate ones. The first one will introduce the game, and I'll go through its design choices, and on the second one I'll focus on coding details.

Wall Chaos is a game I did for a class assignment. They requested us to do a 2D game choosing among these three options:
- To make a 2D prototype of the game we'd chosen as the main project.
- To reuse and extend a 2D top-down tiled engine, a la Final Fantasy VI or the old Zelda games, to make an RTS or an RPG.
- To implement an isometric 2D game, the genre being free for us to choose.

The project was meant to be done in groups, but luckily we were also allowed to do it separately, which was what our group did, as we thought we'd have a bigger opportunity to learn from the experience (and I'll never be thankful enough for that decision, because I got the best mark in the class, mwahahhaha).

You can see Chuck Norris' mage twin in the middle of the picture, chased by mad
spiders

Although my favourite genres are precisely RPG and Strategy, I decided to make a game from the start (or almost), instead of reusing a basic engine, as I thought it would be more challenging and rewarding, and I could learn more.

I chose to do an isometric 2D 'shooter' game partially based on an idea I'd previously had for a 2.5D game. Although I wasn't considering the isometric map at all as a choice to implement the real deal, it just came naturally when I had to think of what kind of game to make. Still, I think a top-down view will suit it better, and when I put my mind seriously on it I'll do it that way.

This is the link to the binaries so you can download it. There is a short manual with the controls:
(Disclaimer: Music and sounds are obviously not mine; Credit for the sprites for the mage and the spider goes to Reiner's Tilesets. I did the walls, tiles and the health item sprite, as well as the HUD...the other graphics, well, I guess everybody knows them)

Here's the concept design:

Wall Chaos: The initial concept (Warning!! Wall of text ahead. To skip through the dirty details, read the TL;DR section instead)

Quick and dirty schematic 3D render, just so you can have an idea of how a level might be laid out. The green sphere would be the player, the red ones the enemies, and the small yellow one a projectile flying around the place.

Wall Chaos will be a 2.5D top-down action game taking place in rooms 'a la' Bomberman, focused in exciting, fast and challenging gameplay while at the same time allowing for some tactical possibilities.

Visually, the overall aesthetic look will be colourful and cartoony. Characters, enemies, etc., are therefore meant to be designed as super-deformed characters (References: Most 3D games for the DS, Dr Slump, Dragon Quest, MySims, ...).
The Legend of Zelda: Phantom Hourglass' visuals are also a great example of what I'd like to accomplish


Story: As the final test to complete your studies at a prestigious academy to be a wizard you're tasked to go to the remotest tower in the remotest corner of the kingdom and fetch your degree certificate, located in the highest floor of said tower. Instead of just answering a few questions,
you'll have to clear the game's many levels, each level matching a tower's floor. Some tips about the levels' layout, or the enemies that'll inhabit a level, may be given to you during cutscenes or loading screens.

Each room will be populated by several enemies you'll need to kill before time runs out. Of course, surviving is a must as well ;) To achieve that you'll cast attack spells with your magic wand, and invoke some powerful defensive magic to grant you some bonuses (such as a barrier deflecting enemy projectiles, increased defense or speed, elemental resistances, etcetera). By getting rid of certain enemies you may unlock new spells, and they'll drop items to help you through your quest, as the levels will get increasingly harder as you progress; you might get a better wand, a cloak of invisibility that might let you sneak past a column of enemies and such.

'But that sounds way too cliche and dull, and what's more, it seems way too easy and unchalleging. Where's the catch?,' you may be thinking.

Well, it turns out that the rooms are enchanted, and some walls will modify a magic projectile upon colliding. At its most basic, they'll simply rebound and decrease the projectile's life (for instance, initially the default spell may collide three times before fading out), but depending on the wall and spell type it may be imbued with additional effects (they may add up or not, allowing for some awesome combos in the first case).

As a result, the rebounds can be used strategically to defeat creatures located in unreachable places (for instance, in an island surrounded by lava), or to increase the spell's power. Stylish enemy deaths will be rewarded! (...and epic fails as well: there'll be something for everyone!)

However, a projectile will not differentiate between yourself (remember you're not a fully fledged wizard yet!) and your enemies, so the spells may hit you as well. You'll have to be careful!. Besides, there might be traps around a room.

WALLS:
- Common walls: The spell will just rebound keeping its properties, although its life time will decrease until it reaches zero. I'm considering to increase the damage they cause depending on the number of rebounds, so the last one before extinguishing will be the most powerful.
- Frozen walls: Depending on the type of spell that hits, the result may differ:
->A basic spell will turn into an ice spell, that may paralyse the first creature it finds on its way after colliding.
->A fire spell will revert to a basic spell.
->A lightning spell might turn into a combined IceStorm spell.
->...others
- Warp walls: If the spell hits that wall, it'll disappear to reappear through another warp wall located in the room.
- Fire walls:
-> A basic spell will turn into a fire spell: it can melt ice blocks or roast an enemy.
-> An ice spell will melt and extinguish.
- Piercing walls: It adds a spell a piercing ability: instead of dying out when hitting an enemy, it'll damage it and then pass past it.
- Etcetera

TYPES OF SPELLS. Some of them will be available as 'castable', and others will be made as a combination of several others, as the spell bumps against the enchanted walls.
- Basic spell: it just does damage.
- Piercing spell: it penetrates through enemies.
- Elemental spells: Fire, ice, lightning,...
- Sponge spell: it'll absorb any spell effect, adding them up no matter if they're even opposite ones (for instance, it might add the ice effect and then hit a fire wall without it getting destroyed: the resulting spell would cause ice AND fire damage)

After a while, you might end up with a Ultra-mega-super-powerful Spell of Doom, killing every creature at hand, only to find yourself dead as well because it hit a Warp Wall and then reappeared just behind you.
...and this would be the humiliating result


All of these rebound-based mechanics add an additional strategic component to the game, letting you cannon the projectiles around, as in the pool game. It also makes you keep your attention focused in both the enemies and your own attacks, or even a tricky, hostile environment. For instance, something 'funny' might happen to you after casting several spells without success or while staying still at the same place for a while...

Sadly, for this version (which is, basically, an initial prototype), I just had time to code one type of wall, one type of spell, two type of tiles (walkable and non-walkable) and a couple of items scattered around the levels (there were no enemy drops either). I didn't have enough time to implement some pathfinding, so the only kind of enemy moved around randomly like an idiot.

TL;DR Design in a few words, for the lazy ones.

Basically, you're put into a maze-like room where enemies roam freely: you must kill all of them before time runs out, hitting them with magic projectiles. The projectiles may rebound against walls, and you can use that fact to your advantage (although that might also lead you to certain death unless you're careful).



Tu sum it all up, despite the obvious limitations and flaws of this initial version I found the final result quite entertaining (okay, I may not be the most objective person to judge it), and I actually think that the complete idea has potential as a real, marketable game, so I'd like to implement the actual version. I was thinking of PC or DS as the platforms of choice, but it might work out on consoles (i.e, XBox Live, PSN network, etc) just as well.