# Design Windows-like pause menu and color computations

990 views

Its function is to be a... pause menu. (I don't know what you expected...)

## The design

Because our game is going to be really Vaporwave, we knew that the visual had to be on point.

We ended up trying a classic Windows-like design with header bars and everything, but with a twist...

Here's the result:

(Note that not all buttons are fully functioning. Also, the seed isn't actually used in the generation)

The idea is that this window appears when the player pauses. It takes the form of a popup with fully functional tabs.

We also plan to let the player easily navigate through the tabs with keyboard (or buttons, in the case of a controller) shortcuts.

In addition, our game uses palettes, so the GUI elements are colored according to the active palette.

Here's a example with a different palette:

## LESS-like color computations

You may have noticed that there is a difference between each palette (for example, the title of the window has changed color). This is done by a beautiful library that I built for our project.

Because I was a web developer for about 2 years, I already knew (and worked with) CSS compilers like SASS and LESS. My library is strongly inspired these compilers. Especially LESS.

### The luma value

For this reason, I knew there was a way to know if a text of a given color would be readable when displayed on a given background. This feature is present in vanilla LESS : it's called "contrast"

That function uses the luma values (sometimes called "relative lightness" or "perceived luminance") of colors. This small practical value describes the perceived luminance of a color, which means that particularly brightly perceived colors (such as lime green or yellow) gets higher luma values than other colors (red or brown) despite their real lightness value.

Here's how I compute a given color's luma value:

Color color = Color.GREEN; // Fictionnal class, but it stores each components as floating points values form 0 to 1

float redComponent, blueComponent, greenComponent;

if (color.r < 0.03928f){
redComponent = color.r / 12.92f;
} else {
redComponent = Math.pow((color.r + 0.055f) / 1.055f, 2.4f);
}

if (color.g < 0.03928f){
greenComponent = color.g / 12.92f;
} else {
greenComponent = Math.pow((color.g + 0.055f) / 1.055f, 2.4f);
}

if (color.b < 0.03928f){
blueComponent = color.b / 12.92f
} else {
blueComponent = Math.pow((color.b + 0.055f) / 1.055f, 2.4f);
}

float luma = (0.2126f * redComponent) + (0.7152f * greenComponent) + (0.0722f * blueComponent);

The actual luma computation is fully describe here.

With that luma value, we can then check and compare the contrast between 2 colors:

float backgroundLuma = getLuma(backgroundColor) + 0.05f;
float textLuma = getLuma(textColor) + 0.05f;

float contrast = Math.max(backgroundLuma, textLuma) / Math.min(backgroundLuma, textLuma);

With that, we can choose between tow color by picking the one with the lowest contrast:

Color chosenTextColor = getContrast(backgroundColor, lightTextColor) > getContrast(backgroundColor, darkTextColor) ? lightTextColor : darkTextColor;

This can give us a lot of flexibility: especially since we use many different color palettes in our game, and each with different luma values.

This, along with more nice LESS colors functions, can make coloring components a breeze.

Just for example, I've inverted our color palette texture and these are the results:

Yes, it looks weird, but notice how each component is still fully readable.

Paired with our dynamic palette, color computation is now really easy and flexable.

Wow! Quite a beautiful game you got there, my friend. But did you know you could buy Skyrim VR Ultimate Edition on your smart fridge now? I wonder if your game can compete against that.

- Rod Broward, independent video game journalist

57 minutes ago, thecheeselover said:

This looks like a clean man.

## Create an account

Register a new account

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• ### Similar Content

• By jb-dev
This is how a mall looks like when a punk breaks one of its window.
What the image doesn't tell you is that a loud alarm is being blasted trough your ears, too!

i don't know.

What i am doing is, I have a gameObject class which is having four components
class gameObject
{
public:
#define MAX_COMPONENT 4
unsigned int components[MAX_COMPONENT];
gameObject()
{
for(int i=0;i<MAX_COMPONENT;i++)
{
components=0;
}
//parent_id=-1;
}
};
i don't use inheritance, Whenever i make the new game entity i add an gameObject in the gameObjectManger class using the game entities constructor
with all of its components filled at the time of game entity creation like index for rigid body , mesh and etc.
Then i use these gameObjects at individual systems to run the game like below
// For renderer
for(unsigned int i=0;i<manager->gameObjects.size();i++)
{
unsigned int meshIndex = manager->gameObjects.components[MY_MESH]; //mesh data
mat4 trans=(*transforms)[bodyIndex];// The transformation matrix extracted and spitted out by the the Physics engine
mesh_Entries[meshIndex].init();
GLuint lMM  = glGetUniformLocation(programHandle,"Model");
glUniformMatrix4fv(lMM, 1, GL_FALSE,&trans[0][0]);
mesh_Entries[meshIndex].bindTexture();
glBindBuffer(GL_ARRAY_BUFFER, mesh_Entries[meshIndex].getVertexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_Entries[meshIndex].getIndexBuffer());
pickColor=vec4(1.0f);
pickScale=mat4(1.0f);
lMM  = glGetUniformLocation(programHandle,"pick");
glUniform4fv(lMM,1,&pickColor[0]);
lMM  = glGetUniformLocation(programHandle,"pickScale");
glUniformMatrix4fv(lMM,1,GL_FALSE,&pickScale[0][0]);
// This is very basic rendering since all object's indices are treated as
// indexed based. Stored in element buffer with indices and vbo with vertices
// for each single gameObject having their own VAO and IO. Optimization need to be done later on.
glDrawElements(
GL_TRIANGLES,                                // mode
mesh_Entries[meshIndex].getIndicesSize(),    // count
GL_UNSIGNED_SHORT,                           // type
(void*)0                                     // element array buffer offset
);
}
but i am not getting it how to add a new component like LogicalData to the gameObject not about how to point from gameObject but how to build one
is this should be my approach
struct LogicalData
{
float running_speed;
vec3 seek_position;
vec3 attack_point;
};
Character : public CharacterController
{
private:
gameObject* me;
public:
// methods to manipulate gameObject content using the component id for each component in their container
// i.e is to update component[LOGICAL_DATA] in the gameLogicContainer
};
and then a global container which hold this logical data and every entity has a id to it using gameobjects
or i should not be doing this at all. i can just put all logical data  into the any game entity like this and push the physics and rendering data back to gameobject
Character : public CharacterController
{
private:
float running_speed;
vec3 seek_position;
vec3 attack_point;
public:
// methods to manipulate above
};
Any comments will be greatly appreciated.

• I created this post due another radix sort post for CPU. This is Radix Sort for GPU. Able achieve 900 Mkeys/S, and sorting 8 million elements in 9.3ms (on RTX 2070). Written on C++ with Vulkan API and GLSL. Based on bitfield and warp hacks. For understand this shader code, need very good knowledge of bitfields and GPU subgroup. For NVIDIA, also need knowledge of subgroup partition extension.
Stable: yes
Parallel: yes, vector supported
Bit width: 8-bit (Turing), 2-bit (other), can be changed
Device type: GPU
Also, how to get fastest GPU radix sort ever?

• I'm making a research about using fonts in video games.
What are possible font formats that are used in games? What are their technical advantages and disadvantages?
Thank you for the help!

• i am confused what i am doing is right or wrong?
currently storing the state of the each key and checking it in the game loop like this
eHandler->getKey(EVENT_KEYS::KEY_LEFT_CTRL);
if it returns true than do something.
//this function is called by the function, which is passed as callback to the glfw library
void eventHandler::keyBoardHandler(int key , int scancode, int action, int mods)
{
if(action!=GLFW_KEY_UNKNOWN)
switch (key)
{
case GLFW_KEY_A:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_A=true;
if(currentCamera->TP_PERSPECTIVE)
character_controller->moveLeft(currentCamera);
}
break;
}
case GLFW_KEY_B:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_B=true;
}
break;
}
case GLFW_KEY_C:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_C=true;
}
break;
}
case GLFW_KEY_D:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_D=true;
if(currentCamera->TP_PERSPECTIVE)
character_controller->moveRight(currentCamera);
}
break;
}
case GLFW_KEY_E:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_E=true;
}
break;
}
case GLFW_KEY_F:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_F=true;
}
break;
}
case GLFW_KEY_G:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_G=true;
}
break;
}
case GLFW_KEY_H:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_H=true;
}
break;
}
case GLFW_KEY_I:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_I=true;
}
break;
}
case GLFW_KEY_J:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_J=true;
}
break;
}
case GLFW_KEY_K:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_K=true;
}
break;
}
case GLFW_KEY_L:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_L=true;
}
break;
}
case GLFW_KEY_M:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_M=true;
}
break;
}
case GLFW_KEY_N:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_N=true;
}
break;
}
case GLFW_KEY_O:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_O=true;
}
break;
}
case GLFW_KEY_P:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_P=true;
}
break;
}
case GLFW_KEY_Q:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_Q=true;
}
break;
}
case GLFW_KEY_R:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_R=true;
}
break;
}
case GLFW_KEY_S:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_S=true;
if(currentCamera->TP_PERSPECTIVE)
character_controller->moveBackward(currentCamera);
}
break;
}
case GLFW_KEY_T:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_T=true;
}
break;
}
case GLFW_KEY_U:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_U=true;
}
break;
}
case GLFW_KEY_V:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_V=true;
}
break;
}
case GLFW_KEY_W:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_W=true;
if(currentCamera->TP_PERSPECTIVE)
character_controller->moveForward(currentCamera);
}
break;
}
case GLFW_KEY_X:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_X=true;
}
break;
}
case GLFW_KEY_Y:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_Y=true;
}
break;
}
case GLFW_KEY_Z:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_Z=true;
}
break;
}
case GLFW_KEY_UP :
{
my_keys.KEY_UP = true;
currentCamera->panUp();
break;
}
case GLFW_KEY_DOWN :
{
my_keys.KEY_DOWN = true;
currentCamera->panDown();
break;
}
case GLFW_KEY_LEFT :
{
my_keys.KEY_LEFT = true;
currentCamera->panLeft();
break;
}
case GLFW_KEY_RIGHT :
{
my_keys.KEY_RIGHT = true;
currentCamera->panRight();
break;
}
case GLFW_KEY_ESCAPE:
{
my_keys.KEY_ESCAPE = true;
glfwSetWindowShouldClose(window, GLFW_TRUE);
break;
}
case GLFW_KEY_SPACE:
{
if(action==GLFW_PRESS||action==GLFW_REPEAT)
{
my_keys.KEY_SPACE = true;
if(currentCamera->TP_PERSPECTIVE)
character_controller->jump(currentCamera);
}
break;
}
case GLFW_KEY_ENTER:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_ENTER = true;
}
break;
}
case GLFW_KEY_TAB:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_TAB = true;
}
break;
}
case GLFW_KEY_LEFT_CONTROL:
{
if(action==GLFW_PRESS)
{
my_keys.KEY_LEFT_CTRL = true;
}
break;
}
default:{}
}
}
sorry that i have pasted this thing here but this is what i am really doing.
i have done this like above because i don't want to pass other pointers to event handler class example
camera,object_manger,game_world_physics and that all
so my question is
what is the correct way of doing event handling? what you people do for optimization?
😓😓😓😓😓😓😓😓😓😓😓😓
×