Draw image in function - c++

I want an image to be drawn when the space key is pressed. This is my code:
void drawImage()
{
rect.x = 100;
rect.y = 100;
SDL_Surface *image = IMG_Load("image.png");
SDL_BlitSurface(image, NULL, screen, &rect);
}
Here is it called:
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_SPACE)
{
drawImage();
}
}
}
The image isn't drawn when I press the space key. What is wrong?

Flip the screen buffers (SDL_Surfaces).

After your line
SDL_BlitSurface(image, NULL, screen, &rect);
Add
SDL_UpdateRect(screen, 0, 0, 0, 0);

Does the function draws, in the main loop without the space pressing thing?
bool draw = false;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_SPACE)
{
draw = true;
}
}
}
int main()
{
if(draw){
drawImage();
}
//DO SOME ERROR CHECKING
}

Related

SFML/C++ Sprite Disappearing After Certain Point

int main() {
sf::RenderWindow window;
sf::Vector2i centerWindow((sf::VideoMode::getDesktopMode().width / 2) - 445, (sf::VideoMode::getDesktopMode().height / 2) - 480);
window.create(sf::VideoMode(900, 900), "SFML Game", sf::Style::Titlebar | sf::Style::Close);
window.setPosition(centerWindow);
window.setKeyRepeatEnabled(true);
sf::Texture wallTxture;
sf::Sprite wall;
if (!wallTxture.loadFromFile("wall.png")) {
std::cerr << "Error\n";
}
wall.setTexture(wallTxture);
//Gravity Vars:
int groundHeight = 750;
bool isJumping = false;
//Movement Vars:
bool goingRight = false;
bool goingLeft = false;
//Set View Mode:
sf::View followPlayer;
followPlayer.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
Player player("newPlayer.png");
player.setPos({ 800, 800 });
sf::Vector2f position(window.getSize().x / 2, window.getSize().y / 2);
//Main Loop:
while (window.isOpen()) {
const float moveSpeed = 0.1;
sf::Event Event;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
isJumping = true;
//Handle Movement While Jumping:
if (goingLeft == true) {
player.move({ -moveSpeed, -moveSpeed });
}
else if (goingRight == true) {
player.move({ moveSpeed, -moveSpeed });
}
else {
player.move({ 0, -moveSpeed });
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
player.move({ 0, moveSpeed });
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
player.move({ -moveSpeed, 0 });
goingLeft = true;
player.flipX('l');
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
player.move({ moveSpeed, 0 });
goingRight = true;
player.flipX('r');
}
//Event Loop:
while (window.pollEvent(Event)) {
switch (Event.type) {
case sf::Event::Closed:
window.close();
case sf::Event::KeyReleased:
if (Event.key.code == sf::Keyboard::Up) {
isJumping = false;
}
else if (Event.key.code == sf::Keyboard::Left) {
goingLeft = false;
}
else if (Event.key.code == sf::Keyboard::Right) {
goingRight = false;
}
}
}
if (player.getX() > window.getSize().x) {
position.x = player.getX();
}
else {
position.x = window.getSize().x;
}
//If player is in air and not jumping:
if (player.getY() < groundHeight && isJumping == false) {
player.move({ 0, moveSpeed });
}
followPlayer.setCenter(position);
window.clear();
window.setView(followPlayer);
window.draw(wall);
player.drawTo(window);
window.display();
}
}
this is my code. What I am trying to do is create a 2D platformer sidescroller. Everything works, except when the sprite goes past a certain point it'll just disappear. This also happens when I jump and move through the air at the same time. I cannot figure out why this is happening, any help would be greatly appreciated :)
I fixed the problem by just getting rid of my flipX function, and instead just creating a new sprite facing a different direction, then changing it everytime the user is facing a new direction

How ove the player in SFML with c++

I'm doing a game in c++ with SFML. I've written a code for move the player, but when the game start the player, moves but when i leave the button the player return at its original position.Can you help me, please?
The main:
#include <iostream>
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(1320, 840), "Window");
window.setPosition(sf::Vector2i(150, 50));
window.setSize(sf::Vector2u(1320, 840));
window.getPosition();
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(5);
window.getSize();
while (window.isOpen()) {
window.clear(sf::Color::White);
//texture
sf::Texture texture;
if (!texture.loadFromFile("/users/gaetanodonnarumma/desktop/background1.png", sf::IntRect(0, 0, 1320, 840))) {
return -1;
}
sf::Texture playerTexture;
if (!playerTexture.loadFromFile("/users/gaetanodonnarumma/desktop/quadrato-giallo.jpg", sf::IntRect(0, 0, 70, 70))) {
return -1;
}
//sprite
sf::Sprite backgroud;
backgroud.setTexture(texture);
sf::Sprite player;
double pX = 0;
double pY = 770;
player.setTexture(playerTexture);
player.setPosition(sf::Vector2f(pX, pY));
player.getPosition();
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::D) {
player.move(10.f, 0.f);
}
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::D) {
player.setPosition(pX + 10, 770);
}
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::A) {
player.move(-5.f, 0.f);
}
}
}
//draw
window.draw(backgroud);
window.draw(player);
window.display();
}
return 0;
}
All your initialization code is running on every frame. This means that on every frame, you are creating (and destroying) a new player, setting its texture, and setting its position to [0, 770].
Move all the initialization to before the main draw loop begins (before while (window.isOpen())).

moving ping-pong rackets at the same time

Well, I've already started a graphic project on c++ and now I need some help.
This is a ping-pong game which has 2 rackets; one goes up and down via UP and DOWN keys, and the other moves by S and W keys.
I need to do something that it both players will be able to move their rackets at the same time.
sorry for my bad English!
#include <iostream>
#include "SDL/SDL.h"
#include <SDL/SDL_gfxPrimitives.h>
using namespace std;
int main()
{
SDL_Surface* screen = SDL_SetVideoMode(1200, 800 ,32, 0);
int i=0,j = 0;
bool a = 0 ;
while(true)
{
boxRGBA(screen, 1000, 200+j, 1050, 350+j, 0, 0, 0, 255);
boxRGBA(screen, 100, 200+i,150,350+i,0,0,0,255);
SDL_Event event;
if(!SDL_PollEvent(&event));
{
if(event.type == SDL_QUIT)
return 0;
if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_UP)
j -=10;
if(event.key.keysym.sym == SDLK_DOWN)
j +=10;
if(event.key.keysym.sym == SDLK_w)
i-=10;
if(event.key.keysym.sym == SDLK_s)
i+=10;
}
else if (event.type == SDL_KEYUP)
a=1;
}
//if(a)
//j += b;
boxRGBA(screen, 1000, 200+j, 1050, 350+j, 255, 50, 0, 255);
boxRGBA(screen, 100, 200+i,150,350+i,50,0,255,255);
SDL_Flip(screen);
SDL_Delay(2);
}
SDL_Delay(5000);
return 0;
}
if(!SDL_PollEvent(&event)); // what's ; doing here? Why are you negating the return value?
Try and change this to while:
while(SDL_PollEvent(&event)) { ... }
That way it will poll all available events in the queue.
SDL_GetKeyboardState givs you a snapshot of the current state of the keyboard.
const Uint8 *state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_UP])
j -=10;
if (state[SDL_SCANCODE_DOWN])
j +=10;
if (state[SDL_SCANCODE_W])
i -=10;
if (state[SDL_SCANCODE_S])
i +=10;

Game Launches to a blank white screen instead of loadingscreen

Trying to create a game but i've run into my first hurdle. The game launches into a blank white screen instead of showing the Red screen and i cant proceed into the loading screen and the menu. I've checked that I'm using display for each of my screens but can't figure out where i'm going wrong. I also get no errors. Below is my code
game.cpp
#include "stdafx.h"
#include "Game.h"
#include "LoadScreen.h"
#include "MainMenu.h"
void Game::Start (void)
{
Game game;
if(_gameState != Unlaunched)
return;
game._mainWindow.create(sf::VideoMode(1024,768,32),"Code Matrix");
_gameState = Game::LogoScreen;
while (!Exists())
{
GameLoop();
}
game._mainWindow.close();
}
bool Game::Exists()
{
if(_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
Game game;
sf::Event currentEvent;
while (game._mainWindow.pollEvent(currentEvent))
{
switch (_gameState)
{
case Game::MenuWindow:
{
ShowMenu();
break;
}
case Game::LogoScreen:
{
ShowLogoScreen();
break;
}
case Game::Playing:
{
sf::Event currentEvent;
while (game._mainWindow.pollEvent(currentEvent))
{
game._mainWindow.clear(sf::Color(255,0,0));
game._mainWindow.display();
if(currentEvent.type == sf::Event::Closed)
_gameState = Game::Exiting;
if(currentEvent.type == sf::Event::KeyPressed)
{
if(currentEvent.key.code == sf::Keyboard::Escape) ShowMenu();
}
}
break;
}
}
}
}
void Game::ShowLogoScreen()
{
Game game;
LoadScreen loadScreen;
loadScreen.Show(game._mainWindow);
_gameState = Game::MenuWindow;
}
void Game::ShowMenu()
{
Game game;
MainMenu mainMenu;
MainMenu::MenuOption option = mainMenu.show(game._mainWindow);
switch(option)
{
case MainMenu::Exit:
_gameState = Game::Exiting;
break;
case MainMenu::Play:
_gameState = Game::Playing;
break;
}
}
Game::GameState Game::_gameState = Unlaunched;
LoadScreen.cpp
#include "stdafx.h"
#include "LoadScreen.h"
void LoadScreen::Show(sf::RenderWindow & renderWindow)
{
sf::Texture image;
if (image.loadFromFile("images/LoadingScreen.png") !=true)
{
return;
}
sf::Sprite sprite (image);
renderWindow.draw(sprite);
renderWindow.display();
sf::Event event;
while (true)
{
while (renderWindow.pollEvent(event))
{
if(event.type == sf::Event::EventType::KeyPressed
||event.type == sf::Event::EventType::MouseButtonPressed
|| event.type == sf::Event::EventType::Closed)
{
return;
}
}
}
}
MainMenu.cpp
#include "stdafx.h"
#include "MainMenu.h"
MainMenu::MenuOption MainMenu::show(sf::RenderWindow& window)
{
//Load menu image from file
sf::Texture image;
image.loadFromFile("images/MainMenu.png");
sf::Sprite sprite(image);
//Setup clickable regions
//Play menu item coordinates
MenuItem playButton;
playButton.rect.top= 319;
playButton.rect.height = 626;
playButton.rect.left = 189;
playButton.rect.width = 329;
playButton.action = Play;
//Options menu item coordinates
MenuItem optionButton;
optionButton.rect.left = 356;
optionButton.rect.height = 596;
optionButton.rect.top = 287;
optionButton.rect.width = 483;
optionButton.action = Options;
//Exit menu item coordinates
MenuItem exitButton;
exitButton.rect.left = 554;
exitButton.rect.height = 580;
exitButton.rect.top = 318;
exitButton.rect.width = 687;
exitButton.action = Exit;
_menuItems.push_back(playButton);
_menuItems.push_back(exitButton);
window.draw(sprite);
window.display();
return GetMenuAction(window);
}
MainMenu::MenuOption MainMenu::HandleClick(int x, int y)
{
std::list<MenuItem>::iterator it;
for ( it = _menuItems.begin(); it != _menuItems.end(); it++)
{
sf::Rect<int> menuItemRect = (*it).rect;
if( menuItemRect.height > y
&& menuItemRect.top < y
&& menuItemRect.left < x
&& menuItemRect.width > x)
{
return (*it).action;
}
}
return null;
}
MainMenu::MenuOption MainMenu::GetMenuAction(sf::RenderWindow& window)
{
sf::Event menuEvent;
while(true)
{
while(window.pollEvent(menuEvent))
{
if(menuEvent.type == sf::Event::MouseButtonPressed)
{
return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y);
}
if(menuEvent.type == sf::Event::Closed)
{
return Exit;
}
}
}
}
void Game::ShowLogoScreen()
{
Game game; // <- this creates a NEW game. You want to use your already created game.
LoadScreen loadScreen;
loadScreen.Show(game._mainWindow);
_gameState = Game::MenuWindow;
}
You create a new game local to the logo screen. That one probably does not even own a window. You should reference your existing game variable.

Move image on screen

I have an image which I want to be moveable. My problem is that the image isn't really moving, it's just dublicated and a new image loads on the new place while the old position still contain the image.
void draw_surface(int srcX, int srcY, int dstX, int dstY, int width, int height, SDL_Surface *source, SDL_Surface *destination)
{
SDL_Rect src;
src.x = srcX;
src.y = srcY;
src.w = width;
src.h = height;
SDL_Rect dst;
dst.x = dstX;
dst.y = dstY;
dst.w = width;
dst.h = height;
SDL_BlitSurface(source, &src, destination, &dst);
}
in the main function:
while (gameRunning)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_DOWN)
{
dstY += 10; //new position
}
}
//apply
apply_surface(0, 10, background, screen);
draw_surface(srcX, srcY, dstX, dstY, width, heigth, background, screen);
}
//update screen
SDL_Flip(screen);
}
What's wrong with this code?
You should use a while loop to poll for events
Moving the drawing outside of the event loop block is a good idea
You need to clear your screen before drawing to it or else the old back buffer data will still be on it
Uint32 black = SDL_MapRGB(screen->format, 0, 0, 0);
while (gameRunning) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
gameRunning = false;
}
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_DOWN) {
dstY += 10; //new position
}
}
}
// Clear screen
SDL_FillRect(screen, NULL, black);
//apply
apply_surface(0, 10, background, screen);
draw_surface(srcX, srcY, dstX, dstY, width, heigth, background, screen);
//update screen
SDL_Flip(screen);
}