2048小游戏程序源码

main.c

#include "head.h"

int main(int argc, char const *argv[])
{
    SwipeScreen();

    return 0;
}

work.c

#include "head.h"

int nums[4][4] = {0};
int i, j, n, sum = 0;
//存放所有图片的数组
int lcd_buf[1024 * 600] = {0};

//上移
void move_up()
{
    //向上聚集
    for(j = 0; j < 4; j++)
    {
        for(n = 0; n < 4; n++)
        {
            for(i = 3; i > 0; i--)
            {
                if(nums[i - 1][j] == 0)
                {
                    nums[i - 1][j] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
    //相同数则相加
    for(j = 0; j < 4; j++)
    {
        for(i = 0; i < 3; i++)
        {
            if(nums[i][j] == nums[i + 1][j])
            {
                nums[i][j] += nums[i + 1][j];
                nums[i + 1][j] = 0;
                sum += nums[i][j];
            }
        }
    }
    //向上聚集
    for(j = 0; j < 4; j++)
    {
        for(n = 0; n < 4; n++)
        {
            for(i = 3; i > 0; i--)
            {
                if(nums[i - 1][j] == 0)
                {
                    nums[i - 1][j] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
}

//下移
void move_down()
{
    //向下聚集
    for(j = 0; j < 4; j++)
    {
        for(n = 0; n < 4; n++)
        {
            for(i = 0; i < 3; i++)
            {
                if(nums[i + 1][j] == 0)
                {
                    nums[i + 1][j] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
    //相同数相加
    for(j = 0; j < 4; j++)
    {
        for(i = 3; i > 0; i--)
        {
            if(nums[i][j] == nums[i - 1][j])
            {
                nums[i][j] += nums[i - 1][j];
                nums[i - 1][j] = 0;
                sum += nums[i][j];
            }
        }
    }
    //向下聚集
    for(j = 0; j < 4; j++)
    {
        for(n = 0; n < 4; n++)
        {
            for(i = 0; i < 3; i++)
            {
                if(nums[i + 1][j] == 0)
                {
                    nums[i + 1][j] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
}

//左移
void move_left()
{
    //向左聚集
    for(i = 0; i < 4; i++)
    {
        for(n = 0; n < 4; n++)
        {
            for(j = 3; j > 0; j--)
            {
                if(nums[i][j - 1] == 0)
                {
                    nums[i][j - 1] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
    //相同数相加
    for(i = 0; i < 4; i++)
    {
        for(j = 0; j < 3; j++)
        {
            if(nums[i][j] == nums[i][j + 1])
            {
                nums[i][j] += nums[i][j + 1];
                nums[i][j + 1] = 0;
                sum += nums[i][j];
            }
        }
    }
    //向左聚集
    for(i = 0; i < 4; i++)
    {
        for(n = 0; n < 4; n++)
        {
            for(j = 3; j > 0; j--)
            {
                if(nums[i][j - 1] == 0)
                {
                    nums[i][j - 1] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
}

//右移
void move_right()
{
    //向右聚集
    for(i = 0; i < 4; i++)
    {
        for(n = 0; n < 4; n++)
        {
            for(j = 0; j < 3; j++)
            {
                if(nums[i][j + 1] == 0)
                {
                    nums[i][j + 1] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
    //相同数相加
    for(i = 0; i < 4; i++)
    {
        for(j = 3; j > 0; j--)
        {
            if(nums[i][j] == nums[i][j - 1])
            {
                nums[i][j] += nums[i][j - 1];
                nums[i][j - 1] = 0;
                sum += nums[i][j];
            }
        }
    }
    //向右聚集
    for(i = 0; i < 4; i++)
    {
        for(n = 0; n < 4; n++)
        {
            for(j = 0; j < 3; j++)
            {
                if(nums[i][j + 1] == 0)
                {
                    nums[i][j + 1] = nums[i][j];
                    nums[i][j] = 0;
                }
            }
        }
    }
}

//放图片
void bmp(const char *bmp_path, int n)
{
    // 打开图片
    int bmp_fd = open(bmp_path, O_RDWR);
    if(bmp_fd == -1)
    {
        perror("oopen bmp failed");
        return ;
    }

    // 跳过54字节头信息
    lseek(bmp_fd, 54, SEEK_SET);

    // 读取图片
    char buf[1024 * 600 * 3] = {0};
    read(bmp_fd, buf, sizeof(buf));
    // 关闭图片
    close(bmp_fd);

    //放入全屏图片,如游戏结束game over
    if(n == 0)
    {
        // 将3字节转为4字节
        int i,j;
        int bmp_buf[1024 * 600] = {0};
        for(i = 0, j = 0; i < 1024 * 600; i++,j += 3)
        {
            bmp_buf[i] = buf[j + 0] << 0 | buf[j + 1] << 8 | buf[j + 2] << 16 | 0x0 << 24;
        }

        // 翻转
        int x, y;
        for(y = 0; y < 600; y++)
        {
            for(x = 0; x < 1024; x++)
            {
                lcd_buf[y * 1024 + x] = bmp_buf[(599 - y) * 1024 + x];
            }
        }
    }
    
    //1/16图片
    else
    {
        // 将3字节转为4字节
        int i,j;
        int bmp_buf[256 * 150] = {0};
        for(i = 0, j = 0; i < 256 * 150; i++,j += 3)
        {
            bmp_buf[i] = buf[j + 0] << 0 | buf[j + 1] << 8 | buf[j + 2] << 16 | 0x0 << 24;
        }

        // 翻转
        int x, y;
        for(y = 0; y < 150; y++)
        {
            for(x = 0; x < 256; x++)
            {
                lcd_buf[y * 1024 + x + 1024 * ((n - 1) / 4) * 150 + 256 * ((n - 1) % 4)] = bmp_buf[(149 - y) * 256 + x];
            }
        }
    }

}

//映射
void show_bmp()
{
    // 打开lcd
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if(lcd_fd == -1)
    {
        perror("open lcd failed:");
        return ;
    }

    // lcd映射
    int *lcd_ptr = mmap(NULL, 
                        1024*600*4, 
                        PROT_READ|PROT_WRITE, 
                        MAP_SHARED,
                        lcd_fd,
                        0 );
    if(lcd_ptr == NULL)
    {
        perror("mmap failed:");
        return ;
    }
    //黑色
    int black = 0x00000000;

    //全屏显示黑色
    int x, y;
    for(y = 0; y < 600; y++)
    {
        for(x = 0; x < 1024; x++)
        {
            lcd_ptr[y * 1024 + x] = black;
        }
    }

    //显示图片
    for(y = 0; y < 600; y++)
    {
        for(x = 0; x < 1024; x++)
        {
            lcd_ptr[y * 1024 + x] = lcd_buf[y * 1024 + x];
        }
    }
    
}

//清屏
void clear()
{
    // 打开lcd
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if(lcd_fd == -1)
    {
        perror("open lcd failed:");
        return ;
    }

    // lcd映射
    int *lcd_ptr = mmap(NULL, 
                        1024*600*4, 
                        PROT_READ|PROT_WRITE, 
                        MAP_SHARED,
                        lcd_fd,
                        0 );
    if(lcd_ptr == NULL)
    {
        perror("mmap failed:");
        return ;
    }
    //黑色
    int black = 0x00000000;

    //全屏显示黑色
    int x, y;
    for(y = 0; y < 600; y++)
    {
        for(x = 0; x < 1024; x++)
        {
            lcd_ptr[y * 1024 + x] = black;
        }
    }
}

//随机位置
void rand_nums()
{
    //对坐标在0-3随机取值
    int x = rand() % 4, y = rand() % 4;
    //一直找,找到值为0的位置为止
    while(nums[x][y] != 0)
    {
        //继续取值
        x = rand() % 4;
        y = rand() % 4;
    }
    //对随机空白位置赋2
    nums[x][y] = 2;
}

//选择对应位置放图片
void choose()
{
    //遍历数组16个数字,放对应的图片
    for(i = 0; i < 4; i++)
    {
        for(j = 0; j < 4; j++)
        {
            switch(nums[i][j])
            {
                case 1:
                    bmp("./1.bmp", i * 4 + j + 1);
                    break;
                case 2:
                    bmp("./2.bmp", i * 4 + j + 1);
                    break;
                case 4:
                    bmp("./4.bmp", i * 4 + j + 1);
                    break;
                case 8:
                    bmp("./8.bmp", i * 4 + j + 1);
                    break;
                case 16:
                    bmp("./16.bmp", i * 4 + j + 1);
                    break;
                case 32:
                    bmp("./32.bmp", i * 4 + j + 1);
                    break;
                case 64:
                    bmp("./64.bmp", i * 4 + j + 1);
                    break;
                case 128:
                    bmp("./128.bmp", i * 4 + j + 1);
                    break;
                case 256:
                    bmp("./256.bmp", i * 4 + j + 1);
                    break;
                case 512:
                    bmp("./512.bmp", i * 4 + j + 1);
                    break;
                case 1024:
                    bmp("./1024.bmp", i * 4 + j + 1);
                    break;
                case 2048:
                    bmp("./2048.bmp", i * 4 + j + 1);
                    break;
                case 4096:
                    bmp("./4096.bmp", i * 4 + j + 1);
                    break;
            }
        }
    }
}

bool strat()
{
    // 打开文件
    int lcd_fd = open("/dev/fb0",O_RDWR);
    if(lcd_fd == -1)
    {
        perror("open file failed\n");
        return false;
    }

    int bmp_fd = open("./start.bmp",O_RDWR);
    if(bmp_fd == -1)
    {
        perror("open bmp failed\n");
        return false;
    }
// 内存映射
    int *p = mmap(NULL, 
                    600*1024*4, 
                    PROT_READ|PROT_WRITE,
                    MAP_SHARED, lcd_fd, 0);
// 偏移54字节
    lseek(bmp_fd,54,SEEK_SET);

    char bmp_buf[1024*600*3] = {0};
// 读取数据
    read(bmp_fd,bmp_buf,sizeof(bmp_buf));

// 将三字节的bmp数据转为四字节的bmp数据
    int bmp[1024*600] = {0};
    int i,j;
    for(i = 0,j = 0;i < 1024*600;i++,j+=3)
    {
        bmp[i] = bmp_buf[0+j] << 0 
        | bmp_buf[1+j] << 8 
        | bmp_buf[2+j] << 16 
        | 0x0 << 0;
    }

	int m,n;
	for(n = 0; n < 600; n++)
	{
		for(m = 0; m < 1024; m++)
		{
            p[n*1024+m] = bmp[(599-n)*1024+m];    
		}
	}

    munmap(p,1024*600*4);

// 关闭文件
    close(lcd_fd);
    close(bmp_fd);

    return true;
}

//滑屏
int SwipeScreen()
{
    //清屏
    clear();
    // 放置开始界面
    strat();
    sleep(3);
    //随机赋值
    rand_nums();
    //放图片
    choose();
    //映射
    show_bmp();
    
    int ts_x,ts_y;
    // 阻塞打开触摸屏设备
    int ts_fd = open("/dev/input/event1", O_RDWR);
    if(ts_fd == -1)
    {
        perror("open ts failed:");
        return -1;
    }

    struct input_event ts_event = {0};
    // 循环读取事件
    
    int time = 0;
    int x0, y0, x1, y1;
    while(1)
    {
        read(ts_fd, &ts_event, sizeof(ts_event));
        //给坐标
        if(ts_event.type == EV_ABS && ts_event.code == ABS_MT_POSITION_X)
        {
            ts_x = ts_event.value;
        }
        if(ts_event.type == EV_ABS && ts_event.code == ABS_MT_POSITION_Y)
        {
            ts_y = ts_event.value;
        }

        //判断是否连续,x占一次,y占一次,一次点击,所以应大于3次判定为连续
        if(time <= 3)
        {
            x0 = ts_x;
            y0 = ts_y;
            time++;
        }
        
        // 判断持续事件,并且连续事件结束后打印坐标值
        if(ts_event.type == EV_SYN && ts_event.code == SYN_REPORT)
        {
            printf("(%d,%d)\n",ts_x,ts_y);
        }
        
        //松手
        if(ts_event.code == ABS_MT_TRACKING_ID && ts_event.value == -1)
        {
            x1 = ts_x;
            y1 = ts_y;
            //存当前数组元素
            int nums1[4][4] = {0};
            for(i = 0; i < 4; i++)
            {
                for(j = 0; j < 4; j++)
                {
                    nums1[i][j] = nums[i][j];
                }
            }

            //横向位移大于纵向位移
            if(abs(x1 - x0) >= abs(y1 - y0))
            {
                //右滑
                if(x1 >= x0)
                {
                    //右移
                    move_right();
                }
                //左滑
                else
                {
                    //左移
                    move_left();
                }
            }
            //纵向位移大于横向位移
            else
            {
                //下滑
                if(y1 >= y0)
                {
                    //下移
                    move_down();
                }
                //上滑
                else
                {
                    //上移
                    move_up();
                }
            }
            //清屏
            clear();
            
            //判断新旧数组是否没变
            int change_times = 0;   //数组元素改变的次数
            int if_full = 0;        //数组元素为0的次数
            for(i = 0; i < 4; i++)
            {
                for(j = 0; j < 4; j++)
                {
                    if(nums1[i][j] != nums[i][j])
                    {
                        change_times++;
                    }
                    if(nums[i][j] == 0)
                    {
                        if_full++;
                    }
                }
            }
            //改变次数不为0,说明有变化
            if(change_times != 0)
            { 
                //随机生成
                rand_nums();
            }
            //改变次数为0,数组没变
            else
            {
                //数组没有为0的位置
                if(if_full == 0)
                {
                    //清屏
                    clear();
                    //清空图片数组
                    for(j = 0; j < 600; j++)
                    {
                        for(i = 0; i < 1024; i++)
                        {
                            lcd_buf[j * 1024 + i] = 0;
                        }
                    }
                    //放入game over图片
                    bmp("./end.bmp", 0);
                    //映射
                    show_bmp();
                    //程序结束
                    break;
                }
            }
            //清空图片数组
            for(j = 0; j < 600; j++)
            {
                for(i = 0; i < 1024; i++)
                {
                    lcd_buf[j * 1024 + i] = 0;
                }
            }
            //放图片
            choose();
            //映射
            show_bmp();
            //判断滑屏连续次数清零
            time = 0;
            //初始坐标清零
            x0 = 0;
            y0 = 0;
            //数组改变次数清零
            change_times = 0;
            //数组为0次数清零
            if_full = 0;
        }
         
    }
    // 关闭ts
    close(ts_fd);

    return 0;
}

head.h

#ifndef _HEAD_H
#define _HEAD_H

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <linux/input.h>

//向上
void move_up();

//向下
void move_down();

//左移
void move_left();

//右移
void move_right();

bool start();

//放图片
void bmp(const char *bmp_path, int n);

//映射
void show_bmp();

//清屏
void clear();

//随机位置
void rand_nums();

//选择对应位置放图片
void choose();

//滑屏
int SwipeScreen();




#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值