Jump to content
Sign in to follow this  
Bonuspunkt

Speedmeter

Recommended Posts

NOTE: i did not stop fiddling with the code, and extracted functions to own modules so you need more than one file, and specific file locations etc etc etc.

if you want an up-to-date copy you can download the bundle here

 

draws the player speed on the screen - numeric and as bar

require "base/internal/ui/reflexcore"

local colors = {
    Color(255,0,0), -- red
    Color(255,255,0), -- yellow
    Color(127,255,127)   -- bright green
};
local function colorLerp(colorA, colorB, k)
    return Color(
        lerp(colorA.r, colorB.r, k),
        lerp(colorA.g, colorB.g, k),
        lerp(colorA.b, colorB.b, k)
    );
end

local barFillSpeedMeter = 1000;
local barFillWidth = 500;
local barHeight = 48

local textColor = Color(255,255,255,255);

SpeedMeter =
{
    draw = function()

        -- Early out if HUD should not be shown.
        if not shouldShowHUD() then return end;

        -- Find player
        local player = getPlayer();
        local speed = player.speed;

        nvgFontSize(52);
        nvgFontFace("TitilliumWeb-Bold");
        nvgTextAlign(NVG_ALIGN_CENTER, NVG_ALIGN_MIDDLE );


        local barColor;
        if speed < 320 then
            barColor = colors[1]
        elseif speed < 480 then
            barColor = colorLerp(colors[1], colors[2], (speed - 320) / (480 - 320))
        elseif speed < 520 then
            barColor = colorLerp(colors[2], colors[3], (speed - 480) / (520 - 480))
        else
            barColor = colors[3]
        end

        if speed > 0 then
            nvgFillColor(barColor);
            nvgBeginPath();
            nvgRoundedRect(
                -barFillWidth / 2,
                -barHeight / 2,
                speed / barFillSpeedMeter * barFillWidth,
                barHeight,
                2
            );
            nvgFill()
        end


        nvgFillColor(textColor);
        nvgText(0, 0, math.floor(speed));
    end
};
registerWidget("SpeedMeter");

adapt to your preferences

Share this post


Link to post
Share on other sites

Calling the widget via

ui_show_widget Speedmeter

from the game.cfg...

        if speed < 320 then

yields a

lua: base/internal/ui/widgets_custom/Speedmeter.lua:39: attempt to compare nil with number

error. During the Warmup phase, e.g. when testing/editing a map alone. Seems

local speed = player.speed;

simply contains no value then?

 

 

Learning LUA by reading your source, strange that in many cases the "statements" end on a ";" (like in most modern languages (ANSI C, C++, Java etc.) but not always e.g. in the line:

local barHeight = 48

Is the ; mostly optional in LUA?

Share this post


Link to post
Share on other sites

lerp is provided in reflexCore.lua

function lerp(a, b, k)
    return a * (1 - k) + b * k;
end

k = 0 return a

k = 1 return b

 

so vales between 0 and 1 returns a value between a and b

 

 

and your error is strange and i can't reproduce it :(

local speed = player.speed;
if speed == nil then speed = 0 end;

this should fix it

Edited by Bonuspunkt

Share this post


Link to post
Share on other sites

So your speed meter should be working during FFA Warmup?

-> Yes it should... tested this by manually setting the speed:

local speed = 10; --local speed = player.speed;

Looked up the code:

--------------------------------------------------------------------------------
-- get the player in question (the one we're watching through the camera)
--------------------------------------------------------------------------------
function getPlayer()
    if playerIndexCameraAttachedTo < 1 then
        return nil;
    end

    return players[playerIndexCameraAttachedTo];
end

The getPlayer should actually only work when "spectating" a player... or the comment is worded ambiguously.

 

Seems this is more what should be used:

--------------------------------------------------------------------------------
-- get LOCAL player, this may be different to getPlayer() when we're speccing someone
--------------------------------------------------------------------------------
function getLocalPlayer()
    return players[playerIndexLocalPlayer];
end

Share this post


Link to post
Share on other sites

Yes, just noted that I was still running 0.33.1... and some bug on Steam regarding "Skyrim - Workshop Content" download was blocking the automatic update to 0.33.2... now have the latter installed and your code works. Sorry about all that.

Share this post


Link to post
Share on other sites

BTW... I am sure you have a nice place where you place your widgets on the HUD... posting the achor, offset and scale console commands to add to the game.cfg would surely be appreciated by the folks here at the forum... i.e. to avoid having to fiddle around until it looks OK.

 

Using this for now:

ui_show_widget SpeedMeter
ui_set_widget_scale SpeedMeter 0.5000
ui_set_widget_anchor SpeedMeter 0 0
ui_set_widget_offset SpeedMeter 0.0000 100.0000

Share this post


Link to post
Share on other sites

The only problem with this is that it's getting your speed in the vertical axis as well, so when you jump or fall it spikes.

 

Is it possible to separate the axes? A height meter would be cool too

Share this post


Link to post
Share on other sites

it would be nice if the widget could consume the value ui_set_widget_anchor

 

I found this code in the thread:

function SetSettings()
    consolePerformCommand("ui_set_widget_anchor ItemReminder 0 0");
    consolePerformCommand("ui_set_widget_offset ItemReminder 0 50");
    consolePerformCommand("ui_hide_widget PickupTimers");
end
SetSettings();

I think that is what you were looking for.

Share this post


Link to post
Share on other sites

I found this code in the thread:

function SetSettings()
    consolePerformCommand("ui_set_widget_anchor ItemReminder 0 0");
    consolePerformCommand("ui_set_widget_offset ItemReminder 0 50");
    consolePerformCommand("ui_hide_widget PickupTimers");
end
SetSettings();

I think that is what you were looking for.

Oh, cool. People who make HUDs should include this in any widget they mess with so you can just plop in HUDs and not have to worry about all your console commands being correct in your game.cfg

Share this post


Link to post
Share on other sites

We really need player velocity exposed.  Having the vertical component of our velocity included in the given speed makes this speedometer mostly useless in its current form.

 

Glad to see this done so quickly though-- I had thought to do it myself, but I didn't get a chance before this was posted :)

Share this post


Link to post
Share on other sites

Is the ; mostly optional in LUA?

 

You never need to use semicolons to end statements in Lua, but you can use them if you want to put multiple statements on the same line or avoid ambiguous statements.

Share this post


Link to post
Share on other sites

We really need player velocity exposed.  Having the vertical component of our velocity included in the given speed makes this speedometer mostly useless in its current form.

 

Glad to see this done so quickly though-- I had thought to do it myself, but I didn't get a chance before this was posted :)

 

I'd like to see the speed separated in its components too. In its current state the value isn't of that much use. 

 

Like AEon said, there will be times when it is useful to have the sum of the components, but there are also times where you don't want to have the sum of the components, but only the horizontal or vertical speed.

 

I don't think there is a reason not to expose the other values in the future.

Share this post


Link to post
Share on other sites

Tried your latest version... nicely rounded off corners... since I skale down your widget with

ui_show_widget SpeedMeter
ui_set_widget_scale SpeedMeter 0.5000
ui_set_widget_anchor SpeedMeter 0 1
ui_set_widget_offset SpeedMeter 0.0000 -160.0000

the rounding barely, if at all, shows. No matter though.

 

http://www.mediafire.com/view/6wh4v3m3l33b9mq/reflex_2015-04-11_18-33-48-47.jpg

 

I still use the default HUD, chosen weapon/ammo widget larger after the bottom of the screen. It might be nice to have a black alpha outline "frame", behind your speedmeter to match the look of the default health and armour bars. I have not yet looked up how they did it in Reflex... but maybe its something you might like to do yourself.

 

Notice the black outline, in the bottom center, the "250"... that might be a good thing to do for the speed number as well, to make it easier to read once the speedmeter bar reached light green. Oh, and the speedmeter number showul be centered vertically, 1 unit or so up (y-=1).

 

I might try all these things myself if you have other pressing things to do.

Share this post


Link to post
Share on other sites

OK, could not resist... tweaked your code to show:

  • Speed number has shadow, reads slightly easier on the light green bar.
  • Speed bar has default outline, using black with 128 alpha used in the default HUD.
  • Vertically aligned the text to bar, y-=2 offset.
  • Updated code to show the 1000 max speed for the background frame.
  • This background bar is always shown, also at speed 0.

AEon's Speedmeter update screenshot (old)

AEon's Speedmeter update shot (new)

require "base/internal/ui/reflexcore"

local colors = {
    Color(255,0,0),     -- red
    Color(255,255,0),   -- yellow
    Color(127,255,127)  -- bright green
};

local function colorLerp(colorA, colorB, k)
    return Color(
        lerp(colorA.r, colorB.r, k),
        lerp(colorA.g, colorB.g, k),
        lerp(colorA.b, colorB.b, k)
    );
end

local barFillSpeedMeter = 1000;
local barFillWidth = 500;
local barHeight = 48

local frameColor = Color(0,0,0,128);
local frameWidth = 5;
local frameHeight = 4;
local textShowdowOffset = 2;    -- for ui_set_widget_scale SpeedMeter 0.5000, else use 1

local textColor = Color(255,255,255,255);

SpeedMeter =
{
    draw = function()

        -- Early out if HUD should not be shown.
        if not shouldShowHUD() then return end;

        -- Find player
        local player = getPlayer();

        --if not player then return end

        local speed = player.speed;
        --if not speed then speed = 0 end

        nvgFontSize(52);
        nvgFontFace("TitilliumWeb-Bold");
        nvgTextAlign(NVG_ALIGN_CENTER, NVG_ALIGN_MIDDLE );

        local barColor;
        if speed < 320 then
            barColor = colors[1]
        elseif speed < 480 then
            barColor = colorLerp(colors[1], colors[2], (speed - 320) / (480 - 320))
        elseif speed < 520 then
            barColor = colorLerp(colors[2], colors[3], (speed - 480) / (520 - 480))
        else
            barColor = colors[3]
        end

        -- Background frame
        nvgFillColor(frameColor);
        nvgBeginPath();
        nvgRoundedRect(
            -barFillWidth / 2 - frameWidth / 2,
            -barHeight / 2  - frameHeight / 2,
            1000 /  barFillSpeedMeter * barFillWidth + frameWidth,
            barHeight + frameHeight,
            5
        );
        nvgFill();

        if speed > 0 then
            -- Bar
            nvgFillColor(barColor);
            nvgBeginPath();
            nvgRoundedRect(
                -barFillWidth / 2,
                -barHeight / 2,
                speed / barFillSpeedMeter * barFillWidth,
                barHeight,
                5
            );
            nvgFill()
        end

        local currentspeed = math.floor(speed);

        -- Speed number
        nvgFillColor(frameColor);
        nvgText(textShowdowOffset, -2+textShowdowOffset, currentspeed);

        nvgFillColor(textColor);
        nvgText(0, -2, currentspeed);
    end
};

registerWidget("SpeedMeter");

Share this post


Link to post
Share on other sites

making a correct position is imho current not really possible, because you cant access the ui_set_widget_align. - currently doing something like this is pretty much pointless

 

afaik there is no limit to playerspeed, so a circle will at a certain speed be just full, where the bar will just overflow

Share this post


Link to post
Share on other sites

I was wondering about 1000+ speeds... visually I'd cut it off for the bar... one might then colour the full bar in some way... maybe.

 

An idea for +1000 speeds you could make is so that the bar overflows (something like the default health bar when mega health is acquired). That's at least what I thought about doing when I can actually code it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×