SDL Moving my character - sdl

I've a problem with my source code. basically, I tried to move a sprite character in 2D map
here's my warrior class:
class Warrior
{
private :
int HP, SP;
int xPos, yPos;
int status;
char *name;
SDL_Surface *warrior;
Map m;
public :
int atk, def, matk, mdef;
Warrior(int, int, int, Map);
int getHP();
bool isAlive();
int getSP();
int getX();
int getY();
void setX(int);
void setY(int);
void changeStatus(int);
void drawChar();
void move();
void deleteChar();
};
//constructor buat warrior
Warrior::Warrior(int pos, int x, int y, Map _m)
{
HP = 250;
SP = 50;
atk = 75;
def = 20;
matk = 15;
mdef = 5;
warrior = NULL;
m = _m;
status = pos;
xPos = x;
yPos = y;
}
bool Warrior::isAlive()
{
if (HP > 0) return true;
return false;
}
//buat ngilangin character warrior-nya...
//timpa ama sprite rumput di coord char-nya
void Warrior::deleteChar()
{
char path = '0';
m.drawTile(xPos, yPos, path);
m.drawTile(xPos, yPos+20, path);
SDL_Flip (SDL_SCREEN);
}
//buat gambar character
void Warrior::drawChar ()
{
switch (status)
{
case WARRIOR_LEFT :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_LEFT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_RIGHT :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_RIGHT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_UP :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_UP.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_DOWN :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_DOWN.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_MOVE_LEFT :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_MOVE_LEFT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
SDL_Flip(SDL_SCREEN);
SDL_Delay (100);
deleteChar();
status = WARRIOR_LEFT;
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_LEFT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_MOVE_RIGHT :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_MOVE_RIGHT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
SDL_Flip(SDL_SCREEN);
SDL_Delay (100);
deleteChar();
status = WARRIOR_RIGHT;
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_RIGHT.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_MOVE_UP :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_MOVE_UP.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
SDL_Flip(SDL_SCREEN);
SDL_Delay (100);
deleteChar();
status = WARRIOR_UP;
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_UP.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
case WARRIOR_MOVE_DOWN :
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_MOVE_DOWN.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
SDL_Flip(SDL_SCREEN);
SDL_Delay (100);
deleteChar();
status = WARRIOR_DOWN;
warrior = IMG_Load ("Sprites/Warrior/WARRIOR_DOWN.png");
applySurface (xPos, yPos, warrior, SDL_SCREEN);
break;
}
SDL_Flip(SDL_SCREEN);
}
int Warrior::getX()
{
return xPos;
}
int Warrior::getY()
{
return yPos;
}
void Warrior::setX(int x)
{
xPos = x;
}
void Warrior::setY(int y)
{
yPos = y;
}
int Warrior::getHP()
{
return HP;
}
int Warrior::getSP()
{
return SP;
}
void Warrior::changeStatus(int _status)
{
status = _status;
}
//jalannya karakter
void Warrior::move()
{
if (event.type == SDL_KEYDOWN)
{
//hilangkan char-nya dolo
deleteChar();
switch (event.key.keysym.sym)
{
case SDLK_UP :
// nge-cek collision dari coord peta-nya (Map m)
if (m.map[m.getLevel()][(yPos/20)-1][xPos] == '0')
{
yPos -= 20;
status = WARRIOR_MOVE_UP;
}
break;
case SDLK_DOWN :
if (m.map[m.getLevel()][(yPos/20)+1][xPos/20] == '0')
{
yPos += 20;
status = WARRIOR_MOVE_DOWN;
}
case SDLK_LEFT :
if (m.map[m.getLevel()][yPos/20][(xPos/20)-1] == '0')
{
xPos -= 20;
status = WARRIOR_MOVE_LEFT;
}
case SDLK_RIGHT :
if (m.map[m.getLevel()][yPos/20][(xPos/20)+1] == '0')
{
xPos += 20;
status = WARRIOR_MOVE_RIGHT;
}
}
//bru di-gambar
drawChar();
SDL_Delay (100);
}
}
The problem is I can't move it, and the program wasn't responding at all... I've checked all the sprite images and it works fine.

Post your main loop.
Add prints in various places in your code, so you can see where it hangs.
Don't call IMG_Load every frame. Load your images at start-up.
SDL_Surfaces loaded with IMG_Load have to be freed with SDL_FreeSurface when no longer needed. Especially if you are loading a lot of them.
You don't have to call SDL_Flip every time you change something. Just make sure you call it at end of every frame.

You can add your Sprite image to a map like textureMap(stringID, pTexture) before enter play state:
SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
SDL_Texture* pTexture = SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
SDL_FreeSurface(pTempSurface);
m_textureMap[id] = pTexture;
When draw the hero, you can use the stringID to get the texture:
SDL_RenderCopyEx(pRenderer, m_textureMap[stringID], &srcRect, &destRect, 0, 0, flip);
For you do not post your main loop, you may should catch input in main loop like:
SDL_Event event;
if (SDL_PollEvent(&event))
{
switch (event.type)
{....}
}
Make sure you get the input event first and then check the draw position every frame.

Related

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.

View class is not receiving updated Model class data

Model class
class spaceshipModel {
private:
Vector2f position;
float speed, acceleration, energy, fuel;
public:
//Contructor
spaceshipModel() : position(0, 0), speed(0), acceleration(0), energy(0), fuel(0) {}
//Destructor
~spaceshipModel() {}
//Sets
void setPosition(float _x, float _y) { position.x = _x; position.y = _y; }
void setSpeed(float _speed) { speed = _speed; }
void setAcceleration(float _acceleration) { acceleration = _acceleration; }
void setEnergy(float _energy) { energy = _energy; }
void setFuel(float _fuel) { fuel = _fuel; }
//Gets
Vector2f getPosition() { return position; }
float getSpeed() { return speed; }
float getAcceleration() { return acceleration; }
float getEnergy() { return energy; }
float getFuel() { return fuel; }
};
View class
class spaceshipView {
private:
Texture* image;
Sprite sprite;
spaceshipModel model;
public:
//Constructor
spaceshipView() : image(0) {}
//Destructor
~spaceshipView() {}
//Setting the image
void setImage(Texture* _image) { image = _image; }
//Drawing the image
void drawImage(RenderWindow* _window) {
sprite.setTexture(*image);
sprite.setPosition(model.getPosition());
sprite.setScale(Vector2f(0.2f, 0.2f));
_window->draw(sprite);
_window->display();
}
};
Main
A left a lot of the code out, but I then call this in main:
int main() {
//Call instance of the Spaceship model
spaceshipModel shipModel;
//Call instance of the Spaceship view
spaceshipView shipView;
//Create the texture of the spaceship from file
Texture spaceship;
spaceship.loadFromFile("spaceship.png");
//Create the window
RenderWindow window(VideoMode(800, 600), "Spaceship with MVC");
//Run the program as long as the window is open
while (window.isOpen()) {
//Check all the window's events that were triggered since the last iteration of the loop
Event event;
while (window.pollEvent(event)) {
//"Close requested" event: we close the window
switch (event.type) {
//Window closed by pressing the X
case Event::Closed:
window.close();
break;
//Checking for key pressed event
case Event::KeyPressed:
//Pressing esc to close the window
if (event.key.code == Keyboard::Escape) {
window.close();
}
break;
//We don't process other types of events
default:
break;
}
//Clear screen with white BG
window.clear(Color::White);
//TESTING THE SETTING OF THE POSITION
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
shipModel.setPosition(100, 100);
std::cout << shipModel.getPosition().x << ", " << shipModel.getPosition().y << std::endl;
//Set and draw the image
shipView.setImage(&spaceship);
shipView.drawImage(&window);
}
}
return 0;
}
The spaceship draws perfectly, but is only set at (0, 0). Even when setting the position to (100, 100) like it shows above. The image stays at (0, 0). As I'm using the getPosition function from the Model class in the View class, I don't think the data is being updated correctly, even when the cout test does show a change.
What am I doing wrong? Can someone give me some pointers?
In the code snippet above, shipModel object from main() and shipView.model are two distinct objects. You can either let your shipView be aware of the model using a setter in spaceshipView, or call shipView.model's methods directly.

RenderWindow Constantly Updating display() Causing Flickering

I am trying to write a program which allows users to draw using the mouse. I have been trying many different ways to appropriately update the display using an object of sf::RenderWindow to call display() without much success. My loop where the drawing is occurring is calling display so fast it's causing massive flickering (confirmed that through testing). If I add a way to slow the call to display(), like using sf::Clock, then the drawing is only updated on the same delay as display() resulting in a stuttering effect. What I need is a way to update the display often enough to show drawing updates while also not causing a screen flicker.
Currently, I've got the display on a delay (at the bottom of the event polling switch statement) so flickering doesn't occur, but adding mainWindow.display(); to the void MainWindow::draw() function causes flickering as it updates too quickly. I had the drawing occurring on sf::Event::MouseMoved, but I tried changing it to see if that would help, and it did not.
Here's where all the drawing and event detection occurs:
MainWindow.h
#pragma once
#include "GraphPaper.h"
#include "stdafx.h"
class MainWindow
{
public:
MainWindow(short, short);
void close();
void start();
void moveCamera(sf::Keyboard::Key);
void draw(sf::Event);
void displayWindow(sf::Vector2i&);
private:
bool leftMousePressed, rightMousePressed, isExiting;
int r, g, b, mouseX, mouseY;
short height, width;
const short DRAWING_CRICLE_RADIUS = 10;
GraphPaper paper;
//DrawingBrush brush;
const sf::Color WHITE = sf::Color(255, 255, 255);
const sf::Color BLACK = sf::Color(0, 0, 0);
sf::CircleShape circle;
sf::Mouse cursor;
sf::Vector2i windowCenter;
sf::RenderWindow mainWindow;
sf::View view;
};
MainWindow.cpp:
#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"
MainWindow::MainWindow(short height, short width)
{
this->height = height;
this->width = width;
circle.setRadius(DRAWING_CRICLE_RADIUS);
circle.setFillColor(BLACK);
}
void MainWindow::start()
{
sf::Clock clock;
mainWindow.create(sf::VideoMode(height, width, 32), "Test");
sf::View view(sf::FloatRect(0,0,height,width));
mainWindow.setView(view);
leftMousePressed, rightMousePressed, isExiting = false;
sf::Event currentEvent;
sf::Vector2i windowCenter(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
while (!isExiting)
{
sf::Clock clock;
while (mainWindow.pollEvent(currentEvent))
{
switch (currentEvent.type)
{
case sf::Event::MouseMoved:
{
if (rightMousePressed == true)
{
std::cout << "Mouse Panned\n";
}
if (leftMousePressed == true)
{
draw(currentEvent);
}
break;
}
case sf::Event::MouseButtonPressed:
{
std::cout << "Mouse Pressed\n";
mouseX = currentEvent.mouseButton.x;
mouseY = currentEvent.mouseButton.y;
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
while (currentEvent.type != sf::Event::MouseButtonReleased)
{
std::cout << "Mouse is Drawing\n";
draw(currentEvent);
mainWindow.pollEvent(currentEvent);
}
}
else if (currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = true;
}
break;
}
case sf::Event::MouseButtonReleased:
{
std::cout << "Mouse Released\n";
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
leftMousePressed = false;
}
else if(currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = false;
}
break;
}
case sf::Event::KeyPressed:
{
sf::Keyboard::Key keyPressed = currentEvent.key.code;
if(keyPressed == sf::Keyboard::Escape)
{
close();
}
else if(keyPressed == sf::Keyboard::Left || sf::Keyboard::Right ||
sf::Keyboard::Down || sf::Keyboard::Up ||
sf::Keyboard::A || sf::Keyboard::S ||
sf::Keyboard::D || sf::Keyboard::W)
{
moveCamera(keyPressed);
displayWindow(windowCenter);
}
break;
}
case sf::Event::Closed:
{
close();
break;
}
case sf::Event::Resized:
{
windowCenter = sf::Vector2i(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
break;
}
}
if (clock.getElapsedTime().asMilliseconds() >= 500)
{
clock.restart();
mainWindow.display();
}
}
}
}
void MainWindow::moveCamera(sf::Keyboard::Key keyPressed)
{
view = mainWindow.getView();
switch (keyPressed)
{
case sf::Keyboard::A:
case sf::Keyboard::Left:
{
view.move(-50, 0);
break;
}
case sf::Keyboard::D:
case sf::Keyboard::Right:
{
view.move(50, 0);
break;
}
case sf::Keyboard::W:
case sf::Keyboard::Up:
{
view.move(0, 50);
break;
}
case sf::Keyboard::S:
case sf::Keyboard::Down:
{
view.move(0, -50);
break;
}
}
mainWindow.setView(view);
}
void MainWindow::draw(sf::Event mouse)
{
circle.setPosition(mainWindow.mapPixelToCoords(sf::Vector2i(mouse.mouseMove.x, mouse.mouseMove.y)));
mainWindow.draw(circle);
}
void MainWindow::close()
{
std::cout << "Closing...\n";
mainWindow.close();
isExiting = true;
}
void MainWindow::displayWindow(sf::Vector2i& windowCenter)
{
mainWindow.clear(WHITE);
mainWindow.draw(paper.getSprite());
mainWindow.display();
cursor.setPosition(windowCenter);
}
You are missing an important part of the rendering loop. You should draw all parts every loop iteration. Right now you are only drawing your circle when it's changed.
Your code should look like this:
change circle position based on input
clear window
draw circle
display

Collision with more than 1 Object SDL 2.0-C++

I'am new there. I've been learning classes and tried to make a very simple platform game. But I have problem now. I've wanted to set Class "Player" to collide with 2 objects of Class "Block" But Collision do not work for one of them.
Here is my code:
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#undef main
class Block
{
private:
SDL_Texture *BlockTexture;
public:
Block(SDL_Renderer *renderTarget, std::string filePath, int xPos, int yPos, int Width, int Height);
~Block();
void Draw(SDL_Renderer *renderTarget);
SDL_Rect BlockPos;
};
Block::Block(SDL_Renderer *renderTarget, std::string filePath, int xPos, int yPos, int Width, int Height)
{
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
BlockTexture = SDL_CreateTextureFromSurface(renderTarget, surface);
}
SDL_FreeSurface(surface);
BlockPos.x = xPos;
BlockPos.y = yPos;
BlockPos.w = Width;
BlockPos.h = Height;
}
Block::~Block()
{
SDL_DestroyTexture(BlockTexture);
}
void Block::Draw(SDL_Renderer *renderTarget)
{
SDL_RenderCopy(renderTarget, BlockTexture, NULL, &BlockPos);
}
class Player
{
private:
SDL_Texture *Texture;
float moveSpeed;
float jumpSpeed;
int falling = 0;
SDL_Scancode keys [3];
public:
SDL_Rect PlayerPos;
Player(SDL_Renderer *renderTarget, std::string filePath, int PosX, int PosY, int Width, int Height);
~Player();
void Update(float delta, const Uint8 *Keystate);
void Draw(SDL_Renderer *renderTarget);
bool Collision(Block &p);
};
Player::Player(SDL_Renderer *renderTarget, std::string filePath, int PosX, int PosY, int Width, int Height)
{
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
Texture = SDL_CreateTextureFromSurface(renderTarget, surface);
}
SDL_FreeSurface(surface);
PlayerPos.x = PosX;
PlayerPos.y = PosY;
PlayerPos.w = Width;
PlayerPos.h = Height;
keys[0] = SDL_SCANCODE_UP;
keys[1] = SDL_SCANCODE_LEFT;
keys[2] = SDL_SCANCODE_RIGHT;
moveSpeed = 200.f;
jumpSpeed = 100.f;
}
Player::~Player()
{
SDL_DestroyTexture(Texture);
}
void Player::Update(float delta, const Uint8 *KeyState)
{
if(KeyState[keys[0]])
{
PlayerPos.y -= moveSpeed * delta;
}
if(KeyState[keys[1]])
{
PlayerPos.x -= (moveSpeed / 2) * delta;
}
if(KeyState[keys[2]])
{
PlayerPos.x += moveSpeed * delta;
}
if(falling == 0)
{
PlayerPos.y += jumpSpeed * delta;
}
}
void Player::Draw(SDL_Renderer *renderTarget)
{
SDL_RenderCopy(renderTarget, Texture, NULL, &PlayerPos);
}
bool Player::Collision(Block &p)
{
if(PlayerPos.x + PlayerPos.w <= p.BlockPos.x || PlayerPos.x >= p.BlockPos.x + p.BlockPos.w ||
PlayerPos.y + PlayerPos.h <= p.BlockPos.y || PlayerPos.y >= p.BlockPos.y + p.BlockPos.h)
{
falling = 0;
return true;
}
else
falling = 1;
return false;
}
SDL_Texture *LoadTexture(std::string filePath, SDL_Renderer *Renderer)
{
SDL_Texture *texture = NULL;
SDL_Surface *surface = IMG_Load(filePath.c_str());
{
texture = SDL_CreateTextureFromSurface(Renderer, surface);
}
SDL_FreeSurface(surface);
return texture;
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("Platform", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
SDL_Renderer *renderTarget = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
int imgFlags = IMG_INIT_PNG;
int currentTime = 0;
int previousTime = 0;
float delta = 0;
const Uint8 *Keystate;
Player Player(renderTarget, "BlockP.png", 100, 100, 50, 50);
Block Block1(renderTarget, "Block.png", 0, 500, 800, 100);
Block Block2(renderTarget, "Block.png", 100, 300, 300, 50);
bool isRunning = true;
SDL_Event ev;
while(isRunning)
{
Keystate = SDL_GetKeyboardState(NULL);
Player.Collision(Block1);
Player.Collision(Block2);
previousTime = currentTime;
currentTime = SDL_GetTicks();
delta = (currentTime - previousTime) / 1000.0f;
Player.Update(delta, Keystate);
while(SDL_PollEvent(&ev) != 0)
{
if(ev.type == SDL_QUIT)
isRunning = false;
}
SDL_RenderClear(renderTarget);
Player.Draw(renderTarget);
Block1.Draw(renderTarget);
Block2.Draw(renderTarget);
SDL_RenderPresent(renderTarget);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderTarget);
window = NULL;
renderTarget = NULL;
SDL_Quit();
return 0;
}
The problem with your code is that each call to Player.Collision overwrites the "falling" variable.
Player.Collision(Block1); //this call calculates a falling value
Player.Collision(Block2); //...then this call overwrites falling with a new value
So effectively your code is only testing if the player is colliding with Block2, so collisions with Block1 are ignored.
Currently your Collision function is:
bool Player::Collision(Block &p)
{
if(PlayerPos.x + PlayerPos.w <= p.BlockPos.x || PlayerPos.x >= p.BlockPos.x + p.BlockPos.w ||
PlayerPos.y + PlayerPos.h <= p.BlockPos.y || PlayerPos.y >= p.BlockPos.y + p.BlockPos.h)
{
falling = 0;
return true;
}
else
falling = 1;
return false;
}
Firstly, your "return false;" is not actually part of the else, as you don't have {}. In this particular case it makes no difference as the else is exited and then the return happens but your indentation would suggest you expect the "return false;" line to be executed as part of the else block so you should put:
else
{
falling = 1;
return false;
}
Next you want to say if you have already detected a collision (eg, with Block1) then don't set falling to 1, to do this add an if statement.
else
{
if(falling != 0) //if we haven't already detected a collision this frame
{
falling = 1;
}
return false;
}
You will however need to set falling back to 1 at the start of each frame, otherwise if a collision is detected on one frame then the player will never fall on subsequent frames, even if they are not colliding with a block.
As a side note, your Player.Update code modifies the player's y position if falling == 0, this seems counter intuitive as usually 0 is false and 1 is true, hence you seem to be saying if not falling then update y, where as it should be if falling update y. Personally I would use a bool rather than an int to hold the value of falling, and then say if(falling) update y, this would make your code clearer.

More SDL C++ Opengl display trouble

I seem to be having the same trouble over and over again and cannot get my thick head around it. This program will not display a paddle as I want (and expected it) to do on screen :( -
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
SDL_Event event;
const int paddle_width = 20;
const int paddle_height = 80;
class PlayerPaddle
{
private:
int xloc;
int yloc;
int yvel;
public:
PlayerPaddle()
{
int xloc = 20;
int yloc = 200;
int yvel = 0;
}
void ShowPaddle()
{
glTranslatef(xloc,yloc,0);
glBegin(GL_QUADS);
glColor4f(1.0,1.0,1.0,1.0);
glVertex3f(0,0,0);
glVertex3f(20,0,0);
glVertex3f(20,80,0);
glVertex3f(0,80,0);
glEnd();
glLoadIdentity();
}
void MovePaddle()
{
yloc += yvel;
}
void Handle_Input()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yvel -= paddle_height / 2; break;
case SDLK_DOWN: yvel += paddle_height / 2; break;
}
}
else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yvel += paddle_height / 2; break;
case SDLK_DOWN: yvel -= paddle_height / 2; break;
}
}
}
};
void init ()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(640,480,32,SDL_OPENGL);
SDL_WM_SetCaption( "Pong", NULL );
glClearColor( 0, 0, 0, 0 );
glViewport(0, 0, 640, 480);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640 , 480 , 0, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
}
int main (int argc, char **argv)
{
init();
PlayerPaddle ppaddle;
bool quit = false;
while (quit == false)
{
while (SDL_PollEvent (&event))
{
ppaddle.Handle_Input();
if (event.type == SDL_QUIT)
quit = true;
}
ppaddle.MovePaddle();
glClear(GL_COLOR_BUFFER_BIT);
ppaddle.ShowPaddle();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}
I just get a clear black screen until I quit the program which returns 0 as expected. I know the code:
ppaddle.MovePaddle();
glClear(GL_COLOR_BUFFER_BIT);
ppaddle.ShowPaddle();
SDL_GL_SwapBuffers();
iterates at least once as if I inserted a return 1; statement in there the program would start up and return 1 immediately.
At a minimum you screwed up your constructor. Again.
It should probably be this:
PlayerPaddle()
{
xloc = 20;
yloc = 200;
yvel = 0;
}
You may also want to toss in a SDL_Delay(100) at the end of your main loop to slow things down until you get some more sophisticated physics handling going.