打砖块 文件读取

/**************************
问题分析: 需要做哪些模块
1.  绘制砖块与小球
2.  绘制木板,木板用键盘控制
3.  物理引擎,小球的反射
4.  消除砖块


**********************/

/***********************
基础
    1.创建窗口
    2.基本绘图函数
        2.1 颜色设置
        2.2 画填充矩形和圆
***************/
#include<graphics.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//画砖块地图
int map[5][8]; //描述整个地图
HWND hwnd=NULL;

void initMap()
{
    //给二维数组赋初值,嵌套for循环 i行j列
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<8;j++)
        {
            map[i][j]=rand()%3+1;
        }
    }
    
}
int gameWin()//全局变量map[][]不需要传递参数进来
{
    for(int i=0;i<5;i++)
        for(int j=0;j<8;j++)
        {
            if(map[i][j]!=0)//只要有砖块就不判断为胜利
            {
                return 0;
            }
        }
    return 1;
}
void drawMap()
{
    setlinestyle(PS_SOLID,2,0);
    setlinecolor(WHITE);
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<8;j++)
        {
           int x=100*j;//左上角x坐标
           int y=25*i;//左上角y坐标
            switch(map[i][j])
            {
                case 0: //设定一个0值,留下做方块的消除
                    break;
                case 1:
                    setfillcolor(YELLOW);
                    fillrectangle(x,y,x+100,y+25);
                    break;
                case 2:
                    setfillcolor(LIGHTBLUE);
                    fillrectangle(x,y,x+100,y+25);
                    break;
                case 3:
                    setfillcolor(GREEN);
                    fillrectangle(x,y,x+100,y+25);
                    break;
                    
            }
        }
    }
}
//球
//1.反射

//2.撞击木板,进行范围判断

//3.撞击砖块,进行条件判断
struct Ball
{
    int x;
    int y;
    int r;//半径
    int dx;//x增量
    int dy;
    COLORREF color;
};
//下面的创建函数对着模仿
struct Ball *createBall(int x,int y,int r, int dx, int dy, COLORREF color)
{
    struct Ball *pBall=(struct Ball*)malloc(sizeof(struct Ball));
    pBall->x=x;
    pBall->y=y;
    pBall->r=r;
    pBall->dx=dx;
    pBall->dy=dy;
    pBall->color=color;
    return pBall;
    
}
void drawBall(struct Ball *pBall)
{
    setfillcolor(pBall->color);
    solidcircle(pBall->x,pBall->y,pBall->r);
}

//绘制木板 
struct Board
{
    int x;
    int y;
    int speed;
    COLORREF color;
    int width;
    int height;
};

struct Board* readInfoFromFile(const char *fileName)
{
    struct Board *pBoard=(struct Board*)malloc(sizeof(struct Board));
     FILE *fp=fopen(fileName,"r");//以读的方式
     
    
    while(fscanf(fp,"%d\t%d\t%d\t%s\t%d\t%d\t",&pBoard->x,&pBoard->y,&pBoard->speed,&pBoard->color,&pBoard->width,&pBoard->height)!=EOF)
        //读到这个变量里面去,不做格式控制,当他读到的时候,插入到链表Node里面
    {}
    
    
    fclose(fp);
    return pBoard;
    
    
}

int hitBricks(struct Ball *pBall)
{
    //1.算出球的行和列是属于地图的
    int ballJ=pBall->x/100;
    int ballI=(pBall->y-pBall->r)/25;// 考虑半径
    //2.当前下标下,数组中油不等于0的砖块需要反射,并且重置为0
    if((ballJ<8&&ballI<5)&&map[ballI][ballJ]!=0) //在5行8列里面,并且有砖块
        //
    {
        map[ballI][ballJ]--;//重置为0
        return 1;//返回一个反射的指令
    }
    return 0;
}
//木板的按键操作
//木板的按键操作
void keyDown(struct Board *pBoard)
{
    // C语言的基本函数: scanf(),getch(),getchar(),gets()为主筛函数,先后顺序,不太实用
    //游戏是实时的,我们需要实现异步的按键操作(类似边刷牙边打电话)
    if((GetAsyncKeyState('A')||GetAsyncKeyState(VK_LEFT))&&pBoard->x>=0)//限制边界在大于0
    {
        //按左键,x变小,做减运算
        pBoard->x=pBoard->x-pBoard->speed;
        
    }
    if((GetAsyncKeyState('D')||GetAsyncKeyState(VK_RIGHT))&&pBoard->x<=800-200)//限制边界小于800-200
    {
        pBoard->x=pBoard->x+pBoard->speed;
        
    }
}
void drawBoard(struct Board *pBoard) //传递木板结构体变量指针
{
    setfillcolor(pBoard->color);//封装的函数绘制,尽量传递进入变量
    fillrectangle(pBoard->x,pBoard->y,pBoard->x+pBoard->width,pBoard->y+pBoard->height); //从坐标x,y绘制到 x+宽度,y+高度坐标
}
//先不考虑反射,简单学习入手
int hitBoard(struct Ball *pBall, struct Board *pBoard) //木板和球的参数都需要
{
    if(pBall->y+pBall->r==pBoard->y) //y满足
    {
        if(pBall->x>=pBoard->x&&pBall->x<=pBoard->x+pBoard->width)
            return 1; //表示撞击
    } 
    return 0;
    
    
}
void moveBall(struct Ball *pBall,struct Board *pBoard)
{
    //增加反射
    //左右碰壁
    if(pBall->x-pBall->r<=0||pBall->x+pBall->r>=800) //记录球的半径就是这个作用
        //左右碰壁,x减去半径小于0或者x加上半径大于800
    {
        pBall->dx=-pBall->dx; //左右墙,dx反射
    }
    //上下碰壁
    if(pBall->y-pBall->r<=0||hitBoard(pBall,pBoard)||hitBricks(pBall)) //x坐标改为y坐标就行了,窗口一样大
    {//增加碰砖块消除
        pBall->dy=-pBall->dy; //上下墙,dy反射
    }
    
    pBall->x+=pBall->dx;
    pBall->y+=pBall->dy; // 移动,注意斜着向上运动,x增加,y减小
}
int gameOver(struct Ball *pBall)
{
    if(pBall->y>800-25)
    {return 1;} 
   return 0;
}


int main()
{
    srand((unsigned int)time(0));//设置随机数种子
    initgraph(800,800);  //绘制界面,8行8列,每个砖块是100,所以横向至少800。
    initMap(); //调用初始化二维数组
    
        
    struct Board *pBoard=readInfoFromFile("boardInfor.txt"); //木板初始坐标计算,在底部中心,速度为1,白色,200×25的方块
    //同样的我们创建球与绘制球
    struct Ball *pBall=createBall(400,600,15,5,-5,RED); //球放在中间,大小为15,通过控制dx,dy作为运动矢量来控制球的初始化运动方向
    //相同的代码我们放一起方便观察
    BeginBatchDraw(); //内存中绘制
    while(1)
    {
        cleardevice();
        drawMap();//根据map数组来绘制砖块
        drawBoard(pBoard); //传入 pBoard结构体指针绘制一下木板

        drawBall(pBall);
        moveBall(pBall,pBoard);
        Sleep(10);

        keyDown(pBoard);
        if(gameOver(pBall))
        {
            MessageBox(hwnd,"游戏结束","game over",MB_OK);
            exit(0);
        }
        if(gameWin())
        {
            MessageBox(hwnd,"游戏结束","game win",MB_OK);
            exit(0);

        }
        FlushBatchDraw(); //画一帧,丢弃一帧
    }
    EndBatchDraw();//结束
    closegraph();
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容