Klassenvariable funktioniert nicht ? Wertzuweisung wird ignoriert.
-
Ich habe versucht ein kleines Minispiel zu programmieren, (werden viele sicherlich vom Taschenrechner kennen), die Rede ist von FallDown.
http://www.albinoblacksheep.com/flash/falldown2 für diejenigen die nicht wissen was falldown ist.
Nun mein Problem:
Die UpdateMethode der Klass Block hat absolut keine Auswirkung und ich verstehe nicht wieso. Es ist leider eine ganze Menge Text, jedoch denke ich das der Fehler was auch immer es ist entweder in der Klasse Block oder in der Klasse World ist.
/* * World.h * * Created on: 21.07.2009 * Author: Administrator */ #include <string> #include <list> #include "Block.h" #include "Player.h" using namespace std; #ifndef WORLD_H_ #define WORLD_H_ class World{ public: World(); void StartLoop(); ~World(); private: void GenerateNextLine(); void Update(); void Render(); bool HasLost(); Player myplayer; bool IsRunning; list<Block> blocklist; }; #endif /* WORLD_H_ *//* * World.cpp * * Created on: 21.07.2009 * Author: Administrator */ using namespace std; #include "World.h" #include "Player.h" #include <iostream> #include "Block.h" #include "ConsoleColour.h" #include <windows.h> World::World(){ this->IsRunning = false; } void World::GenerateNextLine(){ Block newblock(5,5); this->blocklist.push_back(newblock); } void World::StartLoop(){ this->IsRunning = true; while(this->IsRunning){ this->Update(); Sleep(33); } } void World::Render(){ bool PlayerwasRenderd = false; int liney = 0; int linex = 0; system("cls"); cout << green << "Current Distance " << this->myplayer.GetDistance() << "\n"; list<Block>::iterator p = this->blocklist.begin(); while(p != blocklist.end()) { Block current = *p; while (liney < current.posy){ liney = liney + 1; cout << white << "\n"; } while (linex < current.startx){ linex = linex + 1; cout << white << " "; } int size = current.sizex; while(size > 0){ cout << blue << "-"; linex = linex + 1; size = size -1; } p++; } } bool World::HasLost(){ if(this->myplayer.GetPosY() < 0){ return true; } return false; } void World::Update(){ this->GenerateNextLine(); list<Block>::iterator p = this->blocklist.begin(); while(p != blocklist.end()) { Block current = *p; current.Update(); p++; } this->myplayer.Update(); this->Render(); } World::~World(){ }/* * Block.h * * Created on: 21.07.2009 * Author: Administrator */ #ifndef BLOCK_H_ #define BLOCK_H_ class Block{ public: Block(int size,int startx); ~Block(); void Update(); int startx; int sizex; int posy; }; #endif /* BLOCK_H_ *//* * Block.cpp * * Created on: 21.07.2009 * Author: Administrator */ using namespace std; #include "Block.h" #include <iostream> #include "Block.h" #include "ConsoleColour.h" Block::Block(int size,int startx){ cout << red << "New Block " << startx << "-" << size << "\n"; this->startx = startx; this->sizex = size; this->posy = 15; } void Block::Update(){ posy = posy -1; cout << red << posy << "\n"; } Block::~Block(){ }/* * Player.h * * Created on: 21.07.2009 * Author: Administrator */ #ifndef PLAYER_H_ #define PLAYER_H_ class Player{ public: Player(); ~Player(); void Update(); void PushUp(); int GetPosY(); int GetPosX(); int GetDistance(); private: int distance; int posx; int posy; }; #endif /* PLAYER_H_ *//* * Player.cpp * * Created on: 21.07.2009 * Author: Administrator */ using namespace std; #include <iostream> #include "Player.h" Player::Player(){ cout << "New Player"; this->posx = 10; this->posy = 0; this->distance = 0; } void Player::Update(){ } int Player::GetDistance(){ return this->distance; } int Player::GetPosX(){ return this->posx; } int Player::GetPosY(){ return this->posy; } Player::~Player(){ }/* * main.cpp * * Created on: 21.07.2009 * Author: Administrator */ #include "World.h" int main() { World myworld; myworld.StartLoop(); }// ConsoleColor.h #pragma once #include <iostream> #include <windows.h> inline std::ostream& blue(std::ostream &s) { HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE |FOREGROUND_GREEN|FOREGROUND_INTENSITY); return s; } inline std::ostream& red(std::ostream &s) { HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_INTENSITY); return s; } inline std::ostream& green(std::ostream &s) { HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN|FOREGROUND_INTENSITY); return s; } inline std::ostream& yellow(std::ostream &s) { HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY); return s; } inline std::ostream& white(std::ostream &s) { HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); return s; } struct color { color(WORD attribute):m_color(attribute){}; WORD m_color; }; template <class _Elem, class _Traits> std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& i, color& c) { HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdout,c.m_color); return i; }
-
Deine Fehlerbeschreibung und dein langer Code sind nicht besonders hilfreich. Wird die Methode richtig aufgerufen? Überprüfe das doch mal mit dem Debugger, dann kommst du dem Fehler schnell auf die Spur.
-
Aufgerufen wird die Methode (habe nen cout reingepackt, der den wert angibt)
Das Problem ist das der wert zwar berechnet wird, dann es jedoch ist als würde alles verworfen, weil beim nächsten Update Aufruf ist wieder der alte Wert vorhanden.Gerne würde ich weniger code posten, jedoch habe ich absolut keine Idee wodurch der Fehler kommen kann, ausser der (evtuellen) Eingrenzung auf World und Block.
-
Kann es das sein?
while(p != blocklist.end()) { Block current = *p; current.Update(); p++; }current ist eine Kopie von *p. Du brauchst aber eine Referenz, sonst ändert sich nicht der Wert in der Liste!!!
while(p != blocklist.end()) { Block& current = *p; current.Update(); p++; }oder gleich
while(p != blocklist.end()) { p->Update(); p++; }Hilft das?
-
Ah, ich habe den Fehler gefunden.
list<Block>::iterator p = this->blocklist.begin(); while(p != blocklist.end()) { Block current = *p; // <- current.Update(); p++; }Du erstellst bei der Markierung eine lokale Kopie und updatest diese. Sowieso machst du deine Schleife unnötig kompliziert. Machs doch so:
for (list<Block>::iterator p = blocklist.begin(); p != blocklist.end(); ++p) { p->Update(); }Wenn du die Anweisungen trennen willst, brauchst du Referenzen, um nicht neue Objekte zu erstellen. Ausserdem brauchst du nicht ständig
this->anzugeben. Und schreibe besser++pstattp++, das ist nämlich schneller, weil der Iterator direkt erhöht wird, während beip++noch eine Kopie erstellt werden muss.
-
Du veränderst ja auch immer nur eine lokale Kopie.
Nix gut:
while(p != blocklist.end()) { Block current = *p; current.Update(); p++; }Viel gut:
while(p != blocklist.end()) { Block& current = *p; current.Update(); p++; }
-
Ich war auch schon zu langsam...

-
Danke an euch alle 3, das wars jetzt gehts

Darauf wäre ich aber von selber nie gekommen. (Könnte damit zusammenhängen, das ich bislang in Java programmiert habe)
-
Empire Phoenix schrieb:
(Könnte damit zusammenhängen, das ich bislang in Java programmiert habe)
Das ist sogar sehr wahrscheinlich. Du solltest wissen, dass man in C++ eher mit direkten Objekten arbeitet.
std::string a; // erstellt einen gültigen leeren String (eigenständiges Objekt). std::string& r = a; // C++-Referenz auf einen String (nicht Referenz wie in Java!). std::string* p = &a; // Zeiger auf einen String (flexibler als Referenz) void Function(std::string Text); // kopiert den std::string (kann teuer sein) void Function(const std::string& Text); // übergibt eine Const-Referenz und spart die Kopie.Du solltest in deinem C++-Buch das Kapitel über Zeiger und Referenzen am besten genau durcharbeiten, damit du das nötige Verständnis erlangst.