I'm currently playing around with SDL to make a game and I've run into a problem where SDL is not picking up some events. For exampling, I would be pressing 'w' to move forward and at the same time, I'm moving my mouse to look around. But let's say I then press 'a' or 'd', SDL will not pick these events or even when I release 'w', SDL will not pickup the KEYUP event. I first wrote this code in windows and it all worked fine, but after switching to ubuntu, it doesn't work as expected anymore. Here is my main loop where I poll for events:
while(Running)
{
while(SDL_PollEvent(&event))
Events(&event);
if( active ){
Loop();
Render();
}
}
This is the code within Events():
switch(Event->type)
{
case SDL_QUIT:
Running = false;
break;
case SDL_KEYDOWN:
switch(Event->key.keysym.sym)
{
case SDLK_ESCAPE:
Running = false;
break;
case SDLK_a:
keyStates['a'] = true;
break;
case SDLK_s:
keyStates['s'] = true;
break;
case SDLK_d:
keyStates['d'] = true;
break;
case SDLK_w:
keyStates['w'] = true;
break;
case SDLK_LSHIFT:
camera.setSpeed(2.0f);
break;
}
break;
case SDL_KEYUP:
switch(Event->key.keysym.sym)
{
case SDLK_a:
keyStates['a'] = false;
break;
case SDLK_s:
keyStates['s'] = false;
break;
case SDLK_d:
keyStates['d'] = false;
break;
case SDLK_w:
keyStates['w'] = false;
break;
case SDLK_LSHIFT:
camera.setSpeed(1.0f);
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
switch(Event->button.button)
{
case SDL_BUTTON_MIDDLE:
mouse.middle = true;
break;
}
break;
case SDL_MOUSEBUTTONUP:
switch(Event->button.button)
{
case SDL_BUTTON_MIDDLE:
mouse.middle = false;
break;
}
break;
case SDL_MOUSEMOTION:
if( moving ){
camera.lookat(float(Event->motion.x - winWidth/2),float(Event->motion.y - winHeight/2), MOUSE_SENSITIVITY, dt);
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
SDL_WarpMouse(winWidth/2, winHeight/2);
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
}
break;
}
keyStates['a'] = true;
There's SDL_GetKeyState for this. Use it instead of manually maintaining array.
Uint8 keys[SDLK_LAST];
Uint8* sdlKeys = SDL_GetKeyState(0);
memcpy(keys, sdlKeys, sizeof(keys));
.
bool keyPressed(SDLKey key){
return keys[key] == SDL_PRESSED;
}
Also check documentation.
Related
i have a question:
(i use winows, visual studio)
i making a program and i need to read keyboard and mouse input istantly so like getch() (because if i use cin i need to press fullstop new line evry time).
i have this:
char p;
while (running) {
if (_kbhit()) {
p = _getch();
switch (p) {
case 'w':
mx = -1;
map(player, mx, 0);
break;
case 'a':
my = -1;
map(player, 0, my);
break;
case 's':
mx = 1;
map(player, mx, 0);
break;
case 'd':
my = 1;
map(player, 0, my);
break;
case 27:
running = false;
break;
}
}
}
the problem is with _getch() i can't read mouse imput.
so how i can get this?
So I was working on this program again, and I encountered another problem. I am testing if a character is a space. However, instead of detecting that the there is a space, it stops the loop and doesn't do anything more. Here is my code:
string reet(char reet) {
if (isspace(reet) == true) {
return "IA";
}
else {
switch (reet) {
case 'a':
return "Zg";
break;
case'b':
return "dA";
break;
case 'c':
return "dG";
break;
case 'd':
return "aw";
break;
case 'e':
return "bw";
break;
case 'f':
return "dQ";
break;
case 'g':
return "cg";
break;
case 'h':
return "ZA";
break;
case 'i':
return "cQ";
break;
case 'j':
return "YQ";
break;
case 'k':
return "eA";
break;
case 'l':
return "dw";
break;
case 'm':
return "cw";
break;
case 'n':
return "ag";
break;
case 'o':
return "eQ";
break;
case 'p':
return "bA";
break;
case 'q':
return "aA";
break;
case 'r':
return "ZQ";
break;
case 's':
return "cA";
break;
case 't':
return "Yw";
break;
case 'u':
return "eg";
break;
case 'v':
return "bg";
break;
case 'w':
return "aq";
break;
case 'x':
return "bQ";
break;
case 'y':
return "Yg";
break;
case 'z':
return "Zw";
break;
default:
return " ";
break;
}
}
}
string enc(string input) {
string sketchyBois = input;
string bigBoi = "";
int yeetL = sketchyBois.length() + 1;
for (int x = 0; x < yeetL;) {
bigBoi = bigBoi + reet(sketchyBois[x]);
x++;
}
return bigBoi;
}
I was just wondering if anyone can tell me why it is doing this? Thank you!
You need to change
if (isspace(reet) == true)
to
if (isspace(reet))
or
if (isspace(reet) != 0)
since isspace only returns a non-zero int value for a white space character, not a bool.
(Note that as a matter of coding style, it's generally preferred to omit comparison with true or false in boolean tests and just use if (expr) or if (!expr).)
I first added an infinite loop. Dugme is a variable for loop. But I couldn't break the loop. That’s why, when I enter the loop, I can’t exit.
void otoac()
{
long duration, distance;
while(dugme==1)
{
int distanceR = 0;
int distanceL = 0;
delay(40);
if(distance<=24)
{
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if(distanceR>=distanceL)
{
turnRight();
moveStop();
}
else
{
turnLeft();
moveStop();
}
}
else
{
moveForward();
}
distance = readPing();
}
}
I have an code that when I click on case:'X' it goes in automatic mode (application). I have here the code for when I click out of 'X' that's 'x' (little x) it needs to stop but it doesn't stop. This is the code for the 'x'.
void otokapa()
{
dugme=0
motor1.setSpeed(0);
motor2.run(RELEASE); //turn motor1 off
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}
Someone on YouTube only gave me this answer:
I added a while loop to the command, as well as a contradiction to the command, meaning, the action that the car will do when the triangle is not pressed, which is nothing.
More code:
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'F':
forward();
break;
case 'B':
back();
break;
case 'L':
left();
break;
case 'R':
right();
break;
case 'G':
onsol();
break;
case 'I':
onsag();
break;
case 'H':
arkasag();
break;
case 'J':
arkasol();
break;
case 'W':
onac();
break;
case 'w':
onkapa();
break;
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
and dugme:
on top of all the code int dugme=1; and dugme is only in void otokapa and in otoac while(dugme==1)
Is this in essence what your problem looks like?
int dugme = 1; // one and only definition of this (ODR)
void otoac() {
long duration, distance;
while(dugme==1) {
}
}
void otokapa() {
dugme=0;
}
void loop(){
if(Serial.available() > 0){
command = Serial.read();
Stop();
switch(command){
case 'X':
otoac();
break;
case 'x':
otokapa();
break;
}
}
}
Possible errors violation of ODR.
if loop and otoac runs in the same thread you will never get to the serial again.
Hey so I'm working on a project/2d game and I'm having some odd behavior from SDL which I'm sure is probably something I'm not understanding. The function ProcessKeys is called and works fine for all the key press downs except SDLK_SPACE and I cannot for the life of me figure out why.
What is even more bizarre is that the SDL_KEYUP switch of SDLK_SPACE works great. I tried using some debugging code to print out which key is being pressed and when you press space down nothing registers. Every other key on the keyboard registers in my debug statement at the top of the SDL_KEYDOWN case.
If anyone can see what is going on I would really appreciate it.
And if you need to see where its being called let me know.
SDLKeyboard::KeyState SDLKeyboard::ProcessKeys(SDL_Event * event)
{
switch(event->type)
{
/* Look for a keypress */
case SDL_KEYDOWN:
{
std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
/* Check the SDLKey values and move change the coords */
switch(event->key.keysym.sym)
{
case SDLK_LEFT:
{ // rotate the ship left
c.setIsTurningLeft(true);
return this->keystate = LeftPressed;
// add code when user presses left
break;
}
case SDLK_RIGHT:
{
// rotate the ship right
c.setIsTurningRight(true);
return this->keystate = RightPressed;
// add code when user presses right
break;
}
case SDLK_UP:
{
// accleration
c.setIsAccelerating(true);
return this->keystate = UpPressed;
// add code when user presses up
break;
}
case SDLK_SPACE:
{
// shoot
c.setIsShooting(true);
std::cout << "keystate = " << this->keystate;
return this->keystate = SpacePressed;
// add code when user presses space
break;
}
default:
{
return this->keystate = NotPressed;
break;
}
}
break;
}
/* We must also use the SDL_KEYUP events to zero the x */
/* and y velocity variables. But we must also be */
/* careful not to zero the velocities when we shouldn't*/
case SDL_KEYUP:
{
std::cout << "Key currently pressed" << event->key.keysym.sym << std::endl;
switch(event->key.keysym.sym)
{
case SDLK_LEFT:
{ /* We check to make sure the ship is moving */
/* to the left. If it is then we zero the */
/* velocity. If the ship is moving to the */
/* right then the right key is still press */
/* so we don't touch the velocity */
c.setIsTurningLeft(false);
return this->keystate = LeftReleased;
// code to do things when left isn't pushed anymore but still moving left
break;
}
case SDLK_RIGHT:
{ // code to do things when right isn't pushed anymore but still moving right
c.setIsTurningRight(false);
return this->keystate = RightReleased;
break;
}
case SDLK_UP:
{ // code to do things when up isn't pushed anymore but still moving up
c.setIsAccelerating(false);
return this->keystate = UpReleased;
break;
}
case SDLK_SPACE:
{ // accleration
c.setIsShooting(false);
return this->keystate = SpaceReleased;
// add code when user presses up
break;
}
default:
break;
}
break;
}
default:
{
return this->keystate = NotPressed;
break;
}
}
}
EDIT:
Here is the example requested. The other thing that I've noticed is the latency in response isn't that great. Like if you press a key sometimes the console doesn't print the corresponding key. Probably has to do with the issue I'm having with the space as well.
void GUI::TakeInput(SDL_Event *e)
{
while (SDL_PollEvent(e))
OnEvent(e);
}
void SDLEvent::OnEvent(SDL_Event * event)
{
switch(event->type)
{
case SDL_KEYDOWN:
{
OnKeyDown(event->key.keysym.sym);
break;
}
case SDL_KEYUP:
{
OnKeyUp(event->key.keysym.sym);
break;
}
case SDL_MOUSEMOTION:
{
OnMouseMove(event->motion.x,event->motion.y);
break;
}
case SDL_MOUSEBUTTONDOWN:
{
OnMouseButtonDown(event->button.button, event->button.x,event->button.y);
break;
}
case SDL_MOUSEBUTTONUP:
{
OnMouseButtonUp(event->button.button, event->button.x,event->button.y);
break;
}
case SDL_QUIT: {
OnExit();
break;
}
case SDL_SYSWMEVENT: {
//Ignore
break;
}
case SDL_WINDOWEVENT_RESIZED: {
OnResize();
break;
}
case SDL_WINDOWEVENT_EXPOSED: {
OnExpose();
break;
}
default: {
OnUser(event->user.type,event->user.code,event->user.data1,event->user.data2);
break;
}
}
}
void GUI::Play()
{
Uint32 start_ticks = SDL_GetTicks();
TakeInput(this->setup->GetEvent());
this->keyboard->ProcessKeys(this->setup->GetEvent());
this->setup->RenderBegin();
this->ship->drawBackBuffer();
this->ship->renderSprite();
Uint32 end_ticks = SDL_GetTicks();
int sleep_delay = (1000 / 60) - (end_ticks-start_ticks);
if (sleep_delay > 0) {
SDL_Delay(sleep_delay);
}
}
If you are only writing event->key.keysym.sym on the console, you should know that the spacebar key produces an almost invisible character.
Try this instead:
std::cout << "<" << event->key.keysym.sym << ">"
So you can see whataver invisible character printed between angle brackets.
I am having trouble with this program. What it is intended to do is read a list of words, then take input for how long the word is, from the words of this length, count up the total of all the letters in them, sort them by highest frequency, and ask the user for the one with the highest frequency. Before it asks, it checks if that letter has already been asked be looping though the array prevguess. My problem is that, if I enter that 'yesletter' is true, the content of this array gets changed at the point after the inline comment "problem occurs here". The value of q within this test loop I put in doesn't change, but the value itself changes.
I know that the loop in main is infinite right now, but the program is not finished.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int i(0),n(0),counter(0),limit(0),length,mastercount(0);
int acount(0),bcount(0),ccount(0),dcount(0),ecount(0),fcount(0),gcount(0),hcount(0);
int icount(0),jcount(0),kcount(0),lcount(0),mcount(0),ncount(0),ocount(0),pcount(0);
int qcount(0),rcount(0),scount(0),tcount(0),ucount(0),vcount(0),wcount(0),xcount(0),ycount(0),zcount(0);
int letters[2][26];
char prevguess[26];
char words[60000][30];
void initarray() {
int len(0);
string line;
char temp;
ifstream wordlist ("words.txt");
if (wordlist.is_open())
{
while (wordlist.good())
{
getline (wordlist,line);
len=line.length();
for (n=0;n<30;n++)
{
if (n<len){
temp=line.at(n);
words[i][n]=temp;
}
else{
words[i][n]='*';
}
}
i++;
counter++;
}
}
else
{
cout<<"file not opened";
}
wordlist.close();
}
void selectlength()
{
int x(0),y(0);
bool shorter(false),longer(false);
cout <<"length of word"<<endl;
cin >> length;
limit=counter;
counter=0;
for (i=0;i<limit;i++){
shorter=false;
longer=false;
for (n=0;n<length;n++){
if (words[i][n]=='*')
{
shorter=true;
break;
}
}
if (words[i][length] != '*')
{
longer=true;
}
if (!longer && !shorter)
{
n=0;
for (y=0;y<30;y++)
{
if (n<length){
words[x][y]=words[i][n];
n++;
}
else{
words[x][y]='*';
}
}
x++;
counter++;
}
}
}
void mostletters(){
char temp;
for (i=0;i<counter;i++){
for (n=0;n<=length;n++){
temp=words[i][n];
switch (temp){
case 'a':
acount++;
break;
case 'b':
bcount++;
break;
case 'c':
ccount++;
break;
case 'd':
dcount++;
break;
case 'e':
ecount++;
break;
case 'f':
fcount++;
break;
case 'g':
gcount++;
break;
case 'h':
hcount++;
break;
case 'i':
icount++;
break;
case 'j':
jcount++;
break;
case 'k':
kcount++;
break;
case 'l':
lcount++;
break;
case 'm':
mcount++;
break;
case 'n':
ncount++;
break;
case 'o':
ocount++;
break;
case 'p':
pcount++;
break;
case 'q':
qcount++;
break;
case 'r':
rcount++;
break;
case 's':
scount++;
break;
case 't':
tcount++;
break;
case 'u':
ucount++;
break;
case 'v':
vcount++;
break;
case 'w':
wcount++;
break;
case 'x':
xcount++;
break;
case 'y':
ycount++;
break;
case 'z':
zcount++;
break;
}
}
}
}
void guessmost(){
int x,y,temp,temp2,q;
for (x=0;x<26;x++){
letters[0][x]=x;
switch (x){
case 0:
letters[1][x]=acount;
break;
case 1:
letters[1][x]=bcount;
break;
case 2:
letters[1][x]=ccount;
break;
case 3:
letters[1][x]=dcount;
break;
case 4:
letters[1][x]=ecount;
break;
case 5:
letters[1][x]=fcount;
break;
case 6:
letters[1][x]=gcount;
break;
case 7:
letters[1][x]=hcount;
break;
case 8:
letters[1][x]=icount;
break;
case 9:
letters[1][x]=jcount;
break;
case 10:
letters[1][x]=kcount;
break;
case 11:
letters[1][x]=lcount;
break;
case 12:
letters[1][x]=mcount;
break;
case 13:
letters[1][x]=ncount;
break;
case 14:
letters[1][x]=ocount;
break;
case 15:
letters[1][x]=pcount;
break;
case 16:
letters[1][x]=qcount;
break;
case 17:
letters[1][x]=rcount;
break;
case 18:
letters[1][x]=scount;
break;
case 19:
letters[1][x]=tcount;
break;
case 20:
letters[1][x]=ucount;
break;
case 21:
letters[1][x]=vcount;
break;
case 22:
letters[1][x]=wcount;
break;
case 23:
letters[1][x]=xcount;
break;
case 24:
letters[1][x]=ycount;
break;
case 25:
letters[1][x]=zcount;
break;
}
}
for (y=0;y<26;y++){
//problem occurs here (I think)
for (q=mastercount-1;q>=0;q--){
cout<<"for array index:"<<q;
cout << " the value of prevguess is "<<prevguess[q]<<endl;
}
for (x=26;x>=1;x--){
if (letters[1][x]>letters[1][x-1])
{
temp=letters[1][x-1];
letters[1][x-1]=letters[1][x];
letters[1][x]=temp;
temp2=letters[0][x-1];
letters[0][x-1]=letters[0][x];
letters[0][x]=temp2;
}
}
}
}
void letterguess(){
int x(0),z;
char guess;
bool goodletter(false),yesletter(false),alreadyguess(false);
while (!goodletter){
guess=letters[0][x]+97;
if (mastercount==0){
alreadyguess=false;
}
else{
for (z=mastercount-1;z>=0;z--){
if (guess==prevguess[z]){
alreadyguess=true;
}
}
}
if (!alreadyguess){
cout<<"is your letter "<< guess<<endl;
cin >> yesletter;
prevguess[mastercount]=guess;
}
if (yesletter && !alreadyguess){
goodletter=true;
}
else {
cout<<"wrong"<<endl;
x++;
}
mastercount++;
if (mastercount>26){
break;
}
}
}
int main() {
bool found(false);
initarray();
selectlength();
while (!found){
mostletters();
guessmost();
letterguess();
if (mastercount>26){
break;
}
}
}
I believe the problems start a bit lower than your comment.
for (x=26;x>=1;x--){
if (letters[1][x]>letters[1][x-1])
When x is 26, letters[1][x] will be out of range.