OpenGL种子算法生成地图

由于种子寻路的方向是固定的,所以生成的迷宫比较规律。若希望生成更合理的迷宫地图,应该使种子随机向四周进行探索。
下附代码可以实现M*N个格子的迷宫生成。

#include<GL\freeglut.h>
#include<iostream>
#include<ctime>

using namespace std;

void myinit()
{
    // attributes
    glClearColor(1.0, 1.0, 1.0, 1.0);//设置背景颜色
    glColor3f(1.0, 0.0, 0.0);//设置绘画颜色

    // set up viewing
    glMatrixMode(GL_PROJECTION); //当前操作的矩阵为“模型视图矩阵”,GL_PROJECTION表示设置为投影矩阵
    glLoadIdentity(); //把当前矩阵设置为单位矩阵
    gluOrtho2D(0, 1000, 0 , 1000); //设置窗口坐标范围(0.0, 50.0, 0.0, 50.0)-->(0.0, 500, 0.0, 500)
    glMatrixMode(GL_MODELVIEW);
    glPointSize(1);
}

void lineDDA() {
    glBegin(GL_POINTS); //开始绘画,并把每一个点当做顶点来处理
    int randNum = 1;
    clock_t star_time, end_time;
    star_time = clock();
    for (int i = 0; i < randNum; ++i) {
        //int x0 = rand() % 500;
        //int x1 = rand() % 500;
        //int y0 = rand() % 500;
        //int y1 = rand() % 500;
        int x0 = 0, y0 = 0;
        int x1 = 500, y1 = 500;
        int dx = x1 - x0, dy = y1 - y0, step, k;
        float x_inc, y_inc, x = x0, y = y0;
        if (abs(dx) > abs(dy)) step = abs(dx); //此处要加绝对值,否则dx或dy小于0时可能不画
        else step = abs(dy);
        x_inc = float(dx) / step, y_inc = float(dy) / step;
        for (k = 0; k <= step; ++k) {
            glVertex2i(floor(x + 0.5), floor(y + 0.5));
            x += x_inc, y += y_inc;
        }
    }
    glEnd();
    glFlush();//清空缓存
    end_time = clock();
    std::cout << "total time:" << end_time - star_time << std::endl;
}

void lineDDA(int x0, int y0, int x1, int y1) {
    glBegin(GL_POINTS); //开始绘画,并把每一个点当做顶点来处理
    int dx = x1 - x0, dy = y1 - y0, step, k;
    float x_inc, y_inc, x = x0, y = y0;
    if (abs(dx) > abs(dy)) step = abs(dx); //此处要加绝对值,否则dx或dy小于0时可能不画
    else step = abs(dy);
    x_inc = float(dx) / step, y_inc = float(dy) / step;
    for (k = 0; k <= step; ++k) {
        glVertex2i(floor(x + 0.5), floor(y + 0.5));
        x += x_inc, y += y_inc;
    }
    glEnd();
    glFlush();//清空缓存
}


void swap(int& a, int& b) {
    int temp = a;
    a = b; b = temp;
}

int M, N;
int edgelen;
int** reachMatrix;

bool Reach(int x, int y) {//判断是否到达过
    if (x >= M || x < 0 || y >= N || y < 0) return true;
    return reachMatrix[x][y];
};

void Flood_Fill_4(int i, int j)   //(x,y)是种子
{
    reachMatrix[i][j] = 1;
    if (!Reach(i - 1, j)) {//下面能走
        lineDDA(j * edgelen, i * edgelen, (j+1) * edgelen, i * edgelen);
        Flood_Fill_4(i - 1, j);
    }
    if (!Reach(i, j - 1)) {//左边能走
        lineDDA(j * edgelen, i * edgelen, j * edgelen, (i+1) * edgelen);
        Flood_Fill_4(i, j - 1);
    }
    if (!Reach(i + 1, j)) {//上面能走
        lineDDA(j * edgelen, (i + 1) * edgelen, (j + 1) * edgelen, (i + 1) * edgelen);
        Flood_Fill_4(i + 1, j);
    }
    if (!Reach(i, j + 1)) {//右边能走
        lineDDA((j+1) * edgelen, i * edgelen, (j+1) * edgelen, (i + 1) * edgelen);
        Flood_Fill_4(i, j + 1);
    }
}


void maze() {
    edgelen = 40;//设置小方格边长
    M = 20, N = 15;//设置迷宫规格
    reachMatrix = new int* [M];
    for (int i = 0; i < M; ++i) {//0是墙
        reachMatrix[i] = new int[N];
    }
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            reachMatrix[i][j] = 0;
        }
    }
    glColor3f(1.0, 0.0, 0.0);//设置绘画颜色
    for (int i = 0; i <= M; ++i) {//画横线
        lineDDA(0, i * edgelen, N * edgelen, i * edgelen);
    }
    for (int i = 0; i <= N; ++i) {//画竖线
        lineDDA(i * edgelen, 0, i * edgelen, M*edgelen);
    }
    glColor3f(0.0, 0.0, 0.0);//设置绘画颜色
    Flood_Fill_4(8, 8);
    lineDDA(0, M * edgelen, 1*edgelen, M * edgelen);
    lineDDA(N*edgelen, 0, N * edgelen, 1 * edgelen);
}



int main(int argc, char** argv)
{
    glutInit(&argc, argv); //初始化GLUT库
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //选择缓冲区模式和颜色模式
    //glutInitAWindowSize(500, 500) <--是打错了吗?
    glutInitWindowSize(500, 500); //设置窗口大小,(int width, int height),单位是像素
    glutInitWindowPosition(50, 50); //(0,0)是左上角
    glutCreateWindow("Sierpinski Gasket"); //产生一个顶层的窗口.title 作为窗口的名字,也就是窗口标题栏显示的内容
    glutDisplayFunc(lineDDA); //程序会自动调用display函数重绘窗口
    //glutDisplayFunc(lineBresenham);
    glutDisplayFunc(maze);
    myinit();
    glutMainLoop(); //循环执行主函数,并保持窗口不消失;实际操作起来变成每点击一下窗口运行一次glutDisplayFunc
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windrisess

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值