0

嗨,我用名为 Evil Monkeys的 3D Buzz教程制作了一个关卡生成器。我生成了一个关卡,但无法将其绘制在屏幕上。

我的代码:

级别.cpp

    #include "Level.h"
#include <stdlib.h>
#include "Sprite.h"
Level::Level(drawEngine *de, int w, int h)
{
    drawArea = de;

    width = w;
    height = h;

    gamer = 0;

    //create memory for our level
    level = new char *[width];

    for(int x = 0; x < width; x++)
    {
        level[x] = new char[height];
    }

    //create the level
    createLevel();

    drawArea->setMap(level);
}

Level::~Level()
{
    for(x = 0; x < width; x++)
        delete []level[x];

    delete [] level;
}

void Level::createLevel(void)
{
    for(int x = 0; x < width; x++)
    {
        for(int y = 0; y < height; y++)
        {
            int random = rand() % 100;

            if (y == 0 || y == height - 1 || x == 0 || x == width - 1)
            {
                level[x][y] = TILE_WALL;
            }
            else
            {
                if (random < 90 || (x < 3 && y < 3))
                    level[x][y] = TILE_EMPTY;
                else
                    level[x][y] = TILE_WALL;
            }
        }
    }
}


void Level::draw(void)
{
    // level to be drawn here
    drawArea->drawBackground();
}


Level.h

    #ifndef LEVEL_H
#define LEVEL_H

enum
{
    TILE_EMPTY,
    TILE_WALL
};
#include "drawEngine.h"
class Character;

class Level
{
public:
    Level(drawEngine *de, int width = 30, int height = 20);
    ~Level();
    int x;
    int y;

    void addPlayer(Character *p);
    void update(void);
    void draw(void);
    bool keyPress(char c);

protected:
    void createLevel(void);

private:
    int width;
    int height;
    char **level;

    Character *gamer;
    drawEngine *drawArea;

};

#endif

游戏.cpp

    #include "Game.h"
#include <conio.h>
#include <iostream>
#include "drawEngine.h"
#include "Character.h"
#include <windows.h>
using namespace std;
//this will give ME 32 fps
#define GAME_SPEED 25.33
bool Runner::run()
{
    level = new Level(&drawArea, 30, 20);

    drawArea.createBackgroundTile(TILE_EMPTY, ' ');
    drawArea.createBackgroundTile(TILE_WALL, '+');

    drawArea.createSprite(0, '$');
    gamer = new Character(&drawArea, 0);

    level->draw();




    char key = ' ';

    startTime = timeGetTime();

    frameCount = 0;
    lastTime = 0;

    posX = 0;

    while (key != 'q')
    {
        while(!getInput(&key))
        {
            timerUpdate();
        }

        //gamer->keyPress(key);
        //cout << "Here's what you pressed: " << key << endl;
    }

    delete gamer;
    cout << frameCount / ((timeGetTime() - startTime) / 100) << " fps " << endl;
    cout << "Game Over" << endl;

    return true;
}

bool Runner::getInput(char *c)
{ 
    if (kbhit())
    {
        *c = getch();
        return true;
    }
}

void Runner::timerUpdate()
{
    double currentTime = timeGetTime() - lastTime;

    if (currentTime < GAME_SPEED)
        return;


    frameCount++;

    lastTime = timeGetTime();
}

游戏.h

#ifndef GAME_H
#define GAME_H
#include "drawEngine.h"
#include "Sprite.h"
#include "Character.h"
#include "level.h"


class Runner
{
public:
    bool run();



    Runner(){};
protected:
    bool getInput(char *c);

    void timerUpdate();
private:
    Level *level;
    Character* gamer;
    double frameCount;
    double startTime;
    double lastTime;

    int posX;



    drawEngine drawArea;
};

#endif

绘图引擎.cpp

#include <iostream>
#include "drawEngine.h"
#include <windows.h>




using namespace std;
drawEngine::drawEngine(int index, int xSize, int ySize, int x, int y)
{
    screenWidth = x;
    screenHeight = y;

    map = 0;

    //set cursor visibility to false
    //cursorVisibility(false);


}

drawEngine::~drawEngine()
{
    cursorVisibility(true);
    //set cursor visibility to true
}

int drawEngine::createSprite(int index, char c)
{
    if (index >= 0 && index < 16)
    {
        spriteImage[index] = c;
    return index;
    }

    return -1;
}

void drawEngine::deleteSprite(int index)
{
    // in this implemantation we don't need it
}

void drawEngine::drawSprite(int index, int posX, int posY)
{
    //go to the correct location
    gotoxy (index, posX, posY);
    // draw the sprite

    cout << spriteImage[index];

    cursorVisibility(false);
}


void drawEngine::eraseSprite(int index, int posX, int posY)
{
    gotoxy (index, posX, posY);
    cout << ' '; 
}

void drawEngine::setMap(char **data)
{
    map = data;
}

void drawEngine::createBackgroundTile(int index, char c)
{
    if (index >= 0 && index < 16)
    {
        tileImage[index] = c;
    }

}

void drawEngine::drawBackground(void)
{
    if(map)
    {
        for(int y = 0; y < screenHeight; y++)
        {
            gotoxy(0,y, 0);

            for(int x = 0; x < screenWidth; x++)
                cout << tileImage[map[x][y]];

        }
    }
}

void drawEngine::gotoxy(int index, int x, int y)
{
    HANDLE output_handle;
    COORD pos;

    pos.X = x;
    pos.Y = y;

    output_handle = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorPosition(output_handle, pos);
}

void drawEngine::cursorVisibility(bool visibility)
{
    HANDLE output_handle;
    CONSOLE_CURSOR_INFO cciInfo;

    cciInfo.dwSize = 1;
    cciInfo.bVisible = visibility;

    output_handle = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorInfo(output_handle, &cciInfo);
}

绘图引擎.h

#ifndef DRAWENGINE_H
#define DRAWENGINE_H
class drawEngine
{
public:
    drawEngine(int index, int xSize = 30, int ySize = 20, int x = 0, int y = 0);
    ~drawEngine();
    drawEngine(){};

    int createSprite(int index, char c);

    void deleteSprite(int index);
    void eraseSprite(int index, int posX, int posY);

    void createBackgroundTile(int index, char c);

    void drawSprite(int index, int posX, int posY);
    void drawBackground(void);

    void setMap(char **);
protected:
    char **map;
    int screenWidth, screenHeight;
    char spriteImage[16];
    char tileImage[16];
private:


    void gotoxy(int index, int x, int y);
    void cursorVisibility(bool visibility);

};

#endif

如果你需要的话,我还有 Sprite.cpp、Sprite.h、Character.h、Character.cpp 和 main.cpp

4

1 回答 1

0

好的,我通过代码找到了一个问题。该类Runner封装了一个drawEngine对象。在 的构造函数中Runner,调用了默认的 c'tor drawEngine,它不会为sceenWidthand screenHeight(或任何其他成员)设置值。幸运的是,在调试模式下,它们默认0xcccccccc为负数,因此您会drawBackground立即返回(Visual Studio 2010)。
您应该更改该 c'tor (甚至删除它)并在运行器的构造函数中正确初始化引擎,例如:

class Runner {
public: 
    Runner() : drawArea(0, width, height, ?, ?){};
    [...]
};

此外,xandy成员用于 中的循环drawBackground。你应该使用screenWidthand screenWidth,resp。顺便说一句,我不知道 x 和 y 应该是什么drawEngine

更新:gotoxy调用时的 x 和 y 坐标drawBackground混合在一起,因此您将所有内容绘制在同一行上。BTW:是干什么index用的?

于 2011-03-16T09:43:19.873 回答