• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z klasami, sfml cpp

Object Storage Arubacloud
0 głosów
300 wizyt
pytanie zadane 12 stycznia 2020 w C i C++ przez Dawid_1900 Nowicjusz (210 p.)
edycja 12 stycznia 2020 przez Dawid_1900

Witam, 

Jestem początkującym, dlatego proszę o wyrozumiałość smiley

Piszę pacmana w sfml cpp i napotkałem pewien problem, mianowicie

class pos // klasa pomocnicza
{
public:
	int x;
	int y;
	const int Scale_times = 18;
	const int Scale_plus  = 8;
	pos() = default;
	pos(int px, int py);
	friend ostream& operator<<(ostream& fout, const pos& print);
};

class Plansza
{
protected: 
	int mMap[28][31] = { 0 };
	pos Duszki_pos[4];
	pos Pacman_pos;
	vector<pos> punkty;
	int Pkt_total;
public:

	Plansza();

	void wypisz_sie();

	Plansza(string name);

	void wczytaj(string nazwa);

	void uzupelnij_swoje_dane();

	enum TileType
	{
		Pill = 1,
		Wall = 3,
		PacMan = 4,
		Tunnel = 7,
		GhostSpawn = 9
	};

	void makeWallsMap(sf::RenderTarget& target);

	void drawHorizontalLine(sf::RenderTarget& rt, int x1, int x2, int y);

	void drawVerticalLine(sf::RenderTarget& rt, int y1, int y2, int x);

};
class Pacman: public Plansza, public Drawable
{
	int x = 0;
	int y = 0;
	
public:
	Pacman();
	Vector2f getPosition();
private:
	sf::CircleShape ksztalt;
	const float promien{ 10.0f };
	const float kulka_Velocity{ 3.0f };
	sf::Vector2f velocity{ kulka_Velocity, kulka_Velocity }; //wektor predkosci 2d
	virtual void drawPac(sf::RenderTarget& target, sf::RenderStates state) const;
};

Przy takiej strukturze danych, tworze obiekt Pacman gracz(); ale przy wywołaniu gracz.drawPac(…) kompilator pokazuje mi, że wyrażenie musi mieć typ klasy i nie bardzo wiem dlaczego może tak się dziać. Do tego mam pytanie odnośnie klasy Drawable, czy dziedziczenie jest konieczne pomimo tego, że i tak nadpisuje wirtualnie tą funkcję w klasie? Nie nadpisując klasa staje się wirtualna.

Main : 

RenderWindow window{ VideoMode(800,800), "Okienko", Style::Default};
    Plansza Map("Level1.txt");
    Map.wypisz_sie();
    Pacman g();
     
    while (window.isOpen())
    {
        Event evnt;
        while (window.pollEvent(evnt))
        {
            if (evnt.type == evnt.Closed)
                window.close();
        }
 
        g.drawPac(); // tutaj jest blad
 
        Map.makeWallsMap(window);
        window.display();
    }
 
    return 0;
}

Konstruktor klasy :

Pacman::Pacman()
{
    cout << "Konstruktor klasy!" << endl;
    int x = Pacman_pos.x * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
    int y = Pacman_pos.y * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
    ksztalt.setPosition(x, y);
    ksztalt.setRadius(this->promien);
    ksztalt.setFillColor(sf::Color::White);
    ksztalt.setOrigin(this->promien, this->promien);
 
}

 

komentarz 12 stycznia 2020 przez tkz Nałogowiec (42,000 p.)
Pokaż więcej kodu. Jak wywołujesz klasę etc.

1 odpowiedź

0 głosów
odpowiedź 12 stycznia 2020 przez Dawid_1900 Nowicjusz (210 p.)
Main: 

	RenderWindow window{ VideoMode(800,800), "Okienko", Style::Default};
	Plansza Map("Level1.txt");
	Map.wypisz_sie();
	Pacman g();
	
	while (window.isOpen())
	{
		Event evnt;
		while (window.pollEvent(evnt))
		{
			if (evnt.type == evnt.Closed)
				window.close();
		}

		g.drawPac(); // tutaj jest blad

		Map.makeWallsMap(window);
		window.display();
	}

	return 0;
}

Konstruktor klasy:

Pacman::Pacman()
{
	cout << "Konstruktor klasy!" << endl;
	int x = Pacman_pos.x * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
	int y = Pacman_pos.y * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
	ksztalt.setPosition(x, y);
	ksztalt.setRadius(this->promien);
	ksztalt.setFillColor(sf::Color::White);
	ksztalt.setOrigin(this->promien, this->promien);

}

 

komentarz 12 stycznia 2020 przez Dawid_1900 Nowicjusz (210 p.)
Celem jest narysowanie obiektu PacMan w okienku(jak na razie jest po prostu kulka).

Problemem jest to, że po stowrzeniu obiektu, kompilator mówi mi, że nie jest to obiekt klasy, nie mogę odwołać się do żadnej funkcji z tej klasy.
komentarz 12 stycznia 2020 przez tkz Nałogowiec (42,000 p.)
Dlaczego draw jest wirtualne? Masz implementację tych metod?
komentarz 12 stycznia 2020 przez Dawid_1900 Nowicjusz (210 p.)

Jeżeli nie dam funkcji draw jako witrualnej, cala klasa bedzie wirtualna z racji dziedziczenia Drawable (tak przeczytalem w innych pytaniach na tym forum).

Wklejam poniżej cały kod, który do tej pory napisałem (pliki .cpp)

Pacman.cpp:

#include "Pacman.h"

Pacman::Pacman()
{
	cout << "Konstruktor klasy!" << endl;
	int x = Pacman_pos.x * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
	int y = Pacman_pos.y * Pacman_pos.Scale_times + Pacman_pos.Scale_plus;
	ksztalt.setPosition(x, y);
	ksztalt.setRadius(this->promien);
	ksztalt.setFillColor(sf::Color::White);
	ksztalt.setOrigin(this->promien, this->promien);

}



Vector2f Pacman::getPosition()
{
	return ksztalt.getPosition();
}

int Pacman::get_x()
{
	return x;
}


void Pacman::draw(sf::RenderTarget & target, sf::RenderStates state) const
{
	target.draw(this->ksztalt, state);
}

Plansza.cpp: 

#include "Plansza.h"
#include <fstream>
#include <vector>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <sstream>



Plansza::Plansza()
{
}

void Plansza::wypisz_sie()
{
	cout << "////////////////////////////////////" << endl;
	cout << "mMap: " << endl;
	for (int i = 0; i < 28; i++)
	{
		for (int j = 0; j < 31; j++)
			cout << mMap[i][j] << " ";
		cout << endl;
	}
	cout << endl << endl;
	cout << "Pozycje duszkow: " << endl;
	for (int i = 0; i < 4; i++)
		cout << Duszki_pos[i];
	cout << endl;
	cout << "Pozycja Pacmana: " << Pacman_pos << endl;

}

Plansza::Plansza(string name)
{
	wczytaj(name);
	uzupelnij_swoje_dane();
}

void Plansza::wczytaj(std::string nazwa)
{

		ifstream plik;
		plik.open(nazwa);
		if (not plik.good())
		{
			cout << "Bledny plik wejsciowy z plansza!" << endl;
			getchar();
		}
		string linia;
		int y = 0;
		while (getline(plik, linia))
		{
			int x = 0;
			stringstream ss(linia);
			int temp;
			while (ss)
			{
				if (ss >> temp)
				{
					mMap[x][y] = temp;
					x++;
				}
			}
			y++;



		}
		plik.close();

}

void Plansza::uzupelnij_swoje_dane()
{
	int iter = 0;
	for (int i = 0; i < 28; i++)
	{
		for (int j = 0; j < 31; j++)
		{
			if (mMap[i][j] == Pill) punkty.push_back(pos(i, j));
			if (mMap[i][j] == PacMan) { Pacman_pos.x = i; Pacman_pos.y = j; };
			if (mMap[i][j] == GhostSpawn) { Duszki_pos[iter].x = i; Duszki_pos[iter].y = j; iter++; }
		}
	}


}

void Plansza::makeWallsMap(sf::RenderTarget & target)
{
	sf::Vertex arr[4];
	arr[0].color = sf::Color::Blue;
	arr[1].color = sf::Color::Blue;
	arr[2].color = sf::Color::Blue;
	arr[3].color = sf::Color::Blue;
	for (int x = 0; x < 27; ++x)
	{
		if ((mMap[x][0] == Wall) && (mMap[x + 1][0] == Wall)) drawHorizontalLine(target, x, x + 1, 0);
		if ((mMap[x][30] == Wall) && (mMap[x + 1][30] == Wall)) drawHorizontalLine(target, x, x + 1, 30);
	}
	for (int y = 0; y < 30; ++y)
	{
		if ((mMap[0][y] == Wall) && (mMap[0][y + 1] == Wall)) drawVerticalLine(target, y, y + 1, 0);
		if ((mMap[27][y] == Wall) && (mMap[27][y + 1] == Wall)) drawVerticalLine(target, y, y + 1, 27);
	}
	for (int x = 1; x < 27; ++x) for (int y = 1; y < 30; ++y)
	{
		if (mMap[x][y] == Wall)
		{
			if (mMap[x - 1][y] == Wall) drawHorizontalLine(target, x - 1, x, y);
			if (mMap[x + 1][y] == Wall) drawHorizontalLine(target, x + 1, x, y);
			if (mMap[x][y - 1] == Wall) drawVerticalLine(target, y - 1, y, x);
			if (mMap[x][y + 1] == Wall) drawVerticalLine(target, y + 1, y, x);
		}
	}//for x for y
}

void Plansza::drawHorizontalLine(sf::RenderTarget & rt, int x1, int x2, int y)
{
	sf::Vertex arr[4];
	arr[0].color = sf::Color::Blue;
	arr[1].color = sf::Color::Blue;
	arr[2].color = sf::Color::Blue;
	arr[3].color = sf::Color::Blue;
	arr[0].position = sf::Vector2f(16.f*(x1 + 0.5f), 16.f*(y + 0.5f) - 1.5f);
	arr[1].position = sf::Vector2f(16.f*(x1 + 0.5f), 16.f*(y + 0.5f) + 1.5f);
	arr[2].position = sf::Vector2f(16.f*(x2 + 0.5f), 16.f*(y + 0.5f) + 1.5f);
	arr[3].position = sf::Vector2f(16.f*(x2 + 0.5f), 16.f*(y + 0.5f) - 1.5f);
	rt.draw(arr, 4, sf::Quads);
}

void Plansza::drawVerticalLine(sf::RenderTarget & rt, int y1, int y2, int x)
{
	sf::Vertex arr[4];
	arr[0].color = sf::Color::Blue;
	arr[1].color = sf::Color::Blue;
	arr[2].color = sf::Color::Blue;
	arr[3].color = sf::Color::Blue;
	arr[0].position = sf::Vector2f(16.f*(x + 0.5f) - 1.5f, 16.f*(y1 + 0.5f));
	arr[1].position = sf::Vector2f(16.f*(x + 0.5f) + 1.5f, 16.f*(y1 + 0.5f));
	arr[2].position = sf::Vector2f(16.f*(x + 0.5f) + 1.5f, 16.f*(y2 + 0.5f));
	arr[3].position = sf::Vector2f(16.f*(x + 0.5f) - 1.5f, 16.f*(y2 + 0.5f));
	rt.draw(arr, 4, sf::Quads);
}

pos::pos(int px, int py)
	:x (px), y(py)
{
}

ostream & operator<<(ostream & fout, const pos & print)
{
	fout << "Pozycja X: " << print.x << ", Pozycja Y: " << print.y << endl;
	return fout;
}

Source.cpp:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include "Plansza.h"
#include "Pacman.h"
using namespace std;
using namespace sf;

int main()
{
	RenderWindow window{ VideoMode(800,800), "Okienko"};
	//RectangleShape mapa(Vector2f(1200.0f, 1200.0f));
	Plansza Map("Level1.txt");
	Map.wypisz_sie();
	Pacman g();
	g.get_x(); //Wyrazenie musi mieć typ klasy
	
	while (window.isOpen())
	{
		Event evnt;
		while (window.pollEvent(evnt))
		{
			if (evnt.type == evnt.Closed)
				window.close();
		}

		window.draw(g); // zła lista argumentów

		Map.makeWallsMap(window);
		window.display();
	}

	return 0;
}

 

komentarz 12 stycznia 2020 przez tkz Nałogowiec (42,000 p.)

https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Drawable.php

Zobacz, że draw przyjmuje coś innego, niż Ty podajesz. Z tego co widzę na stackoverflow masz źle przeciążoną metodę draw. 

komentarz 12 stycznia 2020 przez Dawid_1900 Nowicjusz (210 p.)
Problem zażegnany, przy deklaracji obiektu niepotrzebnie dałem nawiasy funkcyjne.

Dziekuję za pomoc :D

Podobne pytania

0 głosów
1 odpowiedź 362 wizyt
pytanie zadane 11 września 2018 w C i C++ przez oliwzcak12 Użytkownik (550 p.)
0 głosów
3 odpowiedzi 1,638 wizyt
0 głosów
2 odpowiedzi 135 wizyt
pytanie zadane 1 maja 2019 w C i C++ przez NEFOS Początkujący (320 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...