Pages: [1] 2
  Print  
Author Topic: Filling a rectangle with the background color  (Read 2572 times)
Askr
Protector
****
Posts: 30


View Profile
« on: February 06, 2012, 01:55:49 AM »

Hej,

I'm refering to this page in the documentary: http://doryen.eptalys.net/data/libtcod/doc/1.5.1/html2/console_advanced.html?c=false&cpp=false&cs=true&py=false&lua=false#0
Somehow I can't get behind the concept of this method. I've got an off-screen console named hud with a darkgrey background and I'm trying to place a red rectangle onto it to resemble the player's health. Changing the background color of hud obviously changes the background color of the whole console, so even if the method works there's no way to distinguish it from the rest of the console. What exactly am I doing wrong here?

Code:
            hud.clear();
            hud.print(1, 1, player.name);
            hud.setBackgroundColor(TCODColor.darkerRed);
            hud.rect(2, 2, HUD_WIDTH/2, 2, false);

I suppose I could just create a new off-screen console for each colored rectangle I need, but that somehow renders the method useless, doesn't it?

Thanks in advance. Smiley
Logged
donblas
Moderator
Master
*****
Posts: 365


View Profile WWW
« Reply #1 on: February 06, 2012, 04:50:22 PM »

I'll be honest, it's been long enough since I've touched libtcod that I don't know the answer to your question off the top of my head.

However, since the same function exists in C/C++, you could repost your question to the general forum and see if anybody knows the answer. The C# version just wraps the C API.

If nobody gets back to you, e-mail me at chris dot hamons at gmail dot com and I'll dig into libtcod's source.

Hope That Helps,
--Chris
Logged
jice
Administrator
Master
*****
Posts: 1455


View Profile WWW
« Reply #2 on: February 06, 2012, 05:50:01 PM »

The code seems ok. You should get a red rectangle on your console. What do you get ? The whole console is darkerRed ?
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #3 on: February 07, 2012, 10:55:01 PM »

Quote
The whole console is darkerRed ?
This. There is, however, also a rectangle, that's darkerRed. But since it's the same color as the whole console you can't see it, unless you, for example, place it above of text. I can provide a screenshot if that'd be of use.

By the way, I can't print '%', it just shows nothing. I also tried (char) 37 [% according to terminal.png], but it prints nothing visible aswell. Very confusing.
« Last Edit: February 07, 2012, 11:21:17 PM by Askr » Logged
jice
Administrator
Master
*****
Posts: 1455


View Profile WWW
« Reply #4 on: February 09, 2012, 02:44:51 PM »

Is the code called in some loop ? Once you set background color as darkerRed, clear will fill the console with darkerRed. Did you try that :

Code:
            hud.setBackgroundColor(TCODColor.darkGrey);
            hud.clear();
            hud.print(1, 1, player.name);
            hud.setBackgroundColor(TCODColor.darkerRed);
            hud.rect(2, 2, HUD_WIDTH/2, 2, false);

To print %, use "%%" syntax. Check http://linux.die.net/man/3/printf for details.
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #5 on: February 09, 2012, 05:01:55 PM »

Quote
Is the code called in some loop ?
Yes. It's in a function called render_hud() that is called within the render_screen() method, which is called before the player takes his turn.

Code:
private static TCODConsole hud = new libtcod.TCODConsole(HUD_WIDTH, HUD_HEIGHT);
private static TCODConsole con = new libtcod.TCODConsole(SCREEN_WIDTH, SCREEN_HEIGHT);

private static void render_screen() {
            con.clear();
            render_hud();
            libtcod.TCODConsole.blit(hud, 0, 0, HUD_WIDTH, HUD_HEIGHT, con, MAP_WIDTH + 2, 1);
            libtcod.TCODConsole.blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, TCODConsole.root, 0, 0);
            libtcod.TCODConsole.flush();
}

private static void render_hud() {
            hud.setBackgroundColor(TCODColor.darkGrey);
            hud.clear();
            hud.print(1, 1, player.name);
            hud.setBackgroundColor(TCODColor.darkerRed);
            hud.rect(2, 2, HUD_WIDTH / 2, 2, false);
}

static void Main(string[] args) {
            con.setBackgroundColor(TCODColor.darkerGrey);
            con.clear();
            hud.setBackgroundColor(TCODColor.darkestGrey);
            hud.clear();
            do {
                        render_screen();
            } while ();
}

I stripped the code from all the parts not having anything to do with the hud and con console. When I run this, the problem still remains.

Quote
To print %, use "%%" syntax. Check http://linux.die.net/man/3/printf for details.
Thanks!
« Last Edit: February 09, 2012, 05:03:44 PM by Askr » Logged
jice
Administrator
Master
*****
Posts: 1455


View Profile WWW
« Reply #6 on: February 10, 2012, 12:22:24 PM »

Maybe I'm missing something, but it appears to me that whatever is in hud, you overwrite it with what's in con...

Code:
libtcod.TCODConsole.blit(hud, 0, 0, HUD_WIDTH, HUD_HEIGHT, con, MAP_WIDTH + 2, 1);
libtcod.TCODConsole.blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, TCODConsole.root, 0, 0);
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #7 on: February 11, 2012, 12:22:41 PM »

Quote
Maybe I'm missing something, but it appears to me that whatever is in hud, you overwrite it with what's in con...
I don't see what you're seeing. Embarrassed

As far as I know the code works this way (please correct me, if I'm wrong):
The first line puts all the contents (x1:0, y1:0, to x2:HUD_WIDTH, y2:HUD_HEIGHT) of the off-screen console "hud" into the off-screen console named "con", right beside another off-screen console named "map".
The second line puts all the contents of the off-screen console "con" onto the root-console. I added a screenshot so you can see how the code behaves with my current code:
http://i.imgur.com/hMXqW.png

Also this should make it more clear, what I'm trying to do. (Could've thought of this earlier, my bad)
« Last Edit: February 11, 2012, 12:26:05 PM by Askr » Logged
dalord
Swordsman
***
Posts: 22


View Profile
« Reply #8 on: February 12, 2012, 01:38:53 AM »

Code:
private static TCODConsole hud = new libtcod.TCODConsole(HUD_WIDTH, HUD_HEIGHT);
private static TCODConsole con = new libtcod.TCODConsole(SCREEN_WIDTH, SCREEN_HEIGHT);

private static void render_screen() {
            con.clear();
            render_hud();
            libtcod.TCODConsole.blit(hud, 0, 0, HUD_WIDTH, HUD_HEIGHT, con, MAP_WIDTH + 2, 1);
            libtcod.TCODConsole.blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, TCODConsole.root, 0, 0);
            libtcod.TCODConsole.flush();
}

private static void render_hud() {
            hud.setBackgroundColor(TCODColor.darkGrey);
            hud.clear();
            hud.print(1, 1, player.name);
            hud.setBackgroundColor(TCODColor.darkerRed);
            hud.rect(2, 2, HUD_WIDTH / 2, 2, false);
}

I think I know what the problem is, and it revolves around the blit function. I can't see anywhere on the docs but when you blit does the rest of the console get blitted as the background color? I mean the stuff that isn't explicitly set to anything? If this is the case try setting the background color just after the rectangle is drawn eg.
Code:
private static void render_hud() {
            hud.clear();
            hud.print(1, 1, player.name);
            hud.setBackgroundColor(TCODColor.darkerRed);
            hud.rect(2, 2, HUD_WIDTH / 2, 2, false);
            hud.setBackgroundColor(TCODColor.darkGrey);
}
This means that when you blit the console it is already set back to the original color.

Hope this helps Smiley

Cheers Dalord
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #9 on: February 12, 2012, 02:50:00 AM »

Sorry, I'm lost here. Neither do I get it myself, nor does your post help me anyhow. Sad
I played around with the method myself too, even created a new project to be sure it doesn't have anything to do with my game. Either I really don't get something or the method is bugged. Huh
Logged
dalord
Swordsman
***
Posts: 22


View Profile
« Reply #10 on: February 12, 2012, 05:30:08 AM »

I can't really see any thing else wrong with it, but the method does work, here's the relevant code from my project:

Code:
void render_bar(int x, int y, int total_width, std::string name, int value, int max, TCODColor back_color, TCODColor bar_color)
{
    int bar_width = int(float(value)/max*total_width);

    panel->setBackgroundColor(back_color);
    panel->rect(x,y,total_width,1,false);
    if (bar_width > 0){
        panel->setBackgroundColor(bar_color);
        panel->rect(x,y,bar_width,1,false);
    }

    panel->setForegroundColor(TCODColor::white);
    std::string label = name + " " + to_string(value) + "/" + to_string(max);
    panel->printCenter(x+total_width/2,y,TCOD_BKGND_NONE,label.c_str());
    panel->setBackgroundColor(TCODColor::black);
}

and I attached an image of the output in game.


* health_bar.png (9.08 KB, 640x400 - viewed 110 times.)
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #11 on: February 12, 2012, 01:40:34 PM »

I just took your code and modified it so it can be run within my test project, but it did nothing visible. Then I tried to go through the relevant part of the python tutorial, but that didn't work as well.

Here's the code I wrote and a screenshot of the output:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using libtcod;

namespace ConsoleApplication1
{
    class Program
    {
        private static int SCREEN_WIDTH = 128;
        private static int SCREEN_HEIGHT = 78;
        private static int PANEL_HEIGHT = 20;
        private static TCODConsole panel = new TCODConsole(SCREEN_WIDTH, 10);

        static void Main(string[] args)
        {
            TCODConsole.initRoot(SCREEN_WIDTH, SCREEN_HEIGHT, "test", false);
            render_bar(0, 0, 10, "test", 5, 10, TCODColor.lightRed, TCODColor.darkRed);

            TCODConsole.blit(panel, 0, 0, SCREEN_WIDTH, PANEL_HEIGHT, TCODConsole.root, 0, 0);
            TCODConsole.flush();

            TCODConsole.waitForKeypress(true);
        }

        private static void render_bar(int x, int y, int total_width, string name, int value, int maximum, TCODColor bar_color, TCODColor back_color)
        {
            int bar_width = (int) (value / maximum * total_width);

            panel.setBackgroundColor(back_color);
            panel.rect(x, y, total_width, 1, false);

            panel.setBackgroundColor(bar_color);
            if (bar_width > 0)
            {
                panel.rect(x, y, bar_width, 1, false);
            }
            panel.setForegroundColor(TCODColor.white);
            panel.print(x + total_width / 2, y, name + ": " + value.ToString() + "/" + maximum.ToString());
        }
    }
}

Output

I also tried putting panel.clear() in some different places, but this only results in outputs like this: put after panel.rect(...) & put after render_bar(...)

It's just no use; whatever I try panel.setBackgroundColor() ALWAYS fills the whole off-screen console, overwriting any other color that may have been used by panel.rect().
« Last Edit: February 12, 2012, 01:49:53 PM by Askr » Logged
Jotaf
Global Moderator
Master
*****
Posts: 1181


View Profile
« Reply #12 on: February 12, 2012, 05:12:28 PM »

This is weird, but it reminds me of when we renamed functions like setBackgroundColor to setDefaultBackground. (The idea was that some functions had similar names that were confusing). Maybe that's the problem here, either on the application side or the C# wrapper?

Also it might be worth it to try an even more stripped-down application, just initialize libtcod and draw a single rectangle, see if it works. Then move on to drawing it to an off-screen console. Without any of the HP bar stuff...
Logged
Askr
Protector
****
Posts: 30


View Profile
« Reply #13 on: February 12, 2012, 07:49:26 PM »

Quote
Also it might be worth it to try an even more stripped-down application, just initialize libtcod and draw a single rectangle, see if it works. Then move on to drawing it to an off-screen console. Without any of the HP bar stuff...
I did that right now, coming up with the following code:
Code:
           TCODConsole.root.setBackgroundColor(TCODColor.red);
            TCODConsole.root.rect(10, 5, 8, 4, false, TCODBackgroundFlag.Overlay);
Mind the BackgroundFlag.Overlay, that I only accidentally noticed. Apparently that did the trick. Screen included. Cool

But since I've been on this issue for almost a week now, I came up with a temporary fix that somehow began to appeal to me more than the health bars.
You see the little hearts above the player's stats on the screenshot? I think I'm going to use them. And since I don't think it's a big enough question for it's own thread:

I made a customization of the template.png (view here), that has one row more than the original. I use the following line of code to initialize:
Code:
TCODConsole.setCustomFont("terminal2.png", (int) libtcod.TCODFontFlags.LayoutAsciiInRow, 16, 17);
I print the characters by using putChar(x, y, c); but apparently only the first character of the last row can be printed; for every character following c=255 it just starts counting from the top, as if it's c=0. What am I doing wrong here? I've never had to deal with something like this so I'm clueless.
I found out it's working when I put "TCODRendererType.SDL" in the TCODConsole.initRoot(); -- This kind of stuff should really go in the documentary. Wink

Thanks for everyone's help! Smiley
« Last Edit: February 13, 2012, 06:36:22 PM by Askr » Logged
Jotaf
Global Moderator
Master
*****
Posts: 1181


View Profile
« Reply #14 on: February 19, 2012, 06:53:42 PM »

Great, you fixed it! Cool Yes, basically you should use SDL by default, and only try the other renderers if you need speed and you don't get any glitches (like this one) -- it's pretty hard to make them work on all systems perfectly...
Logged
Pages: [1] 2
  Print  
 
Jump to: