C++ Probleme mit Konstruktor error C3646

vdrenzo

Cadet 1st Year
Registriert
Mai 2017
Beiträge
13
Hallo zusammen,

ich habe in meinem Spiel, das ich in C++ schreibe (übrigens mein erstes C++ Projekt) eine Player-Klasse mit player.h und player.cpp.

Nun möchte ich ein einer anderen Klasse, dem LanPlayState, im Header (also LanPlayState.h) die Variable

Player PlayerOne erstellen und später in der .cpp
PlayerOne.create(//argumente)...ausführen.

Ich habe für Player sowohl einen Default Constructor als auch einen der mehere Argumente übernimmt.
Die gleichen Argumente die auch zur create-funktion gehören.

Der Sinn im definieren in der Headerdatei liegt darin den Scope klassenweit zu bekommen.

Hier meine Player.h:
Code:
#pragma once
#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\System\Vector2.hpp>
#include <SFML\Graphics\Rect.hpp>
#include <SFML\OpenGL.hpp>
#define _USE_MATH_DEFINES 
#include <math.h>
#include <cmath> 
#include "PowerUp.h"
#include "Timer.h"

class Game;

class Player
{
public:
	Player();
	Player(sf::Color col, sf::Vector2<int> pos, sf::Keyboard::Key K1, sf::Keyboard::Key K2);
	void create(sf::Color col, sf::Vector2<int> pos, sf::Keyboard::Key K1, sf::Keyboard::Key K2);
	void Update(float &elapsedTime);
	void Draw(Game& game);
	void PchangeSpeed(float s);
	void PchangeThickness(int d);
	void changeKeys();
	sf::Vector2f getHead();
	sf::Vector2<float> R;
	sf::VertexArray vertices;
	std::pair<int, double> allPPowerUp;
	bool gameoverB = false;
	bool startphase;
	bool drawBorder;


private:

	void Collision();
	void Timerdesolve();
	std::vector<std::pair<Timer, int>> TimersandType;
	sf::Font font;
	sf::Text playtxt;
	sf::CircleShape circle;
	sf::Keyboard::Key Key1, Key2,KeyTemp;
	sf::RectangleShape rect;
	static sf::Texture arrowtxt;
	sf::Sprite arrow;
	sf::Color Col, oldCol;
	sf::Vector2f Pos, N, LP, RP, holeStart;
	int n = 0;
	int m = 0;
	int eT, holetimer, holedis, traceN, radius,dis;
	int randomN;
	bool hole = false;
	bool Peaten = false;
	float speed, turnspeed, alpha;
};

Die Player.cpp:

Code:
#pragma once
#include "Player.h"
#include "Game.h"
#include "eV.h"

std::vector< unsigned char > pixels(1 * 1 * 3);
std::vector< unsigned char > pixelsSide1(1 * 1 * 3);
std::vector< unsigned char > pixelsSide2(1 * 1 * 3);
sf::Texture Player::arrowtxt;


Player::Player()
{}

Player::Player(sf::Color col, sf::Vector2<int> pos, sf::Keyboard::Key K1, sf::Keyboard::Key K2)
{
	circle.setRadius(4);
	circle.setOrigin(circle.getRadius(), circle.getRadius());
	circle.setPosition(pos.x,pos.y);
	circle.setFillColor(col);

	Pos.x=pos.x;
	Pos.y = pos.y;
	
	arrowtxt.loadFromFile("arrow.png");
	arrow.setTexture(arrowtxt);
	arrow.setOrigin(0, 10);
	arrow.setPosition(circle.getPosition());
	arrow.setColor(col);

	vertices.setPrimitiveType(sf::TriangleStrip);
	vertices.append(sf::Vertex(circle.getPosition(), col));
	
	Col = col;
	
	Key1 = K1;
	Key2 = K2;

	speed = 0.115;
	turnspeed = 0.004;
	alpha = 0;
	R = { 1.0f,0.0f };
	holetimer = 0;
	traceN = 0;
	randomN = 1000000;
	allPPowerUp.first = -1; 
	allPPowerUp.second = 1;
	drawBorder = true;

}

void Player::create(sf::Color col, sf::Vector2<int> pos, sf::Keyboard::Key K1, sf::Keyboard::Key K2)
{
	//Player(col, pos, K1, K2);
	circle.setRadius(4);
	circle.setOrigin(circle.getRadius(), circle.getRadius());
	circle.setPosition(pos.x, pos.y);
	circle.setFillColor(col);

	Pos.x = pos.x;
	Pos.y = pos.y;

	arrowtxt.loadFromFile("arrow.png");
	arrow.setTexture(arrowtxt);
	arrow.setOrigin(0, 10);
	arrow.setPosition(circle.getPosition());
	arrow.setColor(col);

	vertices.setPrimitiveType(sf::TriangleStrip);
	vertices.append(sf::Vertex(circle.getPosition(), col));

	Col = col;

	Key1 = K1;
	Key2 = K2;

	speed = 0.115;
	turnspeed = 0.004;
	alpha = 0;
	R = { 1.0f,0.0f };
	holetimer = 0;
	traceN = 0;
	randomN = 1000000;
	allPPowerUp.first = -1;
	allPPowerUp.second = 1;
	drawBorder = true;
}

void Player::changeKeys()
{
	KeyTemp = Key1;
	Key1 = Key2;
	Key2 = KeyTemp;
}

float norm(sf::Vector2f r)
{
	int l= sqrtf(r.x*r.x + r.y*r.y);
	return l;
}

void Player::Update(float &elapsedTime)
{
	eT = elapsedTime;
	
	if (gameoverB == false) {
		if (sf::Keyboard::isKeyPressed(Key1))
		{
			R += sf::Vector2f(-R.y, R.x)*elapsedTime/1000.0f* turnspeed;
			R /= norm(R);
		}
		if (sf::Keyboard::isKeyPressed(Key2))
		{
			R -= sf::Vector2f(-R.y, R.x)*elapsedTime / 1000.0f* turnspeed;
			R /= norm(R);
		}

		if (startphase == false) {
			
			Collision();
			Pos += R*elapsedTime / 1000.0f*speed;
			circle.setPosition(Pos);
		}
		
		if(startphase==true)
		{
			alpha = std::atan(R.y / R.x) * 180 / M_PI;
			if (R.x < 0) { alpha += 180; }
			arrow.setRotation(alpha);
		}

	}
}

void Player::PchangeSpeed(float s)
{
	speed = speed*s;
}

void Player::PchangeThickness(int d)
{
	circle.setRadius(circle.getRadius() +d);
	circle.setOrigin(circle.getRadius(), circle.getRadius());
	radius = circle.getRadius();
}

void Player::Timerdesolve() //Liste der PowerUp-Timer abarbeiten und PowerUps rueckgaengig machen
{
	if (TimersandType.size() > 0)
	{
		for (int i = 0; i < TimersandType.size(); i++)
		{
			if (TimersandType[i].first.TimerCheck() == true)
			{
				switch (TimersandType[i].second)
				{
				case 0://sich selber langsam rückgängig
					PchangeSpeed(1 / 0.7);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 1://andere langsam rückgängig
					allPPowerUp.first = 1; 
					allPPowerUp.second = 1 / 0.7;
					PchangeSpeed(0.7);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 2://sich selber schnell rückgängig
					PchangeSpeed(1 / 1.7);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 3://andere schnell rückgängig
					allPPowerUp.first = 3; 
					allPPowerUp.second = 1 / 1.7;
					PchangeSpeed(1.7);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 4://sich selber duenn rückgängig
					PchangeThickness(3);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 5: //andere dick rückgängig
					allPPowerUp.first = 5; 
					allPPowerUp.second = -3;
					PchangeThickness(3);
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 6://andere Controls verdrehen rückgängig
					allPPowerUp.first = 6;
					allPPowerUp.second = 1;
					changeKeys();
					TimersandType.erase(TimersandType.begin() + i);
					break;
				case 7://Spuren löschen	rückgängig
					break;
				case 8://Rand öffnen/schließen rückgängig
					break;
				}
			}
		}
	}
}

sf::Vector2f Player::getHead()
{
	return sf::Vector2f(circle.getPosition());
}

void Player::Collision()
{	//Collisions-Erkennung in jedem Frame

	LP =  sf::Vector2f(1.732*R.x-0.5*R.y , 0.5*R.x+1.732*R.y); //30° nach links
	RP = sf::Vector2f(1.732*R.x + 0.5*R.y , 1.732*R.y-0.5*R.x); //30°nach rechts

	glReadBuffer(GL_FRONT); //pixel auslesen
	glReadPixels(Pos.x + (R.x* (1.0 * radius+1)), height - Pos.y - (R.y*(1.0*radius+1)), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]); //Pixel Pos vorm kopf
	glReadPixels(Pos.x + (LP.x* (1.0 * radius+1)), height - Pos.y - (LP.y*(1.0*radius+1)), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixelsSide1[0]);//Pixel seitlich 30°
	glReadPixels(Pos.x + (RP.x* (1.0 * radius+1)), height - Pos.y - (RP.y*(1.0*radius+1)), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixelsSide2[0]);//pixel andere Seite -30°
	//std::cout << std::to_string(pixels[0]) << " " << std::to_string(pixels[1]) << " " << std::to_string(pixels[2]) << std::endl;

	if (pixels[0] == 0 && pixels[1] == 0 && pixels[2] == 0 && pixelsSide1[0] == 0 && pixelsSide1[1] == 0 && pixelsSide1[2] == 0 && pixelsSide2[0] == 0 && pixelsSide2[1] == 0 && pixelsSide2[2] == 0)
	{//wenn schwarz passiert nichts
	}
	else if (powerups.size() > 0)
	{//sonst Überprüfung ob Powerup gegessen
		for (int i = 0; i < powerups.size(); i++)
		{ // wenn ja wende powerup an
			int m = powerups[i].Eaten(Pos,radius);
			if (m == 0)//sich selber langsam
			{
				PchangeSpeed(0.7);
				Timer T(7000000);
				std::pair<Timer, int> Pair(T, 0);
				TimersandType.push_back(Pair);//Timer mit Wirkungsdauer und Typ in die Liste stecken
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 1)//andere langsam
			{
				allPPowerUp.first = 1;
				allPPowerUp.second = 0.7;
				PchangeSpeed(1 / 0.7);
				Timer T(7000000);
				std::pair<Timer, int> Pair(T, 1);
				TimersandType.push_back(Pair);
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 2) //sich selber schnell
			{
				PchangeSpeed(1.7);
				Timer T(4000000);
				std::pair<Timer, int> Pair(T, 2);
				TimersandType.push_back(Pair);
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 3) //andere schnell
			{
				allPPowerUp.first = 3;
				allPPowerUp.second = 1.7;
				PchangeSpeed(1 / 1.7);
				Timer T(4000000);
				std::pair<Timer, int> Pair(T, 3);
				TimersandType.push_back(Pair);
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 4) //sich selber duenn
			{
				if (radius > 3) {
					PchangeThickness(-3);
					Timer T(7000000);
					std::pair<Timer, int> Pair(T, 4);
					TimersandType.push_back(Pair);
				}
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 5) //andere dick
			{
				allPPowerUp.first = 5;
				allPPowerUp.second = 3;
				PchangeThickness(-3);
				Timer T(7000000);
				std::pair<Timer, int> Pair(T, 5);
				TimersandType.push_back(Pair);
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 6) //andere Controls verdrehen
			{
				allPPowerUp.first = 6;
				allPPowerUp.second = 1;
				changeKeys();
				Timer T(7000000);
				std::pair<Timer, int> Pair(T, 6);
				TimersandType.push_back(Pair);
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 7) //Alle Spuren löschen
			{
				allPPowerUp.first = 7;
				allPPowerUp.second = 1;
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
			else if (m == 8) //Rand öffnen/schließen
			{
				allPPowerUp.first = 8;
				allPPowerUp.second = 1;
				powerups.erase(powerups.begin() + i);
				Peaten = true;
				break;
			}
		}
		if (Peaten == false)
		{
			if (startphase == false) 
			{
				//std::cout << "gameover" << std::endl;
				R = { 0,0 };
				gameoverB = true;
			}
		}
		if (Peaten == true)
		{
			Peaten = false;
		}
	}
	else
	{
		if (startphase == false) 
		{
			//std::cout << "gameover" << std::endl;
			R = { 0,0 };				
			gameoverB = true;
		}
	}	
}

void Player::Draw(Game& game)
{
	radius = circle.getRadius();
	holetimer += eT;

	traceN += eT;
	if (traceN > 40000)//Spur zeichnen in 0,04s Schritten
	{
		traceN = 0;

		//Loch erzeugung nach random zeit
		if (holetimer>randomN)
		{
			hole = true;
			holeStart = Pos;
			oldCol = Col;
			Col = sf::Color::Transparent;
			holedis = (rand() % 30) + 15;
			vertices.append(sf::Vertex(Pos + N*float(radius), Col));
			vertices.append(sf::Vertex(Pos + -N*float(radius), Col));
		}

		if (hole == true) //Loch zeichnung
		{
			holetimer = 0;
			dis = sqrt((Pos.x - holeStart.x)*(Pos.x - holeStart.x) + (Pos.y - holeStart.y)*(Pos.y - holeStart.y));
			if (dis>holedis)
			{
				vertices.append(sf::Vertex(Pos + N*float(radius), Col));
				vertices.append(sf::Vertex(Pos + -N*float(radius), Col));
				Col = oldCol;
				hole = false;
				dis = 0;
				randomN = (rand() % 4) * 1000000 + 500000;
			}
		}

		N = sf::Vector2f(-R.y, R.x);
		vertices.append(sf::Vertex(Pos + N*float(radius), Col));
		vertices.append(sf::Vertex(Pos + -N*float(radius), Col));
	}

	//Randbedingungen prüfen in jedem Frame;
	if (drawBorder == false) {
		if (Pos.x + 2 * radius > width - 205)
		{

			vertices.append(sf::Vertex(sf::Vector2f(width - 200, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(width - 200, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(0, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(0, Pos.y), sf::Color::Transparent));
			Pos.x = 0 + 2 * radius;
		}
		if (Pos.x - 2 * radius < 0)
		{
			vertices.append(sf::Vertex(sf::Vector2f(0, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(0, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(width - 200, Pos.y), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(width - 200, Pos.y), sf::Color::Transparent));
			Pos.x = width - 205 - 2 * radius;
		}
		if (Pos.y + 2 * radius > height)
		{
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, height), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x + 1, height), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, 0), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x + 1, 0), sf::Color::Transparent));
			Pos.y = 2 * radius;
		}
		if (Pos.y - 2 * radius < 0)
		{
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, 0), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, 0), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, height), sf::Color::Transparent));
			vertices.append(sf::Vertex(sf::Vector2f(Pos.x, height), sf::Color::Transparent));
			Pos.y = height - 2 * radius;
		}
	}

	Timerdesolve();
	game.window.draw(vertices);
	game.window.draw(circle);
	if (startphase == true)
	{
		game.window.draw(arrow); 
	}
}

Die LanPlayState.h:
Code:
#pragma once
#ifndef LANPLAYSTATE_HPP
#define LANPLAYSTATE_HPP

#include <SFML/Graphics.hpp>
#include "Game.h"
#include "Gamestate.h"
#include <SFML\Network.hpp>

class LanPlayState : public Gamestate
{
public:
	LanPlayState();
	~LanPlayState();
	void HandleEvents(Game& game);
	void Update(Game& game);
	void Draw(Game& game);
	
private:
	void NSetup();
	void InBox(sf::Packet packet);
	void gamestart();

	sf::Texture turtlegreen, turtlered, blitzgreen, blitzred, duengreen, dickred, controlswitch, radierer, dBorder;
	sf::RectangleShape rectsplit, border;
	sf::Font font;
	sf::Text scoretxt;
	std::vector<sf::Color> C;
	bool drawBorder = true;

	Player PlayerOne;

	sf::TcpSocket socket;
	sf::SocketSelector selector;
	sf::Time t1;
};

#endif

und die LanPlayState.cpp: Hier Zeile(146)!
Code:
#pragma once
#include "LanPlayState.h"
#include "eV.h"

LanPlayState::LanPlayState()
{
	turtlegreen.loadFromFile("0.png"); //sich selber langsam
	turtlered.loadFromFile("1.png");//andere langsam
	blitzgreen.loadFromFile("2.png");//sich selber schnell
	blitzred.loadFromFile("3.png");//andere schnell
	duengreen.loadFromFile("4.png"); //sich selber duenn
	dickred.loadFromFile("5.png");//andere dick
	controlswitch.loadFromFile("6.png");//andere Controls verdrehen
	radierer.loadFromFile("7.png");//Spuren löschen
	dBorder.loadFromFile("8.png");//Rand öffnen

	rectsplit.setSize(sf::Vector2f(5, height));
	rectsplit.setPosition(sf::Vector2f(width - 200, 0));
	rectsplit.setFillColor(sf::Color(180, 180, 180));

	font.loadFromFile("Jokerman.TTF");
	scoretxt.setFont(font);
	scoretxt.setPosition(width - 150, 50);
	scoretxt.setCharacterSize(30);
	scoretxt.setString("Score:");
	scoretxt.setFillColor(sf::Color(220, 220, 220));

	border.setFillColor(sf::Color::Transparent);
	border.setSize(sf::Vector2f(width - 200, height));
	border.setOutlineThickness(-5);
	border.setOutlineColor(sf::Color(250, 150, 100));

	C.resize(4);
	C[0] = sf::Color::Blue;
	C[1] = sf::Color::Red;
	C[2] = sf::Color::Green;
	C[3] = sf::Color::Yellow;

	t1 = sf::milliseconds(10);
	NSetup();

	/*sf::Vector2<int> x((rand() % (width - 280)) + 20, (rand() % (height - 40)) + 20);
	Player nP(C[playernumber], x, K[i], K[i + 4]);
	nP.startphase = true;*/
}

void LanPlayState::HandleEvents(Game& game)
{
	sf::Event event;

	while (game.window.pollEvent(event))
	{
		switch (event.type)
		{
		case sf::Event::Closed:
			game.window.close();
			game.running = false;
			break;

		case sf::Event::KeyPressed:

			if (event.key.code == sf::Keyboard::Escape)
			{

			}
			
			if (event.key.code == sf::Keyboard::Return)
			{
				
			}
			break;
		}
	}
}

void LanPlayState::Update(Game& game)
{
	if (selector.wait(t1)) //check for data
	{
		if (selector.isReady(socket))//test socket for recv data
		{
			sf::Packet packet;
			if (socket.receive(packet) != sf::Socket::Done)
			{
				std::cout << "recieve FAIL" << std::endl;
			}
			else
			{
				InBox(packet);
			}
		}
	}
}

void LanPlayState::Draw(Game& game)
{
	game.window.draw(rectsplit);
	game.window.draw(scoretxt);

	if (drawBorder == true)
	{
		game.window.draw(border);
		PlayerOne.Draw(game);
	}

}

void LanPlayState::NSetup()
{
	sf::Socket::Status status = socket.connect("127.0.0.1", 54345);
	if (status != sf::Socket::Done)
	{
		std::cout << "socket connect error" << std::endl;
	}
	else
	{
		selector.add(socket);
	}
}

void LanPlayState::InBox(sf::Packet packet)
{
	int x = 0;
	int y = 0;
	packet >> x >> y;

	if (x == 111)
	{
		gamestart();
	}
	std::cout << x << "         " << y << std::endl;
}

void LanPlayState::gamestart()
{
	int n;
	for (int i = 0; i < connectionInfo.size(); i++)
	{
		if (connectionInfo[i][0] == 1)
		{
			n = connectionInfo[i][1];
		}
	}
		
	sf::Vector2<int> x((rand() % (width - 280)) + 20, (rand() % (height - 40)) + 20);
	PlayerOne.create(C[n], x, sf::Keyboard::Right, sf::Keyboard::Left);
	PlayerOne.startphase = true;
	
}

LanPlayState::~LanPlayState()
{
	std::cout << "LanPlayState wurde zerstört" << std::endl;
}

Der Fehler lautet:
1>c:\users\vinc\documents\visual studio 2017\projects\curvefever4\curvefever4\lanplaystate.h(31): error C3646: "PlayerOne": Unbekannter Überschreibungsspezifizierer
1>c:\users\vinc\documents\visual studio 2017\projects\curvefever4\curvefever4\lanplaystate.h(31): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.

Ich denke meine eigentliche Frage ist:

Wie kann ich ein eigenes Objekt in der Header-Datei definieren, und erst später konstruieren. Ich habe das so verstanden:
Um das Objekt in der Headerdatei zu definieren braucht man trotzdem einen default-constructor.
Und das was der eigentliche Konstructor erledigen würde, kann man dann in eine Funktion verschieben wie "init()" oder bei mir eben "create()".
Ergänzung ()

Ok also obwohl Visual nicht gemeckert hat beim erstellen eines Player objekts in LanPlayState, hat das zusaätliche includieren der player.h den fehler beseitigt!
 
Zuletzt bearbeitet:
Der Fehler passiert ja in der lanplaystate.h und ich glaube (mein C++ ist eigentlich schon ziemlich eingerostet) dass du nur vergessen hast die Player.h in der lanplaystate.h zu inkludieren damit er dort die Klasse kennt.
 
Ja genau das wars. Vielen Dank fürs drüber schauen..das Forum hier ist toll!
 
Zurück
Oben