Keyboard in SFML - C++ - sfml

I am doing my project game, but i stuck with these codes.
while (window.pollEvent(e1))
{
if (e1.type == Event::Closed) window.close();
if (e1.type == Event::KeyReleased)
if (e1.key.code == Keyboard::Up) { menu.MoveUp(); break; }
else if (e1.key.code == Keyboard::Down) { menu.MoveDown(); break; }
else if (e1.key.code == Keyboard::Return)
{...}
I made these codes for making my game menu, but when i press up and down, nothing happen. By the way this is the code for MoveUp()
void Menu::MoveUp()
{
if (selectedItemIndex - 1 >= 0)
{
menu[selectedItemIndex].setColor(Color::White);
selectedItemIndex--;
menu[selectedItemIndex].setColor(Color::Red);
}
}

Related

SDL_PollEvents - Part of the code that are executed without key being pressed. Situation not desired

My program has to quit when I press ESC key. Even not pressing the key, my program exit automatically after some seconds of execution. No errors or notable exceptions found during the execution and the code seems to be correct.
void pollE(bool& _isRunning, build *actionBuild,finance *money,squareId* slotId,squareId map[][MAP_SLOTS_H]) {
while (SDL_PollEvent(&event)) {
// MOUSE
switch (event.button.button) {
case SDL_BUTTON_LEFT:
if (event.button.state == SDL_RELEASED) {
actionBuild->construct(ID_CASA, map);
}
if (event.button.state == SDL_PRESSED) {
}
break;
case SDL_BUTTON_RIGHT:
if (event.button.state == SDL_RELEASED) {
// test
debugPrintMap(map);
}
if (event.button.state == SDL_PRESSED) {
}
break;
}
// KEYBOARD
switch (event.key.keysym.sym) { // ---------------------------- HERE
case SDLK_ESCAPE: // ------------------------------------------ HERE
_isRunning = false; // ------------------- to stop mainLoop()
break;
case SDLK_SPACE:
break;
default:
break;
}
}
The function is called here:
void mainLoop() {
(...)
while (isRunning == true) {
dealWithEvents->pollE(isRunning,actionBuild,money,slotId,map);
preDraw();
draw();
afterDrawEffects();
draw();
(...)
}
(...)
}

Beyond Face Reality(BRF) and C++ and VS2017

I am currently using VS2017 with C++ to use the program of Beyond Face Reality(BRF).
Here is the link: https://github.com/Tastenkunst/brfv4_win_examples
However for some reason,I keep getting 3 error codes of LNK2001. Does anyone have any advice or answers to solve this?
int main() {
brf::trace("init app ...");
brf::CameraUtils camUtils(_imageDataWidth, _imageDataHeight, true);
if(!camUtils.init()) {
brf::trace("No Camera found ...");
return -1;
}
cv::namedWindow("main", cv::WINDOW_OPENGL);
brf::Stats _stats;
brf::BRFCppExample example;
example.init(camUtils.cameraWidth, camUtils.cameraHeight, brf::ImageDataType::U8_BGR);
cv::Mat& draw = example._drawing.graphics;
cv::resizeWindow("main", draw.cols, draw.rows);
brf::trace("execute app ...");
while (true) {
if(camUtils.update()) {
camUtils.cameraData.copyTo(draw);
example.update(camUtils.cameraData.data);
}
_stats.update();
_stats.render(draw);
cv::imshow("main", draw);
int key = cv::waitKey(1);
if (key == 27) { // 27 == ESC
break;
} else if(key == 114) { // 114 == R
example.reset();
} else if(key != -1) {
brf::trace("key: " + brf::to_string(key));
}
}
brf::trace("dispose app ...");
example.dispose();
brf::trace("close app ...");
return 0;
}
endif /* GST_CAMERA_UTILS_H */

How to fix a flickering led Matrix and lcd menu screen

I'm making a project where you have a led matrix, LCD and 7 different sensors. Each sensor will display a different message to the matrix and has it's own sub menu on the LCD.
I've created a menu for switching between the sensors. A rotary encoder is used to navigate in the menu. (A pin has an interrupt on change for executing only the void loop when the pin has changed) Also a select button is used to run the program of a menu item.( a sensor program like prg_Pong(), prg_Flame());
I want to display the menu items on the LCD (no I2C). Now my problem is my main menu items are displayed correctly (with no flicker because of the interrupt on the rotary encoder pin)
but when I press the button to run for ex prg_Pong() the lcd prints message running pong but the message is flickering and the message on the led matrix is good (static).
I've found a solution by adding a delay(300); in the loop after drawMenu but when I do that and enter prg_Pong();
the message on the led matrix starts to flicker at the delay time and the menu item "running pong" doesn't flicker anymore.
The functions displayData(),mtx_clear() are used for the led matrix and they are working. Because when I remove the functionality of the LCD the message is displayed correctly.
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
}
previousBtnState = stateBtnSelect;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
}
void prg_Pong()
{
lcd.clear();
delay(100);
lcd.print("run pong");
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}
you are clearing the lcd display frequently, so it will look like flickering.
i used a two more variables to find, Is there any need to update the display? change the display contents only if required, I didn't compile code but hope this will solve your problem, i use similar technique in my projects.
prev_menu=-1;
update_display=true;
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
update_display=true;
}
previousBtnState = stateBtnSelect;
if(prev_menu != rotaryPosition)
update_display=true;
else
update_display=false;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
if( update_display){
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
prev_menu=item;
}
}
void prg_Pong()
{
if(update_display){
lcd.clear();
delay(100);
lcd.print("run pong");
update_display=false;
}
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}

Program crash with removal of SDL_PollEvent [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Why does my program crash when i remove the SDL_PollEvent line from main? I wanted to keep input management in my gamesystem class without using events.
I have also tried putting the !gamesystem.boot() within the while statement itself as well to no avail.
Main:
int main(int argc, char* args[])
{
if(!init())
{
printf("Failed to initialize!\n");
}
else
{
GameSystem gamesystem;
gamesystem.startup(gRenderer,gGameController1,gGameController2);
bool quit = false;
SDL_Event e;
while(!quit)
{
while(SDL_PollEvent(&e)!=0)
{
if(e.type == SDL_QUIT)
{
quit = true;
}
}
if(!gamesystem.boot())
quit = true;
}
}
close();
return 0;
}
gamesystem:
#include "GameSystem.h"
GameSystem::GameSystem()
{
}
void GameSystem::startup(SDL_Renderer* gRenderer, SDL_Joystick* gGameController1, SDL_Joystick* gGameController2)
{
gameRenderer = gRenderer;
controller1 = gGameController1;
controller2 = gGameController2;
title.loadFile(gameRenderer, "Art/Title.png");
arrow.loadFile(gameRenderer, "Art/Arrow.png");
beep = Mix_LoadWAV("SFX/Beep.wav");
boop = Mix_LoadWAV("SFX/Boop.wav");
buup = Mix_LoadWAV("SFX/Buup.wav");
baap = Mix_LoadWAV("SFX/Baap.wav");
}
bool GameSystem::boot()
{
renderClear();
if(menu == 0)
{
title.render(gameRenderer, 0,0);
if(selection == 0)
arrow.render(gameRenderer, 215, 400);
else if(selection == 1)
arrow.render(gameRenderer, 250, 440);
else if(selection == 2)
arrow.render(gameRenderer, 235, 482);
else if(selection == 3)
arrow.render(gameRenderer, 255, 528);
}
update();
return quit;
}
enum buttons GameSystem::controls()
{
const Uint8 *state = SDL_GetKeyboardState(NULL);
if(state [SDL_SCANCODE_DOWN] || SDL_JoystickGetHat(controller1, 0) == SDL_HAT_DOWN)
return u;
else if(state [SDL_SCANCODE_UP] || SDL_JoystickGetHat(controller1, 0) == SDL_HAT_UP)
return d;
else if(state [SDL_SCANCODE_LEFT] || SDL_JoystickGetHat(controller1, 0) == SDL_HAT_LEFT)
return l;
else if(state [SDL_SCANCODE_RIGHT] || SDL_JoystickGetHat(controller1, 0) == SDL_HAT_RIGHT)
return r;
else if(state [SDL_SCANCODE_X] || SDL_JoystickGetButton(controller1, 0))
return a;
else if(state [SDL_SCANCODE_C] || SDL_JoystickGetButton(controller1, 1))
return b;
else if(state [SDL_SCANCODE_S] || SDL_JoystickGetButton(controller1, 2))
return x;
else if(state [SDL_SCANCODE_D] || SDL_JoystickGetButton(controller1, 3))
return y;
else if(state [SDL_SCANCODE_RETURN])
return start;
else if(state [SDL_SCANCODE_SPACE])
return select;
return nopress;
}
void GameSystem::renderClear()
{
SDL_SetRenderDrawColor(gameRenderer, 0, 0, 0, 0xFF);
SDL_RenderClear(gameRenderer);
}
void GameSystem::update()
{
switch(controls())
{
case u:
Mix_PlayChannel(-1,beep,0);
selection++;
if(selection > 3) selection = 0;
break;
case d:
Mix_PlayChannel(-1,beep,0);
selection--;
if(selection < 0) selection = 3;
break;
case l:
Mix_PlayChannel(-1,beep,0);
break;
case r:
Mix_PlayChannel(-1,beep,0);
break;
case a:
Mix_PlayChannel(-1,beep,0);
if(selection == 3) quit = false;
break;
case b:
Mix_PlayChannel(-1,boop,0);
break;
case x:
Mix_PlayChannel(-1,buup,0);
break;
case y:
Mix_PlayChannel(-1,baap,0);
break;
}
//takes in vector of things to render after they have been sorted and renders them//
//^render vector here^//
SDL_RenderPresent(gameRenderer);
}
Your program does not crash, it is just ignoring inputs (it is "not responding"). It will just run gamesystem.boot() repeatedly without ever detecting your imputs.
Actually, SDL_PollEvent() internally calls SDL_PumpEvents() which updates inputs. When you remove SDL_PollEvent(), SDL never updates its internal input device state, so SDL_GetKeyboardState() always returns its initial state.
Replacing your PollEvent loop with SDL_PumpEvents() should solve this.

Displaying from std::vector and handling events using SDL?

I am trying to make a custom app library with SDL as apart of an academic project, and I ran into an issue..
Basically, everything works fine, it compiles, does what I expect it to do, but... its extremely slow, the first element is reacting quite quickly, other elements within the set are completely unresponsive (i need to click them 20 times for the to react, they work just slow)
Below the function that draws the elements from a vector type container, the return 1 means that the handle function ran into an unexpected error or the user X'ed out the window.
Any advice on how to make this react faster?
void StoreDraw::setCamera(size_t input)
{
rectangle.x = containerArray[input].elementLocX;
rectangle.y = containerArray[input].elementLocY;
rectangle.h = containerArray[input].elementPicture->h;
rectangle.w = containerArray[input].elementPicture->w;
}
bool StoreDraw::vectorDraw()
{
/* Draw FloatingElements */
for(size_t i = 0; i < containerArray.size(); i++)
{
if(SDL_PollEvent(&event))//containerArray[i].event
{
if(event.type == SDL_MOUSEBUTTONDOWN)
{
if(event.button.button == SDL_BUTTON_LEFT)
{
locationX = event.button.x;
locationY = event.button.y;
printf("X:%d\tY:%d\n", locationX, locationY);
if(!containerArray[i].handleEvent(locationX, locationY)){drawEnvironment();}
}
}
if(event.type == SDL_QUIT)
{
return 1;
}
}
}
SDL_Flip(screen);
return 0;
}
bool StoreDraw::drawEnvironment()
{
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
SDL_BlitSurface(background, NULL, screen, NULL);
for(size_t i = 0; i < containerArray.size(); i++)
{
setCamera(i);
SDL_BlitSurface(containerArray[i].elementPicture, NULL, screen, &rectangle);
}
SDL_Flip(screen);
}
bool FloatingElement::handleEvent(int x, int y)
{
printf("Object responding.\n");
if((x > elementLocX) && (x < (elementLocX + (elementPicture->w))) && (y > elementLocY) && (y < (elementLocY + (elementPicture->h))))
{
x = (x - (elementPicture->w)/2);
y = (y - (elementPicture->h)/2);
setLocation(x,y);
printf("Object responding.\n");
return 0;
}
return 1;
}
As far as I can see, the problem is how frequently you are checking for events. When you call vectorDraw() it polls the events and acts as intended, but the events eventually end and the function returns. I think there should be a main loop in the code that always checks for events and calls functions when necessary, while vectorDraw() only checks the location of a click and calls the handleEvent() of the container array.
Edit:
I think I found the problem. This is how you're doing now:
bool StoreDraw::vectorDraw()
{
/* Draw FloatingElements */
for(size_t i = 0; i < containerArray.size(); i++)
{
if(SDL_PollEvent(&event))//containerArray[i].event
{
if(event.type == SDL_MOUSEBUTTONDOWN)
{
if(event.button.button == SDL_BUTTON_LEFT)
{
// Check Events
}
}
if(event.type == SDL_QUIT)
{
return 1;
}
}
}
SDL_Flip(screen);
return 0;
}
int main() {
while( ::quit == false ) {
while(SDL_PollEvent(&event) == 1) {
if( event.type != SDL_QUIT ) {
if( event.type == SDL_MOUSEBUTTONDOWN) {
storeDraw::vectorDraw();
}
} else {
quit = true;
break;
}
}
}
}
}
So, what is happening:
After the main loop polls the event, it calls vectorDraw() and vectorDraw() polls events again. By doing so, vectorDraw() doesn't get the information of the click it called, as it was already polled in the main loop. Without the information, it doesn't act upon it.
So, in order to solve the problem, you can change the functions to be somewhat like this:
bool StoreDraw::vectorDraw(SDL_Event event)
{
/* Draw FloatingElements */
for(size_t i = 0; i < containerArray.size(); i++)
{
// Check Events
}
SDL_Flip(screen);
return 0;
}
int main() {
while( ::quit == false ) {
while(SDL_PollEvent(&event) == 1) {
if( event.type != SDL_QUIT ) {
if( event.type == SDL_MOUSEBUTTONDOWN) {
if(event.button.button == SDL_BUTTON_LEFT)
{
storeDraw::vectorDraw(event);
}
}
} else {
quit = true;
break;
}
}
}
}
}
Now, only the main loop polls events and acts on them if possible. And vectorDraw() doesn't poll them anymore, only acts upon them if they meet it's criteria (left mouse button down, in this case). Now the event checking should act as intended.