Problem mit Templates



  • Ich habe eine verkettete Liste aus Templates entworfen und stoße nun auf ein Problem.

    Erst mal der Quelltext:

    cTemplateList.h:

    #ifndef CTEMPLATELIST_H
    #define CTEMPLATELIST_H
    
    #include <stddef.h>
    #include <limits>
    
    template <class tData>
    class cTemplateList;
    template <class tData>
    class cTemplateListNose;
    template <class tData>
    class cTemplateListObject;
    
    template <class tData>
    class cTemplateList
    {
      public:
        cTemplateList();
        ~cTemplateList();
    
        tData&       operator[] (unsigned int pos);        // get
        unsigned int operator<<=(tData newData);           // insert
        tData        operator>>=(unsigned int pos);        // delete
    
        unsigned int insert     (tData newData, unsigned int pos = UINT_MAX);
        tData        remove     (unsigned int pos = 0);
        tData&       get        (unsigned int pos);
    		unsigned int count      ();
    
        void         deleteList ();
    
      protected:
         cTemplateListNose<tData>* listNose;
    };
    
    template <class tData>
    class cTemplateListNose
    {
      public:
    // Konstruktoren
        cTemplateListNose();
        ~cTemplateListNose();
    // Funktionen
        void deleteList();
        unsigned int insertData(tData newData, unsigned int pos);
        tData        deleteData(unsigned int pos);
        tData&       getData   (unsigned int pos);
    
    		unsigned int count();
    
      private:
        cTemplateListObject<tData>* listStart;
    };
    template <class tData>
    class cTemplateListObject
    {
      public:
    // Konstruktoren
        cTemplateListObject(tData newData, cTemplateListObject<tData>* newNextObject);
        ~cTemplateListObject();
    // Funktionen
        unsigned int insertData(tData newData, unsigned int pos, unsigned int itsPos);
        tData        deleteData(unsigned int pos);
        tData&       getData   (unsigned int pos = 0);
    
        cTemplateListObject<tData>* getNextObject() {return nextObject;}
        cTemplateListObject<tData>* setNextObject(cTemplateListObject<tData>* newNextObject);
    
      private:
        cTemplateListObject<tData>* nextObject;
        tData *data;
    };
    
    //---------------------------------------------------------------------------
    #endif // CTEMPLATELIST_H
    

    cTemplateList.cpp:

    #include "cTemplateList.h"
    
    #ifndef CTEMPLATELIST_CPP
    #define CTEMPLATELIST_CPP
    
    template <class tData>
    cTemplateList<tData>::cTemplateList()
    {
      listNose = new cTemplateListNose<tData>();
    }
    
    template <class tData>
    cTemplateList<tData>::~cTemplateList()
    {
      delete listNose;
    }
    
    template <class tData>
    tData& cTemplateList<tData>::operator[](unsigned int pos)
    {
      return listNose->getData(pos);
    }
    
    template <class tData>
    unsigned int cTemplateList<tData>::operator<<=(tData newData)
    {
      return listNose->insertData(newData, UINT_MAX);
    }
    
    template <class tData>
    tData cTemplateList<tData>::operator>>=(unsigned int pos)
    {
      return listNose->deleteData(pos);
    }
    
    template <class tData>
    unsigned int cTemplateList<tData>::insert(tData newData,
                                                  unsigned int pos)
    {
      return listNose->insertData(newData, pos);
    }
    template <class tData>
    tData cTemplateList<tData>::remove(unsigned int pos)
    {
      return listNose->deleteData(pos);
    }
    template <class tData>
    tData& cTemplateList<tData>::get(unsigned int pos)
    {
      return listNose->getData(pos);
    }
    
    template <class tData>
    unsigned int cTemplateList<tData>::count()
    {
      return listNose->count();
    }
    
    template <class tData>
    void cTemplateList<tData>::deleteList()
    {
    	listNose->deleteList();
    }
    
    //----------------------------------------------------------------------
    
    template <class tData>
    cTemplateListNose<tData>::cTemplateListNose()
    {
      listStart = NULL;
    }
    
    template <class tData>
    cTemplateListNose<tData>::~cTemplateListNose()
    {
    	if (listStart != NULL)
    		delete listStart;
    }
    
    template <class tData>
    unsigned int cTemplateListNose<tData>::insertData(tData newData,
                                                      unsigned int pos)
    {
    	if(listStart == NULL)
    	{
    		listStart = new cTemplateListObject<tData>(newData, NULL);
    		return 0;
    	}
      if (pos != 0)
        return listStart->insertData(newData, pos, 0);
      listStart = new cTemplateListObject<tData>(newData, listStart);
      return pos;
    }
    
    template <class tData>
    tData cTemplateListNose<tData>::deleteData(unsigned int pos)
    {
      if (listStart != NULL)
    	{
        //return 0;   ////////////////////////////
      if (pos != 0)
        return listStart->deleteData(pos - 1);
      tData tempData = listStart->getData();
      cTemplateListObject<tData>* temp = listStart->setNextObject(0);
      delete listStart;
      listStart = temp;
      return tempData;
    	}
    }
    
    template <class tData>
    tData& cTemplateListNose<tData>::getData(unsigned int pos)
    {
      if (listStart != 0)
        return listStart->getData(pos);
    }  /////////////////
    
    template <class tData>
    unsigned int cTemplateListNose<tData>::count()
    {
    	if(listStart == NULL)
    		return 0;
    
    	cTemplateListObject<tData>* countObject = listStart;
    
    	unsigned int counter = 1;
    
    	while(countObject->getNextObject() != NULL)
    	{
    		countObject = countObject->getNextObject();
    		counter++;
    	}
    	return counter;
    }
    
    template <class tData>
    void cTemplateListNose<tData>::deleteList()
    {
    	if(listStart != NULL)
    	{
    		delete listStart;
    		listStart = NULL;
    	}
    }
    
    //----------------------------------------------------------------------
    
    template <class tData>
    cTemplateListObject<tData>::cTemplateListObject(tData newData,
                                                    cTemplateListObject<tData>* newNextObject)
    {
    	data = new tData(newData);
    	nextObject = newNextObject;
    }
    
    template <class tData>
    cTemplateListObject<tData>::~cTemplateListObject()
    {
    	if(this != NULL)
    	{
    	  delete data;
    		delete nextObject;
    	}
    }
    
    template <class tData>
    unsigned int cTemplateListObject<tData>::insertData(tData newData,
                                                        unsigned int pos,
                                                        unsigned int itsPos)
    {
      if (nextObject == NULL)
      {
        nextObject = new cTemplateListObject<tData>(newData, NULL);
        return itsPos + 1;
      }
      else
      {
        if (itsPos == pos - 1)
        {
          nextObject = new cTemplateListObject<tData>(newData, nextObject);
          return pos;
        }
        else
          return nextObject->insertData(newData, pos, itsPos + 1);
      }
    }
    
    template <class tData>
    tData cTemplateListObject<tData>::deleteData(unsigned int pos)
    {
      if (nextObject == NULL)
        return *data;      //////////////////////
      if (pos != 0)
        return nextObject->deleteData(pos - 1);
      tData tempData = nextObject->getData();
      cTemplateListObject<tData>* temp = nextObject->setNextObject(0);
      delete nextObject;
      nextObject = temp;
      return tempData;
    }
    
    template <class tData>
    tData& cTemplateListObject<tData>::getData(unsigned int pos)
    {
      if (pos == 0)
        return *data;
      else
        if (nextObject != NULL)
          return nextObject->getData(pos - 1);
    }
    
    template <class tData>
    cTemplateListObject<tData>* cTemplateListObject<tData>::setNextObject
      (cTemplateListObject<tData>* newNextObject)
    {
      cTemplateListObject<tData>* temp = nextObject;
      nextObject = newNextObject;
      return temp;
    }
    
    #endif // CTEMPLATELIST_CPP
    

    Diese TemplateList funktioniert auch erstmal problemlos. In meinem Programm habe ich auch noch eine Klasse cSprite erstellt:

    cspriteclass.h:

    #ifndef SPRITECLASS_H
    #define SPRITECLASS_H
    
    #include <string>
    #include "directdrawclass.h"
    
    using namespace std;
    
    class cSprite
    {
      public:
    
    		cSprite();
    		~cSprite();
    
    		int Init(LPDIRECTDRAWSURFACE7 InitSurface, int x = 0, int y = 0, int startTag = 0);
    
    		void SetXY(int newX, int newY);
    		void Move (int movX, int movY);
    
    		int Draw(LPDIRECTDRAWSURFACE7 Buffer);
    
    		bool Collision(cSprite collisionSprite);
    
    		int GetX()      { return posX; }
    		int GetY()      { return posY; }
    		int GetWidth()  { return Width; }
    		int GetHeight() { return Height; }
    
    		RECT GetBounceRect() { return BounceRect; }
    
    		int GetTag()    { return tag; } 
    
      private:
    
    		LPDIRECTDRAWSURFACE7 SSurface;
    
    		int posX, posY;
    		int Width, Height;
    
    		RECT BounceRect;
    
    		int tag;
    
    };
    
    #endif
    

    cspriteclass.cpp:

    #ifndef SPRITECLASS_CPP
    #define SPRITECLASS_CPP
    
    #include "spriteclass.h"
    
    cSprite::cSprite()
    {
      SSurface = NULL;
    	posX = 0;
    	posY = 0;
    	Width = 0;
    	Height = 0;
    	tag = 0;
    }
    
    cSprite::~cSprite()
    {
    	if(SSurface != NULL)
    	{
    	  delete SSurface;
    		SSurface = NULL;
    	}
    }
    
    int cSprite::Init(LPDIRECTDRAWSURFACE7 InitSurface, int x, int y, int startTag)
    {
    	SSurface = InitSurface;
    
    	if(SSurface == NULL)
    		return Error("Oberfläche von cSurface konnte nicht erstellt werden");
    
    	DDSURFACEDESC2 sizeDesc;
    	ZeroMemory(&sizeDesc, sizeof(sizeDesc));
    	sizeDesc.dwSize = sizeof(sizeDesc);
    
    	SSurface->GetSurfaceDesc(&sizeDesc);
    
    	Width = sizeDesc.dwWidth;
    	Height = sizeDesc.dwHeight;
    
    	DDCOLORKEY ColorKey;
    
    	ColorKey.dwColorSpaceHighValue = RGB(255, 255, 255);
    	ColorKey.dwColorSpaceLowValue  = RGB(255, 255, 255);
    
    	if (FAILED(SSurface->SetColorKey(DDCKEY_SRCBLT, &ColorKey)))
    		return Error("Colorkey konnte nicht SSurface zugewiesen werden");
    
    	posX = x;
    	posY = y;
    
    	BounceRect.left = posX;
    	BounceRect.top = posY;
    	BounceRect.right = posX + Width;
    	BounceRect.bottom = posY + Height;
    
    	tag = startTag;
    
    	return 0;
    }
    
    int cSprite::Draw(LPDIRECTDRAWSURFACE7 Buffer)
    {
    	if(FAILED(Buffer->BltFast(posX, posY, SSurface, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY)))
    		return Error("Sprite konnte nicht auf die Oberfläche geblittet werden");
    
    	return 0;
    
    }
    
    bool cSprite::Collision(cSprite collisionSprite)
    {
    	RECT collisionRect = collisionSprite.GetBounceRect();
    
    	if((BounceRect.left < collisionRect.right) && (BounceRect.right > collisionRect.left) &&
    		(BounceRect.bottom >= collisionRect.top) && (BounceRect.top < collisionRect.bottom))
    	{
    		return true;
    	}
    
    	return false;
    }
    
    void cSprite::SetXY(int newX, int newY)
    {
    	if((newX >= 0) && (newX <= SCR_WIDTH - Width))
    	{
    		posX = newX;
    		BounceRect.left = posX;
    		BounceRect.right = posX + Width;
    	}
    
    	if((newY >= 0) && (newY <= SCR_HEIGHT - Height))
    	{
    		posY = newY;
    		BounceRect.top = posY;
    		BounceRect.bottom = posY + Height;
    	}
    }
    
    void cSprite::Move(int movX, int movY)
    {
    	if((posX + movX >= 0) && (posX + movX <= SCR_WIDTH - Width))
    	{
    		posX += movX;
    		BounceRect.left = posX;
    		BounceRect.right = posX + Width;
    	}
    
    	if((posY + movY >= 0) && (posY + movY <= SCR_HEIGHT - Height))
    	{
    		posY += movY;
    		BounceRect.top = posY;
    		BounceRect.bottom = posY + Height;
    	}
    }
    
    //--------------------------------------------------------------------------------------------------
    
    #endif
    

    Nun noch das Programm selber:

    main.h:

    #ifndef MAIN_H
    #define MAIN_H
    
    #include <windows.h>
    #include <stdio.h>
    
    #define WINDOW_TITLE "Game"
    #define FRAME_RATE 80
    
    HWND CreateMainWindow(HINSTANCE hInstance);
    HRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    namespace nRender
    {
    	void RenderRun();
    	void Collision();
    	void RenderPaused();
    	void RenderLvl();
    	void RenderGameOver();
    }
    
    namespace nStones
    {
    	int size = 48; //normal 48
    	int speed = 7;
    	int max = 3;
    	int actual = 2; 
    	int reloadingTime = 200;
    	int actualReload = 0;
    	int arrowLvl = 1;
    	LPSTR file = "c:\\Bilder\\Stone01.bmp";
    }
    
    namespace nPlayer
    {
    	int lives = 5;
    	int lvl = 1;
    
    	float arrowSpeed = 0;
    	int arrowSpeedIncrease = 1;
    	int arrowSpeedMax = 6;
    
    	int stoneInterval = 10;
    	int actualStoneInterval = 10;
    
    	int escapeInterval = 10;
    	int actualEscapeInterval = 10;
    }
    
    class cFrameManager
    {
      public:
    
    	  void Init();
    		bool Frame();
    
      private:
    
    		LONGLONG Frequency;
    		LONGLONG Interval;
    		LONGLONG NextFrame;
    		LONGLONG ActualTime;
    
    };
    
    class cEnemyManager
    {
      public:
    
    		cEnemyManager();
    
    		void Init(int size, int speed, int duration, LPSTR file);
    		void Change (float changeSize, float changeSpeed, int changeDuration, LPSTR changeFile);
    		int Frame();
    
    	private:
    
    		LPSTR EFile;
    		int ESize;
    		int ESpeed;
    		int EDuration;
    		int ActualTime;
    };
    
    #endif
    

    main.cpp:

    #ifndef MAIN_CPP
    #define MAIN_CPP
    
    #include "main.h"
    #include "directdrawclass.h"
    #include "spriteclass.h"
    #include "directinputclass.h"
    #include "cTemplateList.cpp"
    
    cDirectDraw DirectDraw;
    cDirectInput DirectInput;
    cEnemyManager EnemyManager;
    cFrameManager FrameManager;
    
    cSprite ArrowSprite;
    
    int enemyNumber = 4;
    
    #define RUN      0
    #define PAUSED   1
    #define NEXTLVL  2
    #define GAMEOVER 3
    
    int gameMod = RUN;
    
    cTemplateList<cSprite> StoneList;
    cTemplateList<cSprite> EnemyList;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	MSG msg;
    	HWND hWnd = NULL;
    	LPDIRECTDRAWSURFACE7 ArrowSurf = NULL;
    	cSprite Test;
    
    	hWnd = CreateMainWindow(hInstance);
    
    	EnemyManager.Init(43, 1, FRAME_RATE * 4, "c:\\Bilder\\Sphere01.bmp");
    	StoneList <<= Test;
    
    	FrameManager.Init();
    	DirectDraw.Init(hWnd);
    	DirectInput.Init(hInstance, hWnd);
    
    	ArrowSurf = DirectDraw.CreateSurfaceFromBitmap("c:\\Bilder\\ArrowDown.bmp", 40, 40);
    	ArrowSprite.Init(ArrowSurf, SCR_WIDTH / 2 - 20, (nStones::arrowLvl - 1) * 30 + 4);
    
    	while(true)
    	{
    		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    		{
    			if(msg.message == WM_QUIT)
    			{
    				break;
    			}
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    		else
    		{
    			if(FrameManager.Frame())
    			{
    				if(DirectInput.GetKeyBoardState())
    					Error("Tasten konnten nicht ermittelt werden");
    				if(nPlayer::actualStoneInterval < nPlayer::stoneInterval)
    					nPlayer::actualStoneInterval++;
    				if(nPlayer::actualEscapeInterval < nPlayer::escapeInterval)
    					nPlayer::actualEscapeInterval++;
    
    				switch(gameMod)
    				{
    					case PAUSED:
    
    						if(DirectInput.KeyState(DIK_ESCAPE))
    							if(nPlayer::actualEscapeInterval >= nPlayer::escapeInterval)
    							{
    								PostQuitMessage(0);
    							}
    
    							nRender::RenderPaused();
    						break;
    
    				  case RUN:
    
    						if(DirectInput.KeyState(DIK_LEFT))
    						{
    							if(nPlayer::arrowSpeed > -nPlayer::arrowSpeedMax)
    								nPlayer::arrowSpeed-= nPlayer::arrowSpeedIncrease;
    							else if(nPlayer::arrowSpeed < -nPlayer::arrowSpeedMax)
    								nPlayer::arrowSpeed = -nPlayer::arrowSpeedMax;
    						}
    						else if(DirectInput.KeyState(DIK_RIGHT))
    						{
    							if(nPlayer::arrowSpeed < nPlayer::arrowSpeedMax)
    								nPlayer::arrowSpeed+= nPlayer::arrowSpeedIncrease;
    							else if(nPlayer::arrowSpeed > nPlayer::arrowSpeedMax)
    								nPlayer::arrowSpeed = nPlayer::arrowSpeedMax;
    						}
    
    						if(DirectInput.KeyState(DIK_SPACE))
    						{
    							if((nStones::actual > 0) && (nPlayer::actualStoneInterval >= nPlayer::stoneInterval))
    							{
    								cSprite NewStone;
    								LPDIRECTDRAWSURFACE7 StoneSurf;
    
    								StoneSurf = DirectDraw.CreateSurfaceFromBitmap(nStones::file, nStones::size, nStones::size);
    
    								NewStone.Init(StoneSurf, ArrowSprite.GetX() - (nStones::size - ArrowSprite.GetWidth()) / 4, ArrowSprite.GetY() + 30);
    								StoneList <<= NewStone;
    
    								nStones::actual--;
    								nPlayer::actualStoneInterval = 0;
    							}
    						}
    
    						if(DirectInput.KeyState(DIK_ESCAPE))
    							if(nPlayer::actualEscapeInterval >= nPlayer::escapeInterval)
    							{
    								gameMod = PAUSED;		
    								nPlayer::actualEscapeInterval = 0;
    							}
    
    					  if (EnemyManager.Frame() > 0)
    							nPlayer::lives--;
    						nRender::RenderRun();
    						nRender::Collision();
    						if(nPlayer::lives <= 0)
    							gameMod = GAMEOVER;
    						break;
    
    					case NEXTLVL:
    
    						if(DirectInput.KeyState(DIK_1))
    						{
    							nStones::speed++;
    							gameMod = RUN;
    						}
    						else if(DirectInput.KeyState(DIK_2))
    						{
    							nStones::max += 2;
    							nStones::actual = nStones::max - 1;
    							gameMod = RUN;
    						}
    						else if(DirectInput.KeyState(DIK_3))
    						{
    							nStones::reloadingTime -= 15;
    							gameMod = RUN;
    						}
    						else if(DirectInput.KeyState(DIK_4))
    						{
    							nStones::size += 5;
    							gameMod = RUN;
    						}
    						else if(DirectInput.KeyState(DIK_5))
    						{
    							nStones::arrowLvl++;
    							ArrowSprite.Move(0, 30);
    							gameMod = RUN;
    						}
    						else if(DirectInput.KeyState(DIK_6))
    						{
    							nPlayer::lives += 5;
    							gameMod = RUN;
    						}
    
    						nRender::RenderLvl();
    						break;
    
    					case GAMEOVER:
    
    						nRender::RenderGameOver();
    						break;
    				}
    			}
    		}
    	}
    
    	DirectDraw.~cDirectDraw();
    
    	return 0;
    }
    
    HRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
      	case WM_KEYDOWN:
    
    			if((wParam != VK_ESCAPE) && (gameMod == PAUSED))
    				gameMod = RUN;
    
    	  	break;
    
    		default:
          return DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    //------------------------------------------------------------------------------------------------------
    //-Functions--------------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------------------------
    
    int Error(char *msg)
    {
    	OutputDebugString(msg);
    	OutputDebugString("\n");
    
    	MessageBox(NULL, msg, "Fehler", MB_OK);
    
    	return -1;
    }
    
    HWND CreateMainWindow(HINSTANCE hInstance)
    {
    	WNDCLASSEX window;
    
    	window.cbSize        = sizeof(window);
    	window.style         = CS_DBLCLKS | CS_OWNDC;
    	window.lpfnWndProc   = WindowProc;
    	window.cbClsExtra    = 0;
    	window.cbWndExtra    = 0;
    	window.hInstance     = hInstance;
    	window.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    	window.hCursor       = LoadCursor(NULL, IDC_ARROW);
    	window.lpszMenuName  = NULL;
    	window.lpszClassName = "WindowClass";
    	window.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    	window.hIconSm       = LoadIcon(NULL, IDI_WINLOGO);
    
    	RegisterClassEx(&window);
    
    	return CreateWindowEx(NULL, "WindowClass", WINDOW_TITLE, WS_POPUP | WS_VISIBLE, 200, 200, 500, 500, NULL, NULL, hInstance, NULL);
    }
    
    void nRender::RenderRun()
    {
    	static HDC wndDC;
    
    	ArrowSprite.Draw(DirectDraw.GetBuffer());
    	for(int i = 0; i < StoneList.count(); i++)
    	{
    		StoneList[i].Move(0, nStones::speed);
    		StoneList[i].Draw(DirectDraw.GetBuffer());
    		if(StoneList[i].GetY() >= SCR_HEIGHT - StoneList[i].GetHeight() - nStones::speed)
    		{
    			StoneList >>= i;
    			i--;
    		}
    	}
    	if((nStones::actualReload < nStones::reloadingTime) && (nStones::actual < nStones::max))
    		nStones::actualReload++;
    	if((nStones::actualReload == nStones::reloadingTime) && (nStones::actual < nStones::max))
    	{
    		nStones::actual++;
    		nStones::actualReload = 0;
    	}
    
    	if(ArrowSprite.GetX() >= SCR_WIDTH - nStones::size - nPlayer::arrowSpeed)
    		ArrowSprite.SetXY((nStones::size - ArrowSprite.GetWidth()) / 2, ArrowSprite.GetY());
    	if(ArrowSprite.GetX() <= (nStones::size - ArrowSprite.GetWidth()) / 2 - nPlayer::arrowSpeed)
    		ArrowSprite.SetXY(SCR_WIDTH - nStones::size, ArrowSprite.GetY());
    
    	ArrowSprite.Move(nPlayer::arrowSpeed, 0);
    
    	if(nPlayer::arrowSpeed > 0)
    		nPlayer::arrowSpeed-= 0.1;
    	if(nPlayer::arrowSpeed < 0)
    		nPlayer::arrowSpeed+= 0.1;
    
    	DirectDraw.GetBuffer()->GetDC(&wndDC);
    	char Text[25];
    	sprintf(Text, "Nachladen: %i / %i", nStones::actualReload, nStones::reloadingTime);
    	TextOut(wndDC, 0, 0, Text, strlen(Text));
    
    	sprintf(Text, "Steine: %i / %i", nStones::actual, nStones::max);
    	TextOut(wndDC, 200, 0, Text, strlen(Text));
    
    	sprintf(Text, "Leben: %i", nPlayer::lives);
    	TextOut(wndDC, 400, 0, Text, strlen(Text));
    
    	sprintf(Text, "Feinde: %i", enemyNumber);
    	TextOut(wndDC, 600, 0, Text, strlen(Text));
    
    	sprintf(Text, "Level: %i", nPlayer::lvl);
    	TextOut(wndDC, 800, 0, Text, strlen(Text));
    
      DirectDraw.GetBuffer()->ReleaseDC(wndDC); 
    
    	DirectDraw.Flip();
    	DirectDraw.Clear(RGB(254, 254, 254));
    }
    
    void nRender::Collision()
    {
    	for(int i = 0; i < StoneList.count(); i++)
    		for(int j = 0; j < EnemyList.count(); j++)
    			if(StoneList[i].Collision(EnemyList[j]))
    			{
    				EnemyList >>= j;
    				enemyNumber--;
    				if(enemyNumber == 0)
    				{
    					gameMod = NEXTLVL;
    					nPlayer::lvl++;
    					enemyNumber = nPlayer::lvl * 3;
    					EnemyManager.Change(-0.8, 0.4, -20, "c:\\Bilder\\Sphere01.bmp");
    				}
    			}
    }
    
    void nRender::RenderPaused()
    {
    	static HDC wndDCPaused;
    	DirectDraw.GetBuffer()->GetDC(&wndDCPaused);
    	TextOut(wndDCPaused, SCR_WIDTH / 2 - 20, 50, "Pause", 5);
    	TextOut(wndDCPaused, SCR_WIDTH / 2 - 100, 100, "Drücke ESC, um das Spiel zu beenden", 35);
    	TextOut(wndDCPaused, SCR_WIDTH / 2 - 200, 120, "Drücke eine beliebige andere Taste, um das Spiel zu fortzusetzen", 64);
    
    	DirectDraw.GetBuffer()->ReleaseDC(wndDCPaused);
    	DirectDraw.Flip();
    	DirectDraw.Clear(RGB(254, 254, 254));
    }
    
    void nRender::RenderLvl()
    {
    	static HDC wndDCLvl;
    	char Text[45];
    	sprintf(Text, "Du hast Level %i erfolgreich abgeschlossen!", nPlayer::lvl - 1);
    
    	DirectDraw.GetBuffer()->GetDC(&wndDCLvl);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 50, 50, "Glückwunsch!", 12);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 150, 70, Text, strlen(Text));
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 40, 110, "Upgrades:", 9);
    
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 140, "1 Schnellere Steine", 19);
    	sprintf(Text, "2 Mehr Steine (von %i auf %i)", nStones::max, nStones::max + 2);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 160, Text, strlen(Text));
    	sprintf(Text, "3 Schneller Nachladen (von %i aud %i)", nStones::reloadingTime, nStones::reloadingTime - 15);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 180, Text, strlen(Text));
      TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 200, "4 Größere Steine (+4 Pixel)", 27);
    	sprintf(Text, "5 Abwurfanlage tiefer (auf Ebene %i)", nStones::arrowLvl + 1);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 220, Text, strlen(Text));
    	sprintf(Text, "6 Mehr Leben (von %i auf %i)", nPlayer::lives, nPlayer::lives + 5);
    	TextOut(wndDCLvl, SCR_WIDTH / 2 - 120, 240, Text, strlen(Text));
    
    	DirectDraw.GetBuffer()->ReleaseDC(wndDCLvl);
    	DirectDraw.Flip();
    	DirectDraw.Clear(RGB(254, 254, 254));
    }
    
    void nRender::RenderGameOver()
    {
    	static HDC wndDCGameOver;
    
    	DirectDraw.GetBuffer()->GetDC(&wndDCGameOver);
    
    	TextOut(wndDCGameOver, SCR_WIDTH / 2 - 50, 50, "Game Over", 9);
    	TextOut(wndDCGameOver, SCR_WIDTH / 2 - 130, 80, "Zu viele Kugeln erreichten ihr Ziel!", 36);
    
    	DirectDraw.GetBuffer()->ReleaseDC(wndDCGameOver);
    	DirectDraw.Flip();
    	DirectDraw.Clear(RGB(254, 254, 254));
    }
    
    //-----------------------------------------------------------------------------------------------------
    //-cFrameManager---------------------------------------------------------------------------------------
    //-----------------------------------------------------------------------------------------------------
    
    void cFrameManager::Init()
    {
    	if(!QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency))
    		Error("Performance Counter nicht verfügbar");
    
    	Interval = Frequency / FRAME_RATE;
    	QueryPerformanceCounter((LARGE_INTEGER*)&ActualTime);
    	NextFrame = ActualTime + Interval;
    }
    
    bool cFrameManager::Frame()
    {
    	QueryPerformanceCounter((LARGE_INTEGER*)&ActualTime);
    
    	if(ActualTime > NextFrame)
    	{
    		NextFrame = ActualTime + Interval;
    		return true;
    	}
    
    	return false;
    }
    
    //-----------------------------------------------------------------------------------------------------
    //-cEnemyManager---------------------------------------------------------------------------------------
    //-----------------------------------------------------------------------------------------------------
    
    cEnemyManager::cEnemyManager()
    {
    	ActualTime = 0;
    }
    
    void cEnemyManager::Init(int size, int speed, int duration, LPSTR file)
    {
    	srand(1);
    	ESize = size;
    	ESpeed = speed;
    	EDuration = duration;
    	EFile = file;
    	ActualTime = EDuration / 2;
    }
    
    void cEnemyManager::Change(float changeSize, float changeSpeed, int changeDuration, LPSTR changeFile)
    {
    	ESize += changeSize;
    	ESpeed += changeSpeed;
    	EDuration += changeDuration;
    	EFile = changeFile;
    	ActualTime = EDuration / 2;
    }
    
    int cEnemyManager::Frame()
    {
    	ActualTime++;
    	int damage = 0;
    
    	if(ActualTime == EDuration)
    	{
    		LPDIRECTDRAWSURFACE7 EnemySurface = NULL;
    		cSprite EnemySprite;
    
    		EnemySurface = DirectDraw.CreateSurfaceFromBitmap(EFile, ESize, ESize);
    		int direction = rand() % 2;
    
    		if(direction == 0)
    		{
    			EnemySprite.Init(EnemySurface, 0, SCR_HEIGHT - ESize, 0);
    			EnemyList <<= EnemySprite;
    		}
    		else
    		{
    			EnemySprite.Init(EnemySurface, SCR_WIDTH - ESize, SCR_HEIGHT - ESize, 1);
    			EnemyList <<= EnemySprite;
    		}
    		ActualTime = 0;
    	}
    
    	for (int i = 0; i < EnemyList.count(); i++)
    	{
    		if(EnemyList[i].GetTag() == 0)
    		{
    			if(EnemyList[i].GetX() >= SCR_WIDTH - EnemyList[i].GetWidth() - ESpeed)
    			{
    				damage++;
    				EnemyList >>= i;
    				i--;
    			}
    			else
    			{
    				EnemyList[i].Move(ESpeed, 0);
    				EnemyList[i].Draw(DirectDraw.GetBuffer());
    			}
    		}
    		if(EnemyList[i].GetTag() == 1)
    		{
    			if(EnemyList[i].GetX() <= EnemyList[i].GetWidth() + ESpeed)
    			{
    				damage++;
    				EnemyList >>= i;
    				i--;
    			}
    			else
    			{
    				EnemyList[i].Move(-ESpeed, 0);
    				EnemyList[i].Draw(DirectDraw.GetBuffer());
    			}
    		}
    	}
    
    	return damage;
    }  
    
    #endif
    

    directdrawclass.h und directinputclass.h sind zwei weitere von mir geschriebenen Dateien, die allerdings ohne Probleme funktionieren.

    Wenn ich das Programm im Debug-Modus durchgehe, fügt er Test problemlos in StoneList ein, doch dann bei FrameManager.Init() kommt er zu folgender Nachricht:

    There is no source code available for the current location.

    Wenn ich Test nicht in StoneList einfüge, läuft FrameManager.Init() ohne Fehlermeldung.

    Kann mir da bitte einer helfen?


  • Administrator

    1. Glaubst du wirklich, dass irgendjemand so viel Code durchlesen wird? Verkürze den Code immer, damit es kurz und klein ist, aber den Fehler trotzdem ergzeugt.
    2. There is no source code available for the current location.
    Das ist eine Meldung des Debuggers und hat nichts mit C++ zu tun, sondern mit dem Debugger. Er kann den Code für die Zeile nicht finden, wo das Programm aktuell ist. Daher gehört dies eher in das Compiler/IDE Forum.
    3. Was hat das mit dem Titel zu tun? Oder hast du noch irgendwo eine Frage versteckt?
    4. Dein Code-Stil ist nicht so schön ... aber über Geschmack lässt sich bekanntlich streiten und ich habe aktuell keine Lust, eine Liste aufzustellen, bzw. den ganzen Code durchzulesen.

    Grüssli



  • OK dann lass den Quelltext einfach. Hast du sonst eine Idee wie es zu solch einer Fehlermeldung kommen kann?



  • Ach ja zum Titel. Meiner Meinung nach hat der Fehler irgendwas mit der Templateliste zu tun, da kein Fehler erscheint, sobald ich StoneList <<= Test weglasse.


  • Administrator

    KingLuc schrieb:

    OK dann lass den Quelltext einfach. Hast du sonst eine Idee wie es zu solch einer Fehlermeldung kommen kann?

    Wie sollte ich das? Ich weiss ja nicht mal welcher Debugger du verwendest.

    KingLuc schrieb:

    Ach ja zum Titel. Meiner Meinung nach hat der Fehler irgendwas mit der Templateliste zu tun, da kein Fehler erscheint, sobald ich StoneList <<= Test weglasse.

    Ich soll den Code nicht berücksichtigen, aber StoneList <<= Test im Code suchen gehen, oder wie?

    Mir kommt da aber so eine Idee. Könnte es sein, dass dein Programm mit einer Fehlermeldung abbricht, du auf Wiederholen oder sowas ähnliches drückst und danach erst diese Fehlermeldung kommt? Oder kurz gesagt, dass du uns Informationen vorenthälst, bzw. die richtige Fehlermeldung?

    Grüssli



  • Also mein Problem ist, dass sobald ich ein Element in eine Instanz von cTemplateList einfüge, zeigt er mir bei

    if(!QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency))
    		Error("Performance Counter nicht verfügbar");
    
    	Interval = Frequency / FRAME_RATE;
    	QueryPerformanceCounter((LARGE_INTEGER*)&ActualTime);
    	NextFrame = ActualTime + Interval;
    

    die Fehlermeldung, die oben steht.

    Ich benutze Visual C++ 2008. Diese Fehlermeldung ist die einzige, die ich erhalte wenn ich auf Start im Debug-Mods klicke. Ich muss dazu sagen, dass die Templatelist vorher ohne Probleme lief. Erst als ich in spriteclass.h unter private von cSprite die Zeile

    cTemplateList<cTemplateList<int>> animationList;
    

    eingefügt und gestartet habe, ergaben sich diese Probleme. Als ich diese Zeile entfernt habe, lief das Programm wieder. Nun habe ich noch die Methode deleteList() von cTemplateList deklariert. Von da an funktioniert gar nichts mehr und er zeigt mir die oben genannte Fehlermeldung.

    Ich habe deleteList() natürlich wieder rausgenommen, doch das Programm funktioniert trotzdem nicht.

    Ich entschuldige mich dafür, dass ich im ersten Beitrag nur "Schrott" geschrieben habe.



  • Wie bereits gesagt wurde ist "There is no source code available" keine Fehlermeldung. Und "funktioniert nicht" übrigens auch nicht.



  • also einige Anmerkugnen:
    - ich hab mir natürlich nicht den kompletten Code durchgelesen, aber eines deiner includes ist stddef.h - das ist ein C-header. In C++ bindest du besser <cstddef> ein, der biete die selben Funktionen, allerdings im namespace std. Am besten wäre es natürlich, wenn du garnicht erst header aus der C-Bibliothek brauchst sondern die Funktionalität aus der C++-Bibliothek bekommen kannst.

    KingLuc schrieb:

    if(!QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency))
    

    Das (LARGE_INTEGER*) ist ein C-Cast und hat in C++ so nichts zu suchen. Benutz dynamic_cast oder static_cast, je nach Kontext.
    - die "no source code available" meldung kommt wie andere schon sagten vom Debugger und heißt, dass er bei dem Code-schritt den er grde ausführt keinen zugehörigen Source-Code kennt. Das kann daran liegen dass du eine externe vorkompilierte Bibliothek benutzt die keinen Sourcecode mitgeliefert hat oder dass ein Teil des Codes ohne debuginformationen kompiliert wurde und damit kein bezug zum sourcecode hergestellt werden kann.



  • Mir ist aufgefallen, dass er ein Problem mit LONGLONG (bzw. __int64) hat. Wenn ich zum Beispiel

    Interval = Frequency / FRAME_RATE; //FRAME_RATE ist mit 80 defined
    

    durch

    unsigned long x = Frequency;
    Interval = x / FRAME_RATE;
    

    ersetze, zeigt er mir im Debug-Modus keinen Fehler an. Außerdem funktionieren Addition und Subtraktion von Frequency und FRAME_RATE problemlos. Wenn ich allerdings dividiere oder multipliziere zeigt er mir den Fehler an.
    Manchmal zeigt er kurz vor der Fehlermeldung an, welche Datei er sucht. In diesem Fall war es ulldiv.asm. Was ist das?



  • - Wenn er einen Fehler anzeigt, solltest du den auch hier wiedergeben, da wir mangels Glaskugel nicht sagen können welcher fehler das ist.
    - Beim weiteren Überfliegen deines Quelltextes hab ich einige #defines für Konstanten gesehen, das ist nicht nur PFUI, das ist widerlich. Sowas tut man vielleicht in C, aber auf keinen Fall in C++. Dafür gibts const static int/double/std::string/.....
    - LONGLONG bzw. __int64 sind beide keine Standard-Datentypen. Wenn du nicht einen sehr guten grudn hast sie zu benutzen solltest du es bei long oder einfach int belassen.



  • Ich habe den Fehler inzwischen gefunden. Mein Computer ist ein 32-bit-System. Daher kann er mit __int64 nicht ohne weiteres multiplizieren oder addieren. Er benötigt dafür eine Datei namens ulldiv.asm, die er an meinem Rechner nicht findet. Daher der Fehler: There is no source code available for the current location.

    Ic hhabe __int64 jetzt durch float ersetzt und es funktioniert einwandfrei.
    Nochmal vielen Dank an alle, die mir geholfen haben.



  • KingLuc schrieb:

    Ic hhabe __int64 jetzt durch float ersetzt und es funktioniert einwandfrei.

    Bis jetzt. Denn es ist nicht gerade ungefährlich, was du da machst. Vor allem ist es nicht genau. Weshalb, siehst du in einem der vielen Rundungsfehler-Threads...


  • Mod

    Am Nachwuchs für WTFs wird es auch in Zukunft nicht mangeln...


Anmelden zum Antworten