GLUT_LEFT_BUTTON on glutMouseFunc is not working well - opengl

LEFT and RIGHT Button Mouse Events are working on the program as below.
void mouse(int button, int state, int x, int y)
{
if (button)
{
switch (state)
{
case GLUT_DOWN:
Mouse_X = x;
Mouse_Y = y;
break;
case GLUT_UP:
current = Target;
break;
default:
break;
}
}
}
Not only LEFT Button but also RIGHT BUTTON working in case of if (button==GLUT_LEFT_BUTTON) as below. Let me know how to solve it.
void mouse(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
Mouse_X = x;
Mouse_Y = y;
break;
case GLUT_UP:
current = Target;
break;
default:
break;
}
}
}

Related

The better way to control player in 2d game ? (sdl2)

I'm doing this like this, in .hpp file:
class Player
{
public:
Player(){}
Player(){}
virtual ~Player(){}
void handler(SDL_Event event);
void update()
{
move(velocityForwardX, velocityForwardY);
move(-velocityBackwardX, -velocityBackwardY);
/* the player moves from it current position. */
}
protected:
int speed = 5;
int velocityForwardX = 0;
int velocityForwardY = 0;
int velocityBackwardX = 0;
int velocityBackwardY = 0;
};
in .cpp file:
#include "Player.h"
void Player::handler(SDL_Event event)
{
if(event.type == SDL_KEYDOWN){
switch(event.key.keysym.sym)
{
case SDLK_d:
velocityForwardX = speed;
break;
case SDLK_q:
velocityBackwardX = speed;
break;
case SDLK_z:
velocityBackwardY = speed;
break;
case SDLK_s:
velocityForwardY = speed;
break;
default:
break;
}
}
else if(event.type == SDL_KEYUP){
switch(event.key.keysym.sym)
{
case SDLK_d:
velocityForwardX = 0;
break;
case SDLK_q:
velocityBackwardX = 0;
break;
case SDLK_z:
velocityBackwardY = 0;
break;
case SDLK_s:
velocityForwardY = 0;
break;
default:
break;
}
}}
like this I can presse any key and release it and the player move well. It also works if two opposite keys are pressed then one is release so the player is going in the right direction. Can we make it easier ? (sorry for my english)
You could store only one variable per direction and add and subtract speed when pressing and releasing a button, e.g.
switch(event.key.keysym.sym)
{
case SDLK_d:
velocityX += speed;
break;
case SDLK_q:
velocityX -= speed;
break;
case SDLK_z:
velocityY -= speed;
break;
case SDLK_s:
velocityY += speed;
break;
default:
break;
}
// similar for key release
With this if you press opposite x direction keys simultaniously, velocityX will be 0, and the same for the y direction and velocityY.

Strange behavior spotted c++ sdl2

Using sdl2 I managed to construct "soon-to-be-spaghetti" classes for a game. However when it came to using a function of a class I stumble upon this weirdness.
class Player{
public:
Player();
const SDL_Rect *getPositionPtr() const { return &position; }
const SDL_Rect * getClip(){ return &clip; }
void eventHandle(SDL_Event & e);
void move();
private:
SDL_Rect position;
SDL_Rect clip;
float velocity;
bool leftkeydown;
bool rightkeydown;
};
Player::Player(){
position = {100, 300, 64, 64};
clip = {0, 0, 64, 64};
velocity = 0.3;
leftkeydown = false;
rightkeydown = false;
}
void Player::eventHandle(SDL_Event & e){
if( e.type == SDL_KEYDOWN && e.key.repeat == 0 ){
switch( e.key.keysym.sym ){
case SDLK_a:
leftkeydown = true;
break;
case SDLK_d:
rightkeydown = true;
break;
}
}
else if( e.type == SDL_KEYUP && e.key.repeat == 0 ){
//Adjust the velocity
switch( e.key.keysym.sym ){
case SDLK_a:
leftkeydown = false;
break;
case SDLK_d:
rightkeydown = false;
break;
}
}
}
void Player::move(){
if(leftkeydown) position.x -= velocity;
if(rightkeydown) position.x += velocity; // <----- problem here
}
leftkeydown seems to work as expected but rightkeydown doesn't do anything to the position.x variable.
Any ideas why it is not incrementing?
as #keltar commended it happens because at int + (float < 0) the int stays the same because it converts the result (100.3) from float to int (100) (thats because one of the values is int) so the position x will stay the same unless you make the velocity int or bigger than 0.

Taking 2 keyboard inputs with sfml

How do I make my "game" take 2 key inputs, for example if the user clicks w and d he moves up right.
btw, the variable eventCheck is an Event object
here's my current code(obviously not the full code just the event code):
while (window.isOpen()) {
Event eventCheck;
while (window.pollEvent(eventCheck)) {
switch (eventCheck.type) {
case Event::Closed:
window.close();
break;
case Event::KeyPressed:
switch (eventCheck.key.code) {
case Keyboard::W:
if (Keyboard::isKeyPressed(Keyboard::A)) {
const Vector2f spritePos = sprite.getPosition();
sprite.setPosition(spritePos.x, spritePos.y - 5);}
break;
case Keyboard::A:
if (Keyboard::isKeyPressed(Keyboard::A)) {
const Vector2f spritePos = sprite.getPosition();
sprite.setPosition(spritePos.x - 5, spritePos.y);}
break;
case Keyboard::S:
if (Keyboard::isKeyPressed(Keyboard::S)) {
const Vector2f spritePos = sprite.getPosition();
sprite.setPosition(spritePos.x, spritePos.y + 5);}
break;
case Keyboard::D:
if (Keyboard::isKeyPressed(Keyboard::D)) {
const Vector2f spritePos = sprite.getPosition();
sprite.setPosition(spritePos.x + 5, spritePos.y);}
break;
}
}
break;
}
window.clear(Color(0,0,0,255));
window.draw(sprite);
window.display();
}
return 0;
1.) SFML has event polling through sf::Event and real time key state access provided through sf::Keyboard. If you only need to handle a single key press, your best bet is to poll them through window.pollEvent otherwise it's usually always better to get the state of a key and react based on the state. In this case you are mixing event polling with keyboard states. Choose one or the other.
2.) Not using sf:: removes a lot of clarity from the code
Now onto the code!
I wouldn't poll any user input inside events. I would get the state of the keys:
// Once per game loop
void ProcessInput()
{
int keyCount = 0;
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
keyCount++;
//Move Character Up, The more keys are pressed, the more i would mess around with speed/velocity here
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
keyCount++;
//Move Character Left, The more keys are pressed, the more i would mess around with speed/velocity here
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
keyCount++;
//Move Character Down, The more keys are pressed, the more i would mess around with speed/velocity here
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
keyCount++;
//Move Character Right, The more keys are pressed, the more i would mess around with speed/velocity here
}
}
Depending on the amount of keys the user pressed, you would want to move your character less since they could move more diagonally than vertically/horizontally, but mess around with speed and velocity as you see fit.
I ended up doing
bool moveL = false;
bool moveU = false;
bool moveD = false;
bool moveR = false;
while (window.isOpen()) {
Event eventCheck;
while (window.pollEvent(eventCheck)) {
switch (eventCheck.type) {
case Event::Closed:
window.close();
break;
case Event::KeyReleased:
switch (eventCheck.key.code) {
case Keyboard::A:
moveL = false;
break;
case Keyboard::W:
moveU = false;
break;
case Keyboard::S:
moveD = false;
break;
case Keyboard::D:
moveR = false;
break;
}
break;
case Event::KeyPressed:
switch (eventCheck.key.code) {
case Keyboard::A:
moveL = true;
break;
case Keyboard::W:
moveU = true;
break;
case Keyboard::S:
moveD = true;
break;
case Keyboard::D:
moveR = true;
break;
case Keyboard::Space:
jump(sprite, window);
break;
}
const Vector2f spritePos = sprite.getPosition();
if (moveD && moveR) {
sprite.setPosition(spritePos.x + 5, spritePos.y + 5);
}
else if (moveL && moveU) {
sprite.setPosition(spritePos.x - 5, spritePos.y - 5);
}
else if (moveU && moveD) {
sprite.setPosition(spritePos.x, spritePos.y);
}
else if (moveU && moveR) {
sprite.setPosition(spritePos.x + 5, spritePos.y - 5);
}
else if (moveD && moveL) {
sprite.setPosition(spritePos.x - 5, spritePos.y + 5);
}
else if (moveL) {
sprite.setPosition(spritePos.x - 5, spritePos.y);
}
else if (moveR) {
sprite.setPosition(spritePos.x + 5, spritePos.y);
}
else if (moveU) {
sprite.setPosition(spritePos.x, spritePos.y - 5);
}
else if (moveD) {
sprite.setPosition(spritePos.x, spritePos.y + 5);
}
break;
}
}
window.clear(Color(0,0,0,255));
window.draw(sprite);
window.display();
}
return 0;
}

Mouse Over in SDL/C++ not working

I have a simple script where by i want the script to load a second button when the mouse is hovering over the first initial button. But it won't return true so i can't seem to get it to work.
This is my class which checks the situation:
class Button
{
private:
int m_x, m_y;
int m_width, m_height;
public:
Button(int x, int y, int width, int height)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
}
bool IsIn( int mouseX, int mouseY )
{
if (((mouseX > m_x) && (mouseX < m_x + m_width))
&& ((mouseY > m_y) && (mouseY < m_y + m_height ) ) ) {
return true;
} else {
return false;
}
}
void Render(SDL_Surface *source,SDL_Surface *destination)
{
SDL_Rect offset;
offset.x = m_x;
offset.y = m_y;
offset.w = m_width;
offset.h = m_height;
source = IMG_Load("button.png");
SDL_BlitSurface( source, NULL, destination, &offset );
}
};
Its the IsIn function I am trying to get to work... in my main loop i have:
while(!quit){
while( SDL_PollEvent( &event ) )
switch( event.type ){
case SDL_QUIT: quit = true; break;
case SDL_MOUSEMOTION: mouseX = event.motion.x; mouseY = event.motion.y; break;
}
Button btn_quit(screen->w/2,screen->h/2,0,0);
btn_quit.Render(menu,screen);
if(btn_quit.IsIn(mouseX,mouseY)){
Button btn_settings(screen->w/2,screen->h/2+70,0,0);
btn_settings.Render(menu,screen);
}
SDL_Quit works fine but i can't seem to get the if statement after the case statement to return true when i hover the mouse over the btn_quit button. Any ideas why this might be ?
Because btn_quit has no width or height, and therefore you can never be inside it's bounds.
Button btn_quit(screen->w/2,screen->h/2,0,0);
You checks will fail because your mouse position can never be >x && <x+0 or >y && <y+0.
Perhaps a better way would be to define the location of your button, and let get the dimensions from the loaded image?
class Button
{
public:
// Construct the button with an image name, and position on screen.
// This is important, your existing code loaded the image each render.
// That is not necessary, load it once when you construct the class.
Button(std::string name, int x, int y) : img(IMG_Load(name))
{
if(img) // If the image didn't load, NULL is returned.
{
// Set the dimensions using the image width and height.
offset.x = x; offset.y = y;
offset.w = img.w; offset.h = img.h;
}
else { throw; } // Handle the fact that the image didn't load somehow.
}
~Button() { SDL_FreeSurface(img); } // Make sure you free your resources!
void Render(SDL_Surface *destination)
{
// Simplified render call.
SDL_BlitSurface(img, NULL, destination, &offset );
}
bool Contains(int x, int y)
{
if((x>offset.x) && (x<offset.x+offset.w)
&& (y>offset.y) && (y<offset.y+offset.h))
return true; // If your button contains this point.
return false; // Otherwise false.
}
private:
SDL_Rect offset; // Dimensions of the button.
SDL_Surface* img; // The button image.
}

C++ SDL program terminates immediately

I've been following LazyFoo's tutorial for a while. But I haven't been able to get this to initialize a week a go. I went back to it recently, after error checking, I found it that the window initializes properly, but the images won't load. What is the reason for it?
#include "SDL/SDL.h"
#include <string>
//setting screen info
const int SCH=640;
const int SCW=480;
const int BBP=32;
const char* name = "TEHGAEM";
// sprite height and width
const int SPH=45;
const int SPW=45;
//initilize event
SDL_Event event;
//loading surfaces for screen, sprite, and temp sprite
SDL_Surface *screen=NULL;
SDL_Surface *sprite=NULL;
SDL_Surface *temp = NULL;
//making class for movable objects
class Player
{
private:
int x,y;
int xVel,yVel;
public:
Player();
void show();
void move();
void handle_input();
};
//initializing variables
Player::Player()
{
x=0;
y=0;
xVel=0;
yVel=0;
}
//intended to show player picture
void Player::show()
{
SDL_Rect pos;
pos.x=x;
pos.y=y;
SDL_BlitSurface(sprite, NULL, screen, &pos);
SDL_UpdateRects(screen, 1, &pos);
}
//setting input
void Player::handle_input()
{
if (event.type ==SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_UP: yVel -= SPH /2; break;
case SDLK_DOWN: yVel += SPH /2; break;
case SDLK_LEFT: xVel -=SPW /2; break;
case SDLK_RIGHT: xVel +=SPW /2; break;
}
}
if (event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel += SPH /2; break;
case SDLK_DOWN: yVel -= SPH /2; break;
case SDLK_LEFT: xVel +=SPW /2; break;
case SDLK_RIGHT: xVel -=SPW /2; break;
}
}
}
void Player::move()
{
x=+xVel;
y=+yVel;
if (x >= SCW)
{
x-10;
}
if (y >= SCH)
{
y-10;
}
}
//initializing program
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING)==-1)
{
return false;
}
screen = SDL_SetVideoMode(SCH,SCW,BBP, SDL_SWSURFACE);
if (screen == NULL)
{
return false;
}
SDL_WM_SetCaption(name, NULL);
return true;
}
//loading images
bool somethings()
{
temp = SDL_LoadBMP("sprite.bmp");
if (temp == NULL)
{
return false;
}
sprite = SDL_DisplayFormat (temp);
if (sprite ==NULL)
{
return false;
}
SDL_FreeSurface(temp);
return true;
}
//clean up function
void clean()
{
SDL_FreeSurface(sprite);
SDL_Quit();
}
int main(int argc, char* args[])
{
Player P1;
bool quit;
if (init() == false)
{
return 1;
}
if (somethings() ==false)
{
return 1;
}
while (quit ==false)
{
while (SDL_PollEvent(&event))
{
P1.handle_input();
if (event.type == SDL_QUIT)
{
quit == true;
}
}
if (SDL_Flip(screen) ==-1)
{
return 1;
}
P1.move();
P1.show();
}
clean();
return 0;
}
This isn't completely related to your problem but the varible bool quit; isn't defined as true or false before the main while( quit == false ) { ... }loop. This could produce undefined while loop behavior.
int main(int argc, char* args[])
{
Player P1;
bool quit = false; // CHANGE THIS AND SEE WHAT HAPPENS
if (init() == false)
{
return 1;
}
if (somethings() ==false)
{
return 1;
}
while (quit ==false)
{
while (SDL_PollEvent(&event))
{
P1.handle_input();
if (event.type == SDL_QUIT)
{
quit == true;
}
}
if (SDL_Flip(screen) ==-1)
{
return 1;
}
P1.move();
P1.show();
}
clean();
return 0;
}
About the images not loading, step through your program with a debugger and watch your somethings()function and follow the variables temp and sprite.
Make sure your "sprite.bmp" file is located in the running directory of this program. I tested it and it works for me.
Also this has no effect:
if (x >= SCW)
{
x-10;
}
if (y >= SCH)
{
y-10;
}
You probably wanted to say x -= 10; and y -= 10;.
This makes your 'player' jump back to the original position immediately:
if (event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel += SPH /2; break;
case SDLK_DOWN: yVel -= SPH /2; break;
case SDLK_LEFT: xVel +=SPW /2; break;
case SDLK_RIGHT: xVel -=SPW /2; break;
}
}
You probably only need to handle SDL_KEYDOWN event.
Hope that helps.
There are big chances that you aren't loading the bitmap. But anything that you are trying to print on the screen and wasn't loaded can terminate the app.