Wednesday, December 28, 2011

Lighting, light map and post processing

Amazingly I got something done today even tho all the kids are here, all 5 of them.

I got the lights to blend better and smoothed them out a bit. The image is with a 150 random lights. It takes about a second to calculate everything, so no waiting.


In the last post I made, There's a picture of the light after only using the bresenham algorithm to check what tiles are directly affected by light. I am still doing that, but right after I do some processing where I check surrounding tiles and spreed the light to unlit tiles. After that I start calculating light based on the tiles corners. I am drawing all tiles with a color value at all 4 corners so it's not always an even color over one tile.

There are still some problems with it, but think I will leave it as it is for now. It will probably not make more people play the game. Game contents are going to bring people back for more, not visual perfection..... I hope.

On a side note, doing the lights was really fun, I have never done that before. It's instant satisfaction when things starts working. There's hundreds of hours of tweaking left, but it's time to move on.

Tuesday, December 27, 2011

Colored lights blending

Apparently I have nothing better to do, so I found a way to blend the colored lights. It's not perfect, but it works well. I also noticed that I will have to do some post processing on my light map to blend the colors better. And my walls pickup the light from a nearby tile now, and it's not the expected effect. They now look like they get colored by a light on the wrong side of the wall.

I think I might skip the wall getting it's color from a nearby tile and work out another way to color them. Right now a "blocked" til cant have a light value calculated for it as it stops the line of sight algorithm. So a special case might be to check the light's effect on a blocked tile even if it's blocked, then save it if the light can reach it.

The light map is only for static lights, I will have to run through a list of dynamic lights and calculate them separately.

Light map and line of sight

I implemented Bresenham's line algorithm and used it to calculate the light's path on the map, then added it to the light map. It needs a bits of smoothing to look good, light spilling over into unlighted tiles. But it works great.

The walls are not affected by the light yet, as they need to check the tile next to it and not it's own til to determine how much light it gets.

I might have to expand my light map to hold a light value for each corner of the tile. It should make it look less like blocks.

I found an easy description of Bresenham's line algorithm here wiki/Bresenhams_line_algorithm just scroll down to the simplification, My version looks like this:

    public static boolean isVisibleFrom(int startX, int startY, int endX, int endY, Map map){
        int dx = Math.abs(endX - startX);
        int dy = Math.abs(endY - startY);
        int sx;
        if (startX < endX)
            sx = 1;
        else
            sx = -1;
       
        int sy;
        if (startY < endY)
            sy = 1;
        else
            sy = -1;
       
        int err = dx-dy;
       
        int mapX = startX;
        int mapY = startY;
        int tempError;
       
        while(true){
            Tile tile = map.getTile(mapX, mapY);
           
            if (tile != null){
                if (tile.isBlocking()) return(false);
            }
           
            if (mapX == endX && mapY == endY) break;
            tempError = 2*err;
           
            if (tempError > -dy){
                err = err - dy;
                mapX = mapX + sx;
            }
           
            if (tempError <  dx){
                err = err + dx;
                mapY = mapY + sy;
            }
        }
       
        return(true);
    }

I basically just runs through my map until i hit a tile that is blocking, then stop.

Line of sight and light

I was working on some light for the game, and have implemented a very simple ambient light, it basically just draws everything with a filter to make it appear darker. It was the first step in my lighting idea. I want to add a light map on top of that so I can pre calculate all static lights and just add those values to the ambient light. That will give me instant light at minimum fps cost. Only lost about 100 fps adding ambient light. I still havn't optimized anything, so still doing a lot of overdraw.

I have added a single light at the start position of the map to show what it looks like. I have turned ambient light down to 0 to better show the light.


It supports colors as well, I can set rgb colors. Right now I am not sure how I can blend them if multiple colored lights are next to each other. But I will figure that out when I get the light map to work.


 The light passes through walls at the moment, but that should be fairly easy to fix by implementing a line of sight algorithm. I am thinking Bresenham's line algorithm, implemented one years ago, worked well back then, so should do the job now as well.


 A line of sight algorithmic can also be used for other things, like making npc's detect the player. Ranged attacks will need it to work. Maybe even only drawing tiles that are visible to the player so he cant see enemies sneaking up on him. A lot of fun possibilities.

I command you to move

I have had a go at creating a very simple command structure that will allow me to just create a command anywhere in the game with a "name" that is the class name that should be executed, a priority that is not used yet and a list of parameters of any type.

The constructor looks like this :

public Command(String name, int priority, Object... obj){
 this.commandName = name;
 this.commandPriority = priority;
 this.parameters.addAll(Arrays.asList(obj));
}

To create a command I just decide on a set of parameters that I would need to get it working and add it to the command list :

Command com = new Command("Move", 0, Globals.NORTH, player);
commands.addCommand(com);

That command moves the player to the north. The actual Move class then checks the map, the player and decides if a move to the north is legal :

public void execute(ArrayList<Object> parameters) {
 Map map = (Map)Globals.gameObjects.get("map");
 GameObject mover = (GameObject)parameters.get(1);
 String direction = (String)parameters.get(0);
 if (moveOutsideMap(mover, direction, map.getMaxMapX(), map.getMaxMapY())) return;
 if (direction.equals(Globals.NORTH)){
 mover.setMapPositionY(mover.getMapPositionY()-1);
and so on......
}

It needs a few checks more to be valid, like is the tile blocked or not. Is there an NPC there blocking the path. Those can be added at a later time.

Just for fun, I added a Teleport command that gets activated when the player presses "t" on the keyboard and sends the player to a random location on the map, it looks like this :

public void execute(ArrayList<Object> parameters) {
 Map map = (Map)Globals.gameObjects.get("map");
 GameObject mover = (GameObject)parameters.get(0);
 int x = (Integer)parameters.get(1);
 int y = (Integer)parameters.get(2);
 if (moveOutsideMap(mover, x, y, map.getMaxMapX(), map.getMaxMapY())) return;
 mover.setMapPositionX(x);
 mover.setMapPositionY(y);
}

As long as I always supply the parameters in the right order, there is no limit to what I can send to a command. All my commands implements an interface with an execute function in it to make sure they can all be executed by the command processor.

 The command processor that extracts commands from the list and executes the execute funtion on the specified command looks like this :

Command command = commands.getNextCommand();
String className = command.getCommandName();
CommandI comI;
try {
 comI = (CommandI) Class.forName("rpe.rpg.game.command.commands." + className).newInstance();
 comI.execute(command.getParameters());
 } catch (InstantiationException e) {
  e.printStackTrace();
 } catch (IllegalAccessException e) {
  e.printStackTrace();
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 }

CommandI is the interface that every command have to implement. All my commands are located in package rpe.rpg.game.command.commands. If that changes later, I will have to find a way of detecting where the specified class is actually located.

Monday, December 26, 2011

Commands or just a big bunch of entangled classes

I have been thinking about how I want to handle the gaming aspects of the game. How to handle player moves, what happens when the player clicks om screen. Can he pickup that item or is that nailed to the ground.

In the past I have just had a bunch of functions in different classes that I could call. On the map I could check if a tile was blocked and then move the player. That meant that everything basically knew something about everything else. That meant that one change could spill over in multiple classes that didn't have anything to do with the original class.
This time I will try to make a command based system. A global commands list is available to all components. They then generate commands depending on what they want done and a commands processor then executes them. It all sounds weary nice, but at the moment, all I have is a vague idea about what it should look like, and no idea how to actually implement it.

My thoughts is that the processor should call a class that have an execute function, passing along any parameters with the command. The function then performs the action.

Lets say the player wants to move one tile to the left. Player presses "A" button on keyboard.
  1. A command with name = move and a string containing direction "west" is added to parameters and the player is added.
  2. Command is placed in the commands list.
  3. Command is extracted by the processor.
  4. Processor determines what class should be called "move" and calls execute with the given parameters.
  5. Move class execute function checks map, moves player
That way I can write a bunch of different classes that perform specific actions without having to know about everything else and if "when" I change something, I only have to rewrite those commands that use it.

Friday, December 23, 2011

How to actually build a dungeon

Have been looking at my random dungeon, and something is wrong with it.

Doors will only fit one person, corridors is the same. You would not be able to move a table through there, so how would they actually work.

The player would only be attacked by one npc at the time. Just stand in a corridor and you will be fairly safe.

The only way around this would be to create double doors and wider hallways. This is somewhat more complex to create than just a random room and a random corridor.

That got me thinking. What if I create a starting room. Then a wide corridor in a random direction. A room at the end of that corridor. Then keep going in sort of the same direction. That will give me a string of rooms that the player needs to move through. Maybe adding a few side rooms here and there. It would give a sense of going somewhere. Could also be used for quests, find a key to unlock a door, just add key before door.

It's something I will change later on, as it will not impact my game that much. I will not have 100 maps that needs changing later. It will just happen when I change my code.

Food for thought. Speaking of food, think the player should have to eat to stay alive.

Dungeone walls

Thought I might add the walls and see how that looks.





It looks okay, but a bit tame. It lacks light and shadow. But that will require me to refactor some parts of my small engine. At the moment my render loop calls the map's render function. That needs changing so that my render extracts information from the map and renders it. Right now, it would be impossible to add the player or monsters unless the map knows all about them, and I don't like my objects knowing to much about each other.

The map looks very compact, so some sort of fog of war might have to be implemented. Adding light might solve it as some parts of the map would be darker that others.

I will definitely have to add a lot of junk to the map to make it look unique. I will not have 100's of tiles to mix as i please. So an overlay on walls and floor might make it look more real. A crack that can be placed on a wall or some fungus growing in a corner. Stuff like that can be reused on a number of tiles to make it look like I have a lot of different graphics.

The tiles I am using have been drawn by a friend of mine. I hope I can convince him to create some more stuff for my small game.

Thursday, December 22, 2011

Random dungeon generation

Random dungeon generation is fairly easy, start by creating a room, find a wall and insert a door. Create a new room or corridor on the other side of the door and repeat. That way every room is connected so the player can get everywhere. Problem is making it look good.

A dungeon generated in this way, will be centered around the first room. It will not be a dungeon that is elongated so that he player will have to walk from one end to the other. Unless the map is narrow and the start room is in one end of the map.

This is my first attempt at a random dungeon. The code is ugly and was just slapped together.It will need some serious re-factoring to make it readable and usable.


It consists of 50 rooms and 50 corridors. Rooms can be connected to each other and corridors can be connected to each other.So you can get a bunch of corridors connecting in different ways. Or just a long corridor protruding from a room. I haven't decided if this is a problem or not, but might keep them as it is very simple way to do it.

Another part of the dungeon





Walls will be added to the render method when i have some graphics to draw. The same goes for doors.

On a side note, when drawing a full screen of tiles and a full 1024X768 image for the frame around the edges, yes yes I know its a waste to draw the entire image. I am running around 900 fps. The second picture is around 1200 fps. These numbers are without any optimizations, so can probably be increased.

Design, do I relay need it or should I just do as I always do

Well, I usually just start programming, as that's what I like, but always find myself adding stuff all the time. Usually stuff that don't fit into what I already have. That forces me to make hacks and take shortcuts to get it working again. It always end the same way, I rewrite it and when I am happy with it, I start the process all over again.

Not this time..... I think.

My design is going to be simple and I will stick to it. What I want is a playable prototype to build experience and get me to my goal. Try to make money of it and see if there is a market for simple home made games.

To keep this simple I will not be creating something real time with fancy animations thousands of npcs on screen and particle effects. It will be a simple version of a very simple game i played many years ago. Champions of Krynn. My game will only have the player controlling one character, he will be centered on the screen. When the player moves one square, npc's move one square. There will only be one class, warrior. Weapons and items should also be randomly generated and try to match the killed npc's level. So that if a high level player kills a low level monster it wont drop anything good, but the other way around, might drop something better than what the player already have.

Picture of Champions of Krynn


Major part of an rpg is gaining experience and skills, so will need to work that in somehow.

My maps will be random generated dungeons. I will not spend a lot of time creating maps. Random dungeons will also make it more fun for me to play as I don't know where everything is located. They will be generated based on something I haven't decided on yet, but if the player revisits a level, it should be the same, except all the monsters have returned.


If time and slick allows, I might add a few effects like light to make everything look better. It will not be a priority, but I will probably add hocks in my rendering loop to allow changing the alpha value of images based on lights.

Anything outside of this, should try to be avoided.

First Slick test and menu

I have successfully tested Slick and found it suitable for a simple game.

I have created a simple menu, it has a 1024X768 image as a background and the "buttons" are just images with some text on. I then change the transparency of the buttons as the mouse moves over, so it looks like they get highlighted.

It's a bit difficult to see, but the frame rate is just under 3700 frames per second. That's okay i guess.

Slick has something called states.It separate different sections of the game from each other. My main menu class implements BasicGameState and ComponentListener.

Images are easy to load
private Image background = new Image("gamedata/menu/menuBackground1024X768.png");

Rendering it is easy as well, I use a color, that has an alpha value of 0.45f to make it a bit darker.
background.draw(0, 0, color);

The mouse over effect is achieved by setting 2 color values with different alpha values
areas[0] = new MouseOverArea(container, newCharacter, 350, 220 , 275, 41, this);
areas[0].setNormalColor(new Color(1,1,1,0.7f));
areas[0].setMouseOverColor(new Color(1,1,1,0.9f));

Then implementing the abstract method componentActivated
if (source == areas[0])
game.enterState(CreateCharacterState.ID, new EmptyTransition(), new EmptyTransition());

It looks promising, just need to find someone who can actually make some descent graphics.

Graphics api

The graphics api I have decided to use is Slick2D, it's a simple set of tools wrapped around the lwjgl OpenGL binding for Java.

It has a few things that are nice to have and will save me a lot of work. There's some simple menu stuff. A way to create multiple scenes, so I can split my game up in sections, like actual game, inventory, menu and so on.

There is an active community around Slick at the time I am writing this, but you should check out before you start using it.

I am not sure what the performance is, but since it's based on open gl, it can't be that bad. I will post some screen shots and information when I get it working.

You can read more about it here http://slick.cokeandcode.com/

To do or not to do

I have been programming for some years now in my spare time. I work as a developer and like to program. My language of choice at the moment is Java.

I have programmed a few games before, but never finished any of them. I made a Boulder dash clone with one of my friends, only needed a few thing to be complete, but never got around to it. I think one of the reasons is that there tends to be a lot of feature creep and new ideas. Biting of more than you can handle is also a major factor in un finished projects.

So this time I have decided to write a simple small rpg, a Rouge like game. And release it on one of the sites that share revenue from ads and see if it's possible to make any money as a single or 2 person group.

It will not be a tutorial on how to write a game, but there will be posts on how i solved some of the problems and what technologies I use.