Add input functions

- user must enter nickname
- user must enter difficulty level
- user must enter map
This commit is contained in:
Hanse-14 2023-12-18 00:06:28 +01:00
parent 5c72303409
commit 0590a782b8
5 changed files with 253 additions and 79 deletions

View File

@ -8,8 +8,10 @@
#define MAX_COLOURS 10
#define MAX_LINES_TFF 20 //max lines (of ttf) for the whole project
#define MAX_LINES_STARTSCREEN 6
#define MAX_LINES_SETTINGS 7
#define MAX_LINE_INFOSCREEN 17
#define MAX_LINES_SETTINGS 14
#define MAX_LINES_INFOSCREEN 17
#define TEXT_INPUT_SIZE 30
#define TIME_BETWEEN_UPDATE_MENU 1000 // [ms]
// Enum that defines the active menu
@ -40,8 +42,13 @@ typedef struct tllData_t
int lineHeight; // to print text in middle
int totalHeight; // to print text in middle
int textPrintPosition; // where first line is printed
const time_t cycleDuration;
bool showEnter;
const time_t cycleDuration; // time between blinking ENTER
bool showEnter; // ENTER should be printed only every second cycle
int inputStatus; // 1 if player name was entered; 2 if difficulty level was entered, 3 map was entered
char textInput[TEXT_INPUT_SIZE]; // auxiliary variable for user input
char userName[TEXT_INPUT_SIZE]; // user name
int userDifficultyLevel; // difficulty level which was entered by user
int userSelectedMap; // map which was entered by user
} ttlData_t;
extern ttlData_t ttlStorage;

View File

@ -1,5 +1,6 @@
#pragma once
#include <string.h>
#include "game.h"
#include "snake.h"
#include "menu.h"

View File

@ -81,6 +81,7 @@ void handleInput_runningState(SDL_Event event)
void processInputEvent()
{
SDL_Event event;
// loop through all queued input events that occoured since last run
while (SDL_PollEvent(&event))
{
@ -110,6 +111,12 @@ void processInputEvent()
break;
}
}
//--- key text input ---
// not possible to make this check in the else if query before
else if(event.type == SDL_TEXTINPUT && game.gameState == MENU)
{
menuHandleInput(event);
}
}
return;

View File

@ -15,7 +15,11 @@ ttlData_t ttlStorage =
.fontSize_30 = 30, // size of font
.fontSize_200 = 200, // size of font
.cycleDuration = 500, // time between show and not showing ENTER in start screen
.showEnter = false
.showEnter = false,
.inputStatus = 0,
.textInput[0] = '\0'
};
// Default
@ -53,7 +57,7 @@ void manageMenu()
// shows start screen with blinking ENTER
void showStartScreen()
{
LOGI("menu: showing start-screen\n");
LOGD("menu: showing start-screen\n");
time_t now = GET_TIME_MS();
@ -69,7 +73,7 @@ void showStartScreen()
void showLeaderboard()
{
LOGI("menu: showing leaderboard\n");
LOGD("menu: showing leaderboard\n");
//--- play crash sound ---
//play audio file, wait until playback is finished
@ -84,7 +88,7 @@ void showLeaderboard()
void showPauseScreen()
{
LOGI("menu: showing leaderboard\n");
LOGD("menu: showing leaderboard\n");
game.gameState = PAUSED;
return;
}
@ -92,7 +96,7 @@ void showPauseScreen()
void showSettings()
{
LOGI("menu: showing settings\n");
LOGD("menu: showing settings\n");
time_t now = GET_TIME_MS();
@ -110,7 +114,7 @@ void showSettings()
void showInfoScreen()
{
LOGI("menu: showing info-screen\n");
LOGD("menu: showing info-screen\n");
time_t now = GET_TIME_MS();
@ -125,11 +129,12 @@ void showInfoScreen()
}
// handle input over keyboard
// delete text at the and of one menu section
// delete text at the end of one menu section
void menuHandleInput(SDL_Event event){
//compare 'handleInput_runningState(SDL_Event event)' in input.c
switch(activeMenu)
{
{
// start
case START:
switch (event.key.keysym.sym)
{
@ -148,13 +153,13 @@ void menuHandleInput(SDL_Event event){
}
break;
// settings
case SETTINGS:
switch(event.key.keysym.sym)
{
case SDLK_q: // q: quit
game.gameState = EXIT;
break;
// case SDLK_q: // q: quit
// game.gameState = EXIT;
// break;
case SDLK_F1: // go to info screen
activeMenu = INFOSCREEN;
@ -166,19 +171,70 @@ void menuHandleInput(SDL_Event event){
}
break;
case SDLK_RETURN: //start game
activeMenu = NONE;
game.gameState = RUNNING;
// delete text
for (int i = 0; i < MAX_LINES_TFF; ++i)
case SDLK_RETURN: // confirm user input or start game
switch(ttlStorage.inputStatus)
{
SDL_DestroyTexture(ttlStorage.textTextures[i]);
}
case 0: // confirm user name
// user must enter at least one letter
if(ttlStorage.textInput[0] != '\0')
{
ttlStorage.inputStatus++;
strcpy(ttlStorage.userName, ttlStorage.textInput); // copy textInput to userName
memset(ttlStorage.textInput, 0, sizeof(ttlStorage.textInput)); // clear textInput[]
}
break;
case 1: // confirm difficulty level
// user input must be between 0 and 3
if((ttlStorage.textInput[0] > '0') && (ttlStorage.textInput[0] <= '3'))
{
ttlStorage.inputStatus++;
ttlStorage.userDifficultyLevel = ttlStorage.textInput[0] - '\0'; // copy textInput to userDifficultyLevel
}
memset(ttlStorage.textInput, 0, sizeof(ttlStorage.textInput)); // clear textInput[]
break;
case 2: // confirm map
// user input must be between 0 and 3
if((ttlStorage.textInput[0] > '0') && (ttlStorage.textInput[0] <= '3'))
{
ttlStorage.inputStatus++;
ttlStorage.userSelectedMap = ttlStorage.textInput[0] - '\0'; // copy textInput to userSelectedMap
}
memset(ttlStorage.textInput, 0, sizeof(ttlStorage.textInput)); // clear textInput[]
break;
case 3: // start game
activeMenu = NONE;
game.gameState = RUNNING;
// delete text
for (int i = 0; i < MAX_LINES_TFF; ++i)
{
SDL_DestroyTexture(ttlStorage.textTextures[i]);
}
break;
}
break;
default: // for user inputs
// keyboard input
if (event.type == SDL_TEXTINPUT)
{
strcat(ttlStorage.textInput, event.text.text);
}
// delete single inputs via backspace
else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_BACKSPACE && strlen(ttlStorage.textInput) > 0)
{
ttlStorage.textInput[strlen(ttlStorage.textInput) - 1] = '\0';
}
break;
}
break;
// info screen
case INFOSCREEN:
switch(event.key.keysym.sym)
{
@ -198,7 +254,6 @@ void menuHandleInput(SDL_Event event){
break;
}
return;
}

View File

@ -213,65 +213,168 @@ void renderStartMenu()
//-------------------SETTINGS-----------------------------------
//--------------------------------------------------------------
void renderSettings()
{
{
int textWidth, textHeight; // auxiliary variables for printing
// text in menu settings
static char* textLinesInMenu[MAX_LINES_SETTINGS] = {
"Fuer Infos zum Gameplay, sowie einigen Shortcuts druecken Sie bitte F1",
" ",
" ",
"Bitte geben Sie ihren Nickname ein: ",
" ",
" ",
"Bitte geben Sie ein Schwierigkeitslevel ein:",
"1 fuer Einfach - 2 fuer Fortgeschritten - 3 fuer Profi",
" ",
" ",
"Bitte waehlen Sie eine Map:",
"1 fuer Klein - 2 fuer Mittel - 3 fuer Gross",
" ",
"-- ENTER --"
};
//=========== only first loop ================
if(ttlStorage.lastTimeStep == 0)
{
{
printf("In first loop\n");
ttlStorage.ptrFont_20 = TTF_OpenFont("../fonts/Prototype.ttf", ttlStorage.fontSize_20);
// text in start screen
const char* textLines[] = {
"Fuer Infos zum Gameplay, sowie einigen Shortcuts druecken Sie bitte F1",
" ",
//"Bitte geben Sie ihren Spielnamen ein: ",
"test",
"test",
"test",
"test",
"-- ENTER --"
};
// render setting screen
for (int i = 0; i < MAX_LINES_SETTINGS; ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLines[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
}
SDL_StartTextInput(); // start text input
}
//=========== is always performerd ================
SDL_RenderClear(game.renderer);
int textWidth, textHeight;
// print settings
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < (MAX_LINES_SETTINGS - 1); ++i) {
//=========dependent of which text is currently entered(userName, difficultyLevel, userSelectedMap) =========
switch(ttlStorage.inputStatus)
{
//=== no user inputs ===
case 0:
//--- rendering ---
for (int i = 0; i < 4; ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLinesInMenu[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
}
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, ttlStorage.textInput, ttlStorage.textColour[5]);
ttlStorage.textTextures[4] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
SDL_RenderClear(game.renderer);
SDL_Rect dstRect = { 1, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[i], NULL, &dstRect);
ttlStorage.textPrintPosition += textHeight; // increase print position
}
//--- printing ---
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < 5; ++i)
{
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect = { 1, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[i], NULL, &dstRect);
ttlStorage.textPrintPosition += textHeight; // increase print position
}
break;
// === one user input ===
case 1:
textLinesInMenu[4] = ttlStorage.userName;
//--- rendering ---
for (int i = 0; i < 8; ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLinesInMenu[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
}
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, ttlStorage.textInput, ttlStorage.textColour[5]);
ttlStorage.textTextures[8] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
SDL_RenderClear(game.renderer);
//---printing ---
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < 9; ++i)
{
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect = { 1, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[i], NULL, &dstRect);
ttlStorage.textPrintPosition += textHeight; // increase print position
}
break;
//=== two user inputs ===
case 2:
textLinesInMenu[8] = &(ttlStorage.userDifficultyLevel);
//--- rendering ---
for (int i = 0; i < 12; ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLinesInMenu[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
}
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, ttlStorage.textInput, ttlStorage.textColour[5]);
ttlStorage.textTextures[12] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
SDL_RenderClear(game.renderer);
//---printing ---
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < 13; ++i)
{
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect = { 1, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[i], NULL, &dstRect);
ttlStorage.textPrintPosition += textHeight; // increase print position
}
break;
//=== user inputs completely
case 3:
textLinesInMenu[12] = &(ttlStorage.userSelectedMap);
//--- rendering ---
for (int i = 0; i < (MAX_LINES_SETTINGS - 1); ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLinesInMenu[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
}
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLinesInMenu[MAX_LINES_SETTINGS - 1], ttlStorage.textColour[5]);
ttlStorage.textTextures[MAX_LINES_SETTINGS - 1] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
SDL_FreeSurface(ttlStorage.textSurface);
SDL_RenderClear(game.renderer);
//---printing ---
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < (MAX_LINES_SETTINGS - 1); ++i)
{
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect = { 1, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[i], NULL, &dstRect);
ttlStorage.textPrintPosition += textHeight; // increase print position
}
//print ENTER every second cycle
if(ttlStorage.showEnter)
{
ttlStorage.textPrintPosition = (config.windowSize / 1.5); // print position for ENTER
SDL_QueryTexture(ttlStorage.textTextures[MAX_LINES_SETTINGS-1], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect1 = { (config.windowSize - textWidth) / 2, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[MAX_LINES_SETTINGS-1], NULL, &dstRect1);
}
// update screen
if(ttlStorage.showEnter)
{
ttlStorage.textPrintPosition = (config.windowSize / 1.5); // print position for ENTER
SDL_QueryTexture(ttlStorage.textTextures[MAX_LINES_SETTINGS-1], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect1 = { (config.windowSize - textWidth) / 2, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[MAX_LINES_SETTINGS-1], NULL, &dstRect1);
}
break;
}
// update screen
SDL_RenderPresent(game.renderer);
ttlStorage.lastTimeStep = GET_TIME_MS();
return;
}
//--------------------------------------------------------------
@ -284,27 +387,28 @@ void renderInfoScreen()
{
// text in start screen
const char* textLines[] = {
" Steuerung: W (nach oben)",
" STEUERUNG: W (nach oben)",
" A (nach links)",
" S (nach unten)",
" D (nach rechts) ",
" oder: Pfeiltasten ",
" oder: Pfeiltasten ",
" ",
" ",
" Pause: p",
" oder: Leertaste",
" PAUSE: p",
" oder: Leertaste",
" ",
" ",
"Spiel verlassen: q ",
"SPIEL VERLASSEN: q ",
" ",
" ",
" ",
"By Jonas Schoenberger, Johannes Graf und Julia Steinberger",
"-- ENTER --"
};
// render setting screen
for (int i = 0; i < MAX_LINE_INFOSCREEN; ++i)
for (int i = 0; i < MAX_LINES_INFOSCREEN; ++i)
{
ttlStorage.textSurface = TTF_RenderText_Solid(ttlStorage.ptrFont_20, textLines[i], ttlStorage.textColour[5]);
ttlStorage.textTextures[i] = SDL_CreateTextureFromSurface(game.renderer, ttlStorage.textSurface);
@ -320,7 +424,7 @@ void renderInfoScreen()
// print settings
ttlStorage.textPrintPosition = 0; // first print position
for (int i = 0; i < (MAX_LINE_INFOSCREEN - 1); ++i) {
for (int i = 0; i < (MAX_LINES_INFOSCREEN - 1); ++i) {
SDL_QueryTexture(ttlStorage.textTextures[i], NULL, NULL, &textWidth, &textHeight);
@ -333,9 +437,9 @@ void renderInfoScreen()
if(ttlStorage.showEnter)
{
ttlStorage.textPrintPosition = (config.windowSize / 1.5); // print position for ENTER
SDL_QueryTexture(ttlStorage.textTextures[MAX_LINE_INFOSCREEN-1], NULL, NULL, &textWidth, &textHeight);
SDL_QueryTexture(ttlStorage.textTextures[MAX_LINES_INFOSCREEN-1], NULL, NULL, &textWidth, &textHeight);
SDL_Rect dstRect1 = { (config.windowSize - textWidth) / 2, ttlStorage.textPrintPosition, textWidth, textHeight };
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[MAX_LINE_INFOSCREEN-1], NULL, &dstRect1);
SDL_RenderCopy(game.renderer, ttlStorage.textTextures[MAX_LINES_INFOSCREEN-1], NULL, &dstRect1);
}