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