zoukankan      html  css  js  c++  java
  • C/C++编程笔记:C语言实现连连看游戏,小白练手项目(源码分享)

    本篇文章分享看题目就知道是写给初学者的,学的比较好的小伙伴也可以将自动算法等一些知识给加进去,希望对大家有帮助!

    好了,当我们所有的准备工作做好之后,我们就可以来编写我们的C语言连连看游戏了!

    其实这个游戏设计起来真的是很简单的一种,本例用到的知识点主要有:数组,结构体,分支结构,图形库函数。

    游戏效果展示


     
    连连看游戏的效果图大致就是这样(之所以没用本例的,是因为没用图形开发还是有点不好看,嘿嘿~)

    编写准备:编译软件(VS2013),连连看图片素材,easyX图形库插件,有需要可以关注笔者微信公众号:C语言编程学习基地,领取相关图片素材可以回复关键字【连连看】即可。

    那么接下来就给大家展示我们本期的连连看游戏C语言代码,自己写之前,请一定要获取到相关的必备资料哦!不然你就无法根据代码示例写出来了!

    源代码示例

    /*
        课程内容:练练看,很简单
        开发环境:vs2013+easyx图形库
        知识点:
        数组,结构体,分支结构,图形库函数
    */
    #include<stdio.h>
    #include<graphics.h>
    #define IMG_SIZE 39 //隔一个动物图片的宽度
    #define MAX_ANIMAL_NUM 42 //总共的动物数量
    #define MAP_SIZE 10  //每行动物的数量
    #define WIN_SIZE (MAP_SIZE*IMG_SIZE+2*IMG_SIZE)
    
    //定义变量 int  a;
    IMAGE img_total[2];
    IMAGE img_animal[MAX_ANIMAL_NUM][2];
    //地图
    int map[MAP_SIZE+2][MAP_SIZE+2];
    //存储两次点击的数组的下标
    POINT begin = { -1, -1 }, end = { -1, -1 };
    enum STATE
    {
        BEGIN,
        END,
    };
    int flag = BEGIN;
    //游戏初始化
    void GameInit()
    {
        //创建一个图形窗口,贴图片
        initgraph(WIN_SIZE, WIN_SIZE,SHOWCONSOLE);
        //设置随机数种子
        srand(GetTickCount());
        //加载图片,如果现实没有重载的函数,就是字符集的问题
        loadimage(&img_total[0], "./res/animal.bmp");
        loadimage(&img_total[1], "./res/bk.jpg", WIN_SIZE, WIN_SIZE);
        //把整个图片进行分割,保存到新的数组
        SetWorkingImage(&img_total[0]);
        for (int i = 0; i < MAX_ANIMAL_NUM; i++)
        {
            for (int k = 0; k < 2; k++)
            {
                getimage(&img_animal[i][k], k*IMG_SIZE, i*IMG_SIZE, IMG_SIZE, IMG_SIZE);
            }
        }
        SetWorkingImage();
        //11111  222 3333
        //每张图片来10张
        int temp = 1,_count=1;
        for (int i = 1; i <= MAP_SIZE; i++)
        {
            for (int k = 1; k <= MAP_SIZE; k++)
            {
                map[i][k] = temp;
                if (_count % 10 == 0)
                {
                    temp++;
                }
                _count++;
    
            }
        }
        //打乱图片,实际上就是打乱数组数据
        for (int i = 1; i <= MAP_SIZE; i++)
        {
            for (int k = 1; k <= MAP_SIZE; k++)
            {
                int temp=map[i][k];
                int row = rand() % 10 + 1;
                int col = rand() % 10 + 1;
                map[i][k] = map[row][col];
                map[row][col] = temp;
            }
        }
    }
    //游戏的绘制
    void GameDraw()
    {
        putimage(0, 0, &img_total[1]);
        for (int i = 1; i <= MAP_SIZE; i++)
        {
            for (int k = 1; k <= MAP_SIZE; k++)
            {
                if (map[i][k]>0)
                {
                    //用透明贴图,使图片背景透明
                    putimage(k*IMG_SIZE, i*IMG_SIZE, &img_animal[map[i][k]][1],SRCAND);
                    putimage(k*IMG_SIZE, i*IMG_SIZE, &img_animal[map[i][k]][0],SRCPAINT);
                }
            }
        }
        
    }
    //鼠标控制消除,获取鼠标消息
    void GameMouse()
    {
        //检测是否有鼠标操作
        if (MouseHit())
        {
            MOUSEMSG msg = GetMouseMsg();
            if (msg.uMsg == WM_LBUTTONDOWN )
            {
                if (flag==BEGIN)
                {
                    begin.x = msg.y / IMG_SIZE;
                    begin.y = msg.x / IMG_SIZE;
                    flag = END;
                }
                else if (flag == END)
                {
                    end.x = msg.y / IMG_SIZE;
                    end.y = msg.x / IMG_SIZE;
                    flag = BEGIN;
                }
                printf("begin(%d,%d),end(%d,%d)
    ", begin.x, begin.y, end.x, end.y);
            }
        }
    }
    void show()
    {
        for (int i = 0; i <= MAP_SIZE+2; i++)
        {
            for (int k = 0; k <= MAP_SIZE+2; k++)
            {
                printf("%2d ",map[i][k]);
    
            }
            printf("
    ");
        }
    
    }
    //判断某一点是否有图片,没有为0
    int isBlocked(int x,int y)
    {
        return map[x][y];
    }
    //水平方向是否能够消除
    bool horizon(POINT begin, POINT end)
    {
        //不能点击同一个
        if (begin.x == end.x &&begin.y == end.y)
        {
            return false;
        }
        //检测是否在同一水平方向
        if (begin.x != end.x)
        {
            return false;
        }
        //求出大小
        int m_min = min(begin.y, end.y);
        int m_max = max(begin.y, end.y);
        for (int i = m_min + 1; i < m_max; i++)
        {
            if (isBlocked(begin.x, i))
            {
                return false;
            }
        }
        return true;
    }
    //垂直方向是否能够消除
    bool vertical(POINT begin, POINT end)
    {
        //不能点击同一个
        if (begin.x == end.x &&begin.y == end.y)
        {
            return false;
        }
        //检测是否在同一垂直方向
        if (begin.y != end.y)
        {
            return false;
        }
        //求出大小
        int m_min = min(begin.x, end.x);
        int m_max = max(begin.x, end.x);
        for (int i = m_min + 1; i < m_max; i++)
        {
            if (isBlocked(i,begin.y))
            {
                return false;
            }
        }
        return true;
    }
    //一个拐点
    bool turn_ocne(POINT begin, POINT end)
    {
        //不能点击同一个
        if (begin.x == end.x &&begin.y == end.y)
        {
            return false;
        }
        //保存两个拐点信息
        POINT temp1 = { begin.x, end.y }, temp2 = { end.x, begin.y };
        if (!isBlocked(begin.x, end.y))
        {
            if (horizon(begin, temp1) && vertical(end, temp1))
            {
                return true;
            }
    
        }
        if (!isBlocked(end.x, begin.y))
        {
            if (horizon(end, temp2) && vertical(temp2, begin))
            {
                return true;
            }
    
        }
        return false;
    }
    int main()
    {
        GameInit();
        show();
        BeginBatchDraw();
        while (1)
        {
            GameDraw();
            FlushBatchDraw();
            GameMouse();
            //消除操作,消除就是让数组的值等于0
            if (map[begin.x][begin.y] == map[end.x][end.y])
            {
                if (horizon(begin, end))
                {
                    map[begin.x][begin.y] = 0;
                    map[end.x][end.y] = 0;
                }
                else if (vertical(begin, end))
                {
                    map[begin.x][begin.y] = 0;
                    map[end.x][end.y] = 0;
                }
                else if (turn_ocne(begin, end))
                {
                    map[begin.x][begin.y] = 0;
                    map[end.x][end.y] = 0;
                }
    
            }
        }
        return 0;
    }

    以上就是分享给大家的全部的C语言代码,希望能够对大家有帮助~

    自学C/C++编程难度很大,不妨和一些志同道合的小伙伴一起学习成长!

    C语言C++编程学习交流圈子,【点击进入】微信公众号:C语言编程学习基地

    有一些源码和资料分享,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!

  • 相关阅读:
    pyqt信号和槽传递额外参数
    PyQt--QTreeWidget
    转载:futex同步机制详解
    Linux 下的同步机制
    Linux 下线程的理解
    Linux下的物理内存管理2-slab缓存的管理
    转:C语言的编译链接过程的介绍
    LInux中ThreadInfo中的preempt_count字段
    LInux中的物理内存管理
    Linux下的内核抢占
  • 原文地址:https://www.cnblogs.com/yxy6/p/13195491.html
Copyright © 2011-2022 走看看