I'm unable to move the rectangle I made in the program. There is no error message in the compiler when I run the program. Can you please tell me what I missed out in the keyboard event. Other event that I assigned to the window works fine. Thanks (an example will also be helpful).
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
SDL_Window *o;
SDL_Renderer *r;
SDL_Event e;
int i = 1;
SDL_Rect q;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("Game test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(r,0,0,255,255);
SDL_RenderClear(r);
//Creating a box
q.x=475;
q.y=700;
q.h=50;
q.w=50;
SDL_SetRenderDrawColor(r,0,0,0,255);
SDL_RenderFillRect(r,&q);
//SDL_Delay(10);
SDL_RenderPresent(r);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
else if(e.type == SDL_KEYDOWN)
{
switch(e.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
i=0;
break;
case SDLK_UP:
q.y -=10;
SDL_Delay(11);
break;
case SDLK_DOWN:
q.y +=10;
SDL_Delay(11);
break;
case SDLK_RIGHT:
q.x +=10;
SDL_Delay(11);
break;
case SDLK_LEFT:
q.x -=10;
SDL_Delay(11);
break;
default:
break;
}
}
}
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);
SDL_Quit();
return 0;
}
You are only rendering the contents of the window before you enter your event loop. Since you never redraw the contents in the event loop, it's not very strange that no changes happen.
In SDL, you need to constantly redraw the window to see any changes you make. Since you only call the redraw function once, you only see what's happening in the very first moment of the window's creation. You simply need to add a redraw call inside of the loop, and it'll show you moving the rectangle as expected.
Related
I have tried to write a program which will detect the mouse movement. But it is showing error while running in linux environment. i also want to implement the program where if user move the mouse in x axis for different distance like 2cm, 4 cm then it will print some statement. how can i initialize the mouse in linux and get the cursur point coordinate(x,y) while user move mouse.
#include <dos.h>
#include <graphics.h>
union REGS in, out;
void detect_mouse ()
{
in.x.ax = 0;
int86 (0X33,&in,&out); //invoke interrupt
if (out.x.ax == 0)
printf ("\nMouse Failed To Initialize");
else
printf ("\nMouse was Succesfully Initialized");
}
void showmouse_graphics ()
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
in.x.ax = 1;
int86 (0X33,&in,&out);
getch ();
closegraph ();
}
void detect ()
{
int button;
while (!kbhit () )
{
in.x.ax = 3;
int86 (0X33,&in,&out);
button=out.x.bx&7
switch(button)
{
case 1:
print(“left button pressed\n”);
break;
case 2:
print(“right button pressed\n”);
break;
case 4:
print(“middle button pressed\n”);
break;
case 3:
print(“left and right button pressed\n”);
break;
case 5:
print(“left and middle button pressed\n”);
break;
case 6:
print(“right and middle button pressed\n”);
break;
case 7:
print(“all the three buttons pressed\n”);
break;
default:
print(“No button pressed\n”);
}
delay (200); // Otherwise due to quick computer response 100s of words will get print
}
}
void hide_mouse ()
{
in.x.ax = 2;
int86 (0X33,&in,&out);
}
int main ()
{
detect_mouse ();
showmouse_graphics ();
detect ();
hide_mouse ();
return 0;
}
You are using dos.h which is a header available for MS/PC-DOS, not available in Linux. It's my strong belief that it doesn't even compile under gcc in Linux.
I use C and SDL 2.0, but i have a problem, this(when you click on the window's "x" it quits):
void function(SDL_Surface *screen) {
SDL_Event event;
bool quit=false;
while (!quit) {
SDL_WaitEvent(&event);
switch (event.type) {
case...
case SDL_QUIT:
quit = true;
break;
}
}
This is working, but not well. If this is in a function like this, it quits only to the main(), so I need to click on "x" again to quit from the whole program.
How can I solve it? (I want to quit from the whole program everytime, does not matter if it's in a function or not).
As already mentioned in comments you, most probably, have multiple event handling loops, which is usually incorrect design. You game general layout should be something like:
int main(int argc, char* argv[]) {
// do initialize stuff
bool run = true;
SDL_Event evt;
// game loop
while (run) {
// process OS events
while(SDL_PollEvent(&evt) != 0) {
switch (evt.type) {
case SDL_QUIT:
run = false;
break;
}
}
update();
render();
}
// clean up
SDL_Quit();
return 0;
}
In my SDL 2.0 based application, I would like to handle both Control + and Control =.
I understand that I could handle the SDL_KEYDOWN event and look for the SDLK_EQUALS keycode in combination with KEYMODE_CTRL. And even check for KEYMOD_SHIFT' to distinguish between+and=`. However, this is not portable and breaks on keyboards where those symbols are mapped to different keys.
Another thing I have tried is to enable SDL_StartTextInput() and then listen to SDL_TEXTINPUT events. However that only works for printable characters. It ignores control sequences completely.
What is the correct the way to do this? I see SDL 1.2 actually had a unicode field in the SDL_Keysym structure. That would definitely make this a lot easier for me. Does anyone know why that was removed and what the equivalent in SDL 2.0 would be?
Here is an example how you can get unicode input as SDL_TEXTINPUT but the rest as SDL_KEYDOWN:
#include "SDL.h"
#include <stdio.h>
int main(int argc, char *argv[]) {
int done = 0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *w = SDL_CreateWindow("foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, 0);
int lctrl = 0, rctrl = 0;
SDL_StartTextInput();
while (!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_TEXTINPUT: {
int ctrl_state = lctrl || rctrl;
printf("%s, ctrl %s\n", event.text.text, (ctrl_state) ? "pressed" : "released");
} break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 1; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 1; }
break;
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 0; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 0; }
break;
}
}
SDL_UpdateWindowSurface(w);
}
SDL_Quit();
return 0;
}
To simplify things, it ignores SDL_TEXTEDITING, which may (or not) be what you want. Also SDL_GetKeyboardState can be used instead of manually processing events and accumulating modifier keys flags, with the same result.
This is my first time using SDL2 library. When I push W and S (handling the first player position) hold them, and then I push UP on my keyboard, nothing happens. Curious is that other buttons work just fine while I am holding the W and S buttons.
The same thing happens when I do it the opposite way (holding the UP and DOWN buttons...).
Header file:
/**
* Header file for theGame.
*
*/
#include <SDL2/SDL_ttf.h>
// macro definitions
#define HEIGHT 540
#define WIDTH 960
#define SPEED 300
#define MAXBULLETS 1000
#define BULLETSPEED 700
// structs definitions
typedef struct{
bool up, down, left, right, up2, down2, left2, right2;
bool p1Shooting, p2Shooting;
} Action;
typedef struct{
int x;
int y;
bool walking, shooting, alive, facingLeft;
int currentSprite;
int hp;
SDL_Texture *sheetTexture;
} Man;
typedef struct{
int x, y;
bool display; // is it on the screen
bool goingRight;
} Bullet;
typedef struct{
Man *p_p1;
Man *p_p2;
Bullet *bullets;
Action *action;
SDL_Texture *bulletTexture;
int frames;
} gameState;
/**
* Function detects keyboard actions.
*/
void eventsDetection(SDL_Event *event, Action *action, bool *running);
//other stuff
void renderStuff(SDL_Renderer *renderer, gameState game);
void logicStuff(gameState game);
int isInWindow(int x, int y);
void drawText(SDL_Renderer *renderer, char *text, int x, int y);
The problematic function:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_ttf.h>
#include "theGame.h"
void eventsDetection(SDL_Event *event, Action *p_action, bool *running)
{
switch(event->type)
{
case SDL_QUIT:
*running = false;
break;
case SDL_KEYDOWN:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_W:
p_action->up = true;
break;
case SDL_SCANCODE_S:
p_action->down = true;
break;
case SDL_SCANCODE_D:
p_action->right = true;
break;
case SDL_SCANCODE_A:
p_action->left = true;
break;
case SDL_SCANCODE_SPACE:
p_action->p1Shooting = true;
break;
}
break;
case SDL_KEYUP:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_W:
p_action->up = false;
break;
case SDL_SCANCODE_S:
p_action->down = false;
break;
case SDL_SCANCODE_D:
p_action->right = false;
break;
case SDL_SCANCODE_A:
p_action->left = false;
break;
case SDL_SCANCODE_SPACE:
p_action->p1Shooting = false;
break;
}
break;
}
switch(event->type)
{
case SDL_QUIT:
*running = false;
break;
case SDL_KEYDOWN:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_UP:
p_action->up2 = true;
break;
case SDL_SCANCODE_DOWN:
p_action->down2 = true;
break;
case SDL_SCANCODE_RIGHT:
p_action->right2 = true;
break;
case SDL_SCANCODE_LEFT:
p_action->left2 = true;
break;
case SDL_SCANCODE_P:
p_action->p2Shooting = true;
break;
}
break;
case SDL_KEYUP:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_UP:
p_action->up2 = false;
break;
case SDL_SCANCODE_DOWN:
p_action->down2 = false;
break;
case SDL_SCANCODE_RIGHT:
p_action->right2 = false;
break;
case SDL_SCANCODE_LEFT:
p_action->left2 = false;
break;
case SDL_SCANCODE_P:
p_action->p2Shooting = false;
break;
}
break;
}
/*printf("----------------------\nACTIONS\n"
"1p: %d up, %d down, %d left, %d right\n"
"2p: %d up, %d down, %d left, %d right\n",
p_action->up,p_action->down,p_action->left,p_action->right,
p_action->up2,p_action->down2,p_action->left2,p_action->right2
);*/
}
And finally important part of main:
// Animation loop
while(running)
{
// events processing
while(SDL_PollEvent(&event))
{
eventsDetection(&event, p_action, &running);
}
// logic stuff
logicStuff(game);
// rendering
renderStuff(renderer, game);
// Show what was drawn
SDL_RenderPresent(renderer);
game.frames = game.frames + 1;
} // end of animation loop
Thank you very much for help.
It's has nothing to do with SDL, it's your keyboard. A common keyboard doesn't handle more than 2-3 keys at the same time and only if the keys are not on the same line or column. More info on wiki
I'm unable to move the rectangle I made in the program. There is no error message in the compiler when I run the program. Can you please tell me what I missed out in the keyboard event. Other event that I assigned to the window works fine. Instead of writing instructions down can you please show me the solution. I have been on this forever. Thanks
#include <SDL.h>
#include <stdlib.h>
int main()
{
SDL_Window *o;
SDL_Renderer *r;
SDL_Event e;
SDL_Rect q;
int i =1;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("Game test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
else if(e.type == SDL_KEYDOWN)
{
switch(e.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
i=0;
break;
case SDLK_UP:
q.y -=10;
break;
case SDLK_DOWN:
q.y +=10;
break;
case SDLK_RIGHT:
q.x +=10;
break;
case SDLK_LEFT:
q.x -=10;
break;
}
}
}
SDL_SetRenderDrawColor(r,0,0,255,255);
SDL_RenderClear(r);
// Creating the rectangle
q.x=475;
q.y=700;
q.h=50;
q.w=50;
SDL_SetRenderDrawColor(r,0,0,0,255);
SDL_RenderFillRect(r,&q);
SDL_RenderPresent(r);
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);
SDL_Quit();
return 0;
}
You didn't initialize the rectangle object:
SDL_Rect q;
before potentially modifying its values in the event loop, which will result in undefined behavior:
case SDLK_UP:
q.y -=10;
break;
Then any change made to the object is invalidated when you set constant values to it:
q.x=475;
q.y=700;
q.h=50;
q.w=50;
So the solution is clear, set the constant values to the object only when you define it.