Tuesday, February 26, 2013

I'm back.... sort of.

Hey people I'm back again, but not in the sense that I will continue this blog, but I will start one about Unity3d and the stuff I am making there.

After messing around in Unity for a while I decided to create a game for Android devices and since I am a fan of Dungeon Crawlers I started making one. It's based on the stuff in this blog about random dungeon generation.

The Dungeon Beta is the name and as the name suggests it's a work in progress that is already available on the android market. Being a beta theres a lot of things changing and you may loose your character from time to time when larger updates gets released.

You can find my new blog here : Game Creation And Programming In Unity3d

It's new, so only a couple of posts so far.

Best regards

Tuesday, March 20, 2012

God or bad news

I have some good or bad news depending on how you see it.

I have some how convinced my 3d artist friend to create some models for a tower defense game. This means that I will not have time for my own little project, and I will be moving to 3d for that project.

So good news is that I have models to play with, bad news is that this project is shelved for a longer time than first expected.

Tuesday, March 6, 2012

Spring is here

Well almost here anyway, that means that I have a lot of things to do in the garden and around the house, so it will be a bit quite on this blog for a while.

My little project is not scraped, it's just dormant.

Wednesday, February 22, 2012

More items and player image

I added some more items "feet and head", they have the same item types as the other, iron, steel, dwarven and so on. They can be equipped as well and so can the chest armor now. All I need is pants and shield or other left hand items for a full set of drops. It's coming along quite nicely and all items that get equipped or unequipped change the players stats. I want to add more items like books "inc xp when read", postions "permanent inc of str, int" to allow player to gain extra stats from drops.

Why yeesssss, I drew them all my self, how did you know?

I added a player image so that I could remove the red square in the center. He get's colored by the lightmap when the player move around. And yes, he's not pretty and only point in one direction, but that's all you get from a free game :-)

So what's the next step in my development. I think it's time for some combat. It's going to be simple, walk up to a monster and then walk into it until you or the monster is dead. Should be fairly simple to implement, all I need now are some cool drawings of monsters........ Hmmm, could just reuse the player image for all monsters. That's a great idea, or not :-)

And  I should probably change the lighting to something more dungeon like instead of the disco lighting I have now. Some torches might be god, with lights of course.

Tuesday, February 21, 2012

Equipping weapons and bug hunting

Bug hunting, sounds more exiting than it is, and I am not talking about hunting monsters.

I had an annoying bug where chests and bags would not be removed when it was empty. As there are no way to distinguish between a chest that's empty and one that got items in it, I would need to remove them or the player would have to spend a lot of time checking empty chests for missed loot. It's fixed now, turned out that I didn't remove it correctly from the ItemGroupList that's controlled by the map.

I added the possibility to equip items. At the moment its just the right hand that's working, but all the basic code for adding item effects to the player like changing armor class, damage, strength and so on is in place. I also added swapping items so that the player don't have to place the item in the inventory before picking up an equipped item, that also goes for items in the inventory.

So my inventory looks like it did last time I showed it, added some stats in the top part to show effects of using items.

 I drank a potion from the inventory by right clicking it and equipped an iron mace that increased the damage from 1-2 to 2-6, mace doing 1-4 damage and unarmed player doing 1-2.

Swapped iron mace to a dwarven  shortsword and thereby increasing my damage. All seems to work fine, just need to add the other items and create more items that can be randomly generated.

Might switch player stats and item stats to float to give more variety, player doing 1.5 damage and item doing 6.6 with monsters having float health as well. Will make item hunting better as you can find more items without drastic increases in damage. Mace 1.0/4.0 dam to 2.0/5.0 dam, it's a lot of possibilities compared to 1/4 dam to 2/5 dam.

Just noticed that I have 2 slots for the feet, probably going to remove one, and might add slots for rings and necklace. No rpg is complete without magic rings.

Friday, February 17, 2012

Not switching technologies

I have decided not to switch technologies and keep using slick and java to create my game.

I have over the last week experimented with Unity 3D and it's a fantastic tool for creating 3d games. If you have access to 3d models "an artist" you can in no time create a basic game that you can keep expanding on.

I created a flat box that was the ground, a player controller to move the camera around, some objects that I created in max and added some scripts to objects allowing the player to move them around. It's just a matter of writing more scripts and adding them to the player or objects to keep evolving the game. Fast and fun.

The reason why I am not using it is that I like programming, and there's not a lot of that in Unity. Granted, you can write a lot of scripts in java script or c#, but I spend a lot of time manipulating 3d objects in the editor and creating stuff in a 3d modeling program when I would rather be programming.

My pace will slow down a bit from now on as I have a lot of other things on my plate at the moment, but hoping for a bit of time this weekend. Would be nice to add some unholy monsters that are in dire need of some smiting :-)

Monday, February 13, 2012

How to draw isometric tile map

Drawing an isometric map is not that different from a regular tile map. Granted there are a bit more going on when calculating where to draw the next tile on the screen, but traversing the map is the same.

On a regular tile map, you start by drawing the tile furthest away so that you don't overwrite tiles that have already been drawn. It's the same with isometric. In your head, keep thinking of the map as a 2 dimensional array where you start by drawing all tiles on the x axis and then increasing y and draw all tiles along the x axis on the line. It's the same thing you do with isometric. There are other ways, but this is the easiest one, at least I think so. The other one involves even and odd lines and stepping through the map in a strange way.

Now you need to draw them on the screen, and that is where the tricky part is. I have added my code to draw the floor, see it below. There are surprisingly..... comments in it, how did that happen?

The code that implements this.
private void drawFloor(){

    // Get player position, only used if player is always at the center of the screen
    int mapDrawCenterX = player.getMapPositionX();
    int mapDrawCenterY = player.getMapPositionY();

    // how many tiles to draw on either side of the player   
    int startMapX = mapDrawCenterX - Globals.DRAW_TILES_X;
    int startMapY = mapDrawCenterY - Globals.DRAW_TILES_Y;
    int endMapX = mapDrawCenterX + Globals.DRAW_TILES_X +1; // +1 is to create a center tile for player
    int endMapY = mapDrawCenterY + Globals.DRAW_TILES_Y +1; // +1 is to create a center tile for player

    // the first tile to draw
    int mapX = startMapX;
    int mapY = startMapY;

    // displacing the drawing area so that it's don't start at the top left of the screen
    int drawStartX = 512;
    int drawStartY = -250;

    int drawX = drawStartX;
    int drawY = drawStartY;

    int linesDone = 0;
    boolean done = false;
    while (!done){

        // Check if this tile is inside the map, check if the drawing coordinate is inside screen
        if ((map.isInsideMap(mapX, mapY)) && (drawX <= 1024 || drawY <= 768) && ((drawX + Globals.FLOOR_TILE_SIZE_X + Globals.FLOOR_TILE_PADDING_X > 0) && (drawY + Globals.FLOOR_TILE_SIZE_Y + Globals.FLOOR_TILE_PADDING_Y > 0))){

            // Get the tile and check if there is an image to draw. -1 means nothing there.
            Tile tile = map.getTile(mapX, mapY);

            if (tile.getImageIndex(Tile.FLOOR) != -1){
                Image floor = map.floorImageList.getImage((tile.getImageIndex(Tile.FLOOR))).getImage();

                // Get lightmap corners for this tile
                float[][] lightMapColor = lightMap.getLightCorner(mapX, mapY);
                // Set image corners to the lightmap corners.
                floor.setColor(0, lightMapColor[0][0], lightMapColor[0][1], lightMapColor[0][2], 1.0f);
                floor.setColor(1, lightMapColor[1][0], lightMapColor[1][1], lightMapColor[1][2], 1.0f);
                floor.setColor(2, lightMapColor[2][0], lightMapColor[2][1], lightMapColor[2][2], 1.0f);
                floor.setColor(3, lightMapColor[3][0], lightMapColor[3][1], lightMapColor[3][2], 1.0f);

                // Finally draw image
                floor.draw(drawX, drawY);

        // step along the x axis of the map

        // Move drawing "pointer" to the next tile, half tile length on x and half tile height on y
        drawX += (Globals.FLOOR_TILE_SIZE_X + Globals.FLOOR_TILE_PADDING_X)/2;
        drawY += (Globals.FLOOR_TILE_SIZE_Y + Globals.FLOOR_TILE_PADDING_Y)/2;

        // Nothing more on this x line on map, starting on next line
        if (mapX >= endMapX){

            mapX = startMapX;

            // black magic moving the drawing pointer to the start of the next line ;-)
            drawX = drawStartX - (((Globals.FLOOR_TILE_SIZE_X+Globals.FLOOR_TILE_PADDING_X)/2)*linesDone);
            drawY = drawStartY + (((Globals.FLOOR_TILE_SIZE_Y+Globals.FLOOR_TILE_PADDING_Y)/2)*linesDone);

        //Check if we are done and end the loop
        if (mapY >= endMapY)
            done = true;

There are probably a lot of optimizations that can be done to it, I haven't looked into it yet as the game was running fast enough as it is. Besides, don't spend time optimizing stuff before it's necessary, and use a profiler to identify bottlenecks.

There's some stuff there you cant see, like the tile padding. I use that as my tiles don't connect directly, there is a 2 pixels gap between them on the x axis so that the tile below fit's in it. See pictures below.

The tiles are 62*32 pixels.

So when adding more rows of tiles they fit into the 2 pixel gap on the x axis.

The 2 pixel gap is not something I came up with, it's a friend of mine. He's a graphics artist and it all adds up in the end.

Hope that helped, please ask if you have any more questions.