Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

C++ SFML" no appropriate default constructor available"

Ostatnio zmodyfikowano 2022-06-09 21:14
Autor Wiadomość
farethh
Temat założony przez niniejszego użytkownika
C++ SFML" no appropriate default constructor available"
» 2022-05-30 21:18:53
Witam Visual Studio wypisuje takie błędy:
1. Severity Code Description Project File Line Suppression State
Error C2512 'Fruit': no appropriate default constructor available SFML D:\Programowanie\C++\VIsual Studio Projekty\SFML\5 Snake\Projekt\Game.cpp 40

2. Severity Code Description Project File Line Suppression State
Error (active) E0291 no default constructor exists for class "Fruit" SFML D:\Programowanie\C++\VIsual Studio Projekty\SFML\5 Snake\Projekt\Game.cpp 40

3.Severity Code Description Project File Line Suppression State
Message  see declaration of 'Fruit' SFML D:\Programowanie\C++\VIsual Studio Projekty\SFML\5 Snake\Projekt\Fruit.h 10


main. cpp

C/C++
#include <iostream>
#include <ctime>

#include "Game.h"

int main()
{
   
srand( static_cast < unsigned >( time( NULL ) ) );
   
   
Game game;
   
   
while( game.running() )
   
{
       
game.update();
       
game.render();
   
}
   
   
return 0;
}

Fruit.h

C/C++
#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>
#include <iostream>

class Fruit
{
private:
   
sf::Texture textureFruit;
   
sf::Sprite snakeFruit;
   
   
void initTexture();
   
   
public:
   
   
Fruit( const sf::RenderWindow & window );
   
virtual ~Fruit();
   
   
const sf::Sprite getSprite() const;
   
   
void randFruitPosition( const sf::RenderWindow & window );
   
void update();
   
void render( sf::RenderTarget * target );
};

Fruit.cpp

C/C++
#include "Fruit.h"

void Fruit::initTexture()
{
   
if( !textureFruit.loadFromFile( "fruit.png" ) )
   
{
       
std::cout << "Tekstura nie zaladowala sie";
   
}
   
   
this->snakeFruit.setTexture( textureFruit );
}

void Fruit::randFruitPosition( const sf::RenderWindow & window )
{
   
int x = window.getSize().x - this->snakeFruit.getGlobalBounds().width;
   
int y = window.getSize().y - this->snakeFruit.getGlobalBounds().height;
   
   
this->snakeFruit.setPosition( sf::Vector2f(
   
static_cast < float >( rand() % x ),
   
static_cast < float >( rand() % y )
    )
    )
;
}

Fruit::Fruit( const sf::RenderWindow & window )
{
   
this->initTexture();
   
this->randFruitPosition( window );
}

Fruit::~Fruit()
{
}

const sf::Sprite Fruit::getSprite() const
{
   
return this->snakeFruit;
}

void Fruit::update()
{
}

void Fruit::render( sf::RenderTarget * target )
{
   
target->draw( this->snakeFruit );
}

Snake.h

C/C++
#pragma once

#include <iostream>
#include <ctime>
#include <vector>
#include <sstream>

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>

class Snake
{
private:
   
sf::Texture textureHead;
   
sf::Sprite snakeHead;
   
   
sf::Texture textureTail;
   
sf::Sprite snakeTail;
   
   
float movementSpeed;
   
int taiLenght;
   
   
enum class direction { left, right, up, down };
   
direction dir = direction::right;
   
   
void initVariables();
   
void initTexture();
   
public:
   
Snake( float x = 400.f, float y = 300.f );
   
virtual ~Snake();
   
   
const sf::Sprite getSprite() const;
   
   
void updateInput();
   
void updateWindowBoundsCollision( const sf::RenderTarget * target );
   
void update( const sf::RenderTarget * target );
   
void render( sf::RenderTarget * target );
};

Snake.cpp

C/C++
#include "Snake.h"

void Snake::initVariables()
{
   
this->movementSpeed = 5.f;
   
this->snakeHead.setOrigin( snakeHead.getLocalBounds().width / 2, snakeHead.getLocalBounds().height / 2 );
   
this->taiLenght = 0.f;
}

void Snake::initTexture()
{
   
if( !textureHead.loadFromFile( "head.png" ) || !textureTail.loadFromFile( "tail.png" ) )
       
 std::cout << "Tekstura nie zaladowala sie";
   
   
this->snakeHead.setTexture( textureHead );
   
this->snakeTail.setTexture( textureTail );
}

Snake::Snake( float x, float y )
{
   
this->snakeHead.setPosition( x, y );
   
this->initTexture();
   
this->initVariables();
}

Snake::~Snake()
{
   
}

const sf::Sprite Snake::getSprite() const
{
   
return this->snakeHead;
}

void Snake::updateInput()
{
   
if( sf::Keyboard::isKeyPressed( sf::Keyboard::A ) && this->dir != direction::right )
   
{
       
if( dir == direction::up )
           
 this->snakeHead.rotate( - 90.f );
       
else if( dir == direction::down )
           
 this->snakeHead.rotate( 90.f );
       
       
this->dir = direction::left;
   
}
   
   
if( sf::Keyboard::isKeyPressed( sf::Keyboard::D ) && this->dir != direction::left )
   
{
       
if( dir == direction::up )
           
 this->snakeHead.rotate( 90.f );
       
else if( dir == direction::down )
           
 this->snakeHead.rotate( - 90.f );
       
       
this->dir = direction::right;
   
}
   
   
if( sf::Keyboard::isKeyPressed( sf::Keyboard::W ) && this->dir != direction::down )
   
{
       
if( dir == direction::right )
           
 this->snakeHead.rotate( - 90.f );
       
else if( dir == direction::left )
           
 this->snakeHead.rotate( 90.f );
       
       
this->dir = direction::up;
   
}
   
   
if( sf::Keyboard::isKeyPressed( sf::Keyboard::S ) && this->dir != direction::up )
   
{
       
if( dir == direction::right )
           
 this->snakeHead.rotate( 90.f );
       
else if( dir == direction::left )
           
 this->snakeHead.rotate( - 90.f );
       
       
this->dir = direction::down;
   
}
   
   
switch( dir )
   
{
   
case direction::left:
       
this->snakeHead.move( - this->movementSpeed, 0.f );
       
break;
   
case direction::right:
       
this->snakeHead.move( this->movementSpeed, 0.f );
       
break;
   
case direction::up:
       
this->snakeHead.move( - 0.f, - this->movementSpeed );
       
break;
   
case direction::down:
       
this->snakeHead.move( - 0.f, this->movementSpeed );
       
break;
   
}
}

void Snake::updateWindowBoundsCollision( const sf::RenderTarget * target )
{
   
//left
   
if( this->snakeHead.getGlobalBounds().left <= 0.f )
   
{
       
this->snakeHead.setPosition( target->getSize().x - this->snakeHead.getGlobalBounds().width, this->snakeHead.getGlobalBounds().top );
       
this->snakeHead.move( 0.f, 16.f );
   
}
   
//right
   
if( this->snakeHead.getGlobalBounds().left + this->snakeHead.getGlobalBounds().width >= 800 )
   
{
       
this->snakeHead.setPosition( 17.f, this->snakeHead.getGlobalBounds().top );
       
this->snakeHead.move( 0.f, 16.f );
   
}
   
   
//top
   
if( this->snakeHead.getGlobalBounds().top <= 0.f )
   
{
       
this->snakeHead.setPosition( this->snakeHead.getGlobalBounds().left, target->getSize().y - this->snakeHead.getGlobalBounds().height );
       
this->snakeHead.move( 16.f, 0.f );
   
}
   
   
//bottom
   
if( this->snakeHead.getGlobalBounds().top + this->snakeHead.getGlobalBounds().height >= target->getSize().y )
   
{
       
this->snakeHead.setPosition( this->snakeHead.getGlobalBounds().left, 17.f );
       
this->snakeHead.move( 16.f, 0.f );
   
}
}

void Snake::update( const sf::RenderTarget * target )
{
   
this->updateInput();
   
this->updateWindowBoundsCollision( target );
}

void Snake::render( sf::RenderTarget * target )
{
   
target->draw( this->snakeHead );
}

Game.h

C/C++
#pragma once

#include "Snake.h"
#include "Fruit.h"

class Game
{
private:
   
sf::VideoMode videoMode;
   
sf::RenderWindow * window;
   
sf::Event sfmlEvent;
   
bool endGame;
   
   
Snake snake;
   
Fruit fruit;
   
   
int points = 0;
   
   
sf::Font font;
   
sf::Text guiText;
   
sf::Text endGameText;
   
   
void initWindow();
   
void initVariables();
   
void initFonts();
   
void initText();
   
public:
   
Game();
   
~Game();
   
   
const bool & getEndGame() const;
   
const bool running() const;
   
void pollEvents();
   
   
void spawnFruit( const sf::RenderWindow & window );
   
   
void updatePlayer();
   
void updateCollison();
   
void updateGui();
   
void update();
   
   
void renderGui( sf::RenderTarget * target );
   
void render();
};

Game.cpp

C/C++
#include "Game.h"

void Game::initWindow()
{
   
this->videoMode = sf::VideoMode( 800, 600 );
   
this->window = new sf::RenderWindow( this->videoMode, "GAME 2", sf::Style::Close | sf::Style::Titlebar );
   
this->window->setFramerateLimit( 60 );
   
   
this->points = 0;
}

void Game::initVariables()
{
   
this->endGame = false;
}

void Game::initFonts()
{
   
if( !this->font.loadFromFile( "Minecraft.ttf" ) )
   
{
       
std::cout << "Nie udalo wczytac sie czcionki";
   
}
}

void Game::initText()
{
   
this->guiText.setFont( this->font );
   
this->guiText.setFillColor( sf::Color::White );
   
this->guiText.setCharacterSize( 26 );
   
   
this->endGameText.setFont( this->font );
   
this->endGameText.setFillColor( sf::Color::Red );
   
this->endGameText.setCharacterSize( 60 );
   
this->endGameText.setPosition( sf::Vector2f( 165, 250 ) );
   
this->endGameText.setString( "YOU ARE DEAD" );
   
// this->guiText.setString("Test 4");
}

Game::Game()
{
   
this->initWindow();
   
this->initVariables();
   
this->initFonts();
   
this->initText();
}

Game::~Game()
{
   
delete this->window;
}

const bool & Game::getEndGame() const
{
   
return this->endGame;
}

const bool Game::running() const
{
   
return this->window->isOpen() /* && !this->endGame*/;
}

void Game::pollEvents()
{
   
while( this->window->pollEvent( this->sfmlEvent ) )
   
{
       
switch( this->sfmlEvent.type )
       
{
       
case sf::Event::Closed:
           
this->window->close();
           
break;
       
case sf::Event::KeyPressed:
           
if( this->sfmlEvent.key.code == sf::Keyboard::Escape )
               
 this->window->close();
           
           
break;
       
}
    }
}

void Game::spawnFruit( const sf::RenderWindow & window )
{
   
this->fruit.randFruitPosition( window );
}

void Game::updatePlayer()
{
   
this->snake.update( this->window );
}

void Game::updateCollison()
{
   
if( this->snake.getSprite().getGlobalBounds().intersects( this->fruit.getSprite().getGlobalBounds() ) )
   
{
       
this->points++;
       
this->fruit.randFruitPosition( * this->window );
   
}
}

void Game::updateGui()
{
   
std::stringstream ss;
   
   
ss << "Points " << this->points << "\n";
   
   
// tutaj będzie wczytanie z pliku i rekord punktów zapisany
   
   
this->guiText.setString( ss.str() );
}

void Game::update()
{
   
this->pollEvents();
   
   
if( this->endGame == false )
   
{
       
this->spawnFruit( * this->window );
       
this->updatePlayer();
       
this->updateCollison();
       
this->updateGui();
   
}
}

void Game::renderGui( sf::RenderTarget * target )
{
   
target->draw( this->guiText );
}

void Game::render()
{
   
this->window->clear();
   
this->snake.render( this->window );
   
this->fruit.render( this->window );
   
   
this->renderGui( this->window );
   
   
if( this->endGame )
   
{
       
this->window->clear( sf::Color::Black );
       
this->window->draw( this->endGameText );
   
}
   
   
this->window->display();
}
P-179470
pekfos
» 2022-05-30 22:36:49
Fruit nie ma domyślnego konstruktora. Musisz wywołać konstruktor Fruit w konstruktorze Game.

Niepotrzebnie piszesz wszędzie this->.
P-179471
farethh
Temat założony przez niniejszego użytkownika
» 2022-06-05 23:54:58
A jak przykładowo mógłbym go zrobić?
P-179518
DejaVu
» 2022-06-06 09:34:19
P-179521
farethh
Temat założony przez niniejszego użytkownika
» 2022-06-09 16:13:09
Przeczytałem cały artykuł i nadal nie ograniam co mam zrobić
P-179530
pekfos
» 2022-06-09 18:24:44
Chodzi o ten zapis gdzie w konstruktorze po dwukropku inicjalizujesz pola w klasie. Gdy typ pola klasy ma konstruktory z parametrami, to jest jedyny sposób na wywołanie konstruktora innego niż domyślny. W tym wypadku:
C/C++
Game::Game()
    :
videoMode( 800, 600 )
   
, window( new sf::RenderWindow( this->videoMode, "GAME 2", sf::Style::Close | sf::Style::Titlebar ) )
   
, fruit( * window )
{
   
this->initWindow(); // wtedy już w initWindow nie tworzysz okna drugi raz
   
this->initVariables();
   
this->initFonts();
   
this->initText();
}
Pola klasy są tworzone w kolejności w jakiej są zdefiniowane z definicji klasy. W tym wypadku kolejność masz poprawną. Okno trzeba też utworzyć w tym miejscu, by istniało w momencie tworzenia fruit. W przeciwnym razie window byłoby jeszcze niezainicjalizowanym wskaźnikiem.

Na dobrą sprawę randFruitPosition() mogłeś nie wywoływać w konstruktorze, wtedy nie byłoby problemu z przekazywaniem tam obiektu okna.
P-179532
farethh
Temat założony przez niniejszego użytkownika
» 2022-06-09 18:58:39
Dobra, wielkie dzięki za pomoc.
Errory z konstrukotrem zniknęły, ale niestety pojawiły się inne:

Game.h  15 linia:

Severity Code Description Project File Line Suppression State
Error C3646 'fruit': unknown override specifier SFML D:\Programowanie\C++\VIsual Studio Projekty\SFML\5 Snake\Projekt\Game.h 15

Severity Code Description Project File Line Suppression State
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int SFML D:\Programowanie\C++\VIsual Studio Projekty\SFML\5 Snake\Projekt\Game.h 15

wiecie jak to naprawic?
P-179533
pekfos
» 2022-06-09 20:12:52
Jak wygląda kod we wskazanym miejscu?
P-179534
« 1 » 2
  Strona 1 z 2 Następna strona