tool.hpp
#pragma once #includevoid drawImg(int x, int y,IMAGE *src) { // 变量初始化 DWORD* pwin = GetImageBuffer(); //窗口缓冲区指针 DWORD* psrc = GetImageBuffer(src); //图片缓冲区指针 int win_w = getwidth(); //窗口宽高 int win_h = getheight(); int src_w = src->getwidth(); //图片宽高 int src_h = src->getheight(); // 计算贴图的实际长宽 int real_w = (x + src_w > win_w) ? win_w - x : src_w; // 处理超出右边界 int real_h = (y + src_h > win_h) ? win_h - y : src_h; // 处理超出下边界 if (x < 0) { psrc += -x; real_w -= -x; x = 0; } // 处理超出左边界 if (y < 0) { psrc += (src_w * -y); real_h -= -y; y = 0; } // 处理超出上边界 // 修正贴图起始位置 pwin += (win_w * y + x); // 实现透明贴图 for (int iy = 0; iy < real_h; iy++) { for (int ix = 0; ix < real_w; ix++) { //计算透明通道的值[0,256) 0为完全透明 255为完全不透明 byte a = (byte)(psrc[ix] >> 24); if (a > 100) { pwin[ix] = psrc[ix]; } } //换到下一行 pwin += win_w; psrc += src_w; } } void drawImg(int x, int y, int dstW, int dstH, IMAGE* src, int srcX, int srcY) { // 变量初始化 DWORD* pwin = GetImageBuffer(); //窗口缓冲区指针 DWORD* psrc = GetImageBuffer(src); //图片缓冲区指针 int win_w = getwidth(); //窗口宽高 int win_h = getheight(); int src_w = src->getwidth(); //图片宽高 int src_h = src->getheight(); // 计算贴图的实际长宽 int real_w = (x + dstW > win_w) ? win_w - x : dstW; // 处理超出右边界 int real_h = (y + dstH > win_h) ? win_h - y : dstH; // 处理超出下边界 if (x < 0) { psrc += -x; real_w -= -x; x = 0; } // 处理超出左边界 if (y < 0) { psrc += (dstW * -y); real_h -= -y; y = 0; } // 处理超出上边界 //printf("realw,h(%d,%d)n", real_w, real_h); // 修正贴图起始位置 pwin += (win_w * y + x); // 实现透明贴图 for (int iy = 0; iy < real_h; iy++) { for (int ix = 0; ix < real_w; ix++) { //计算透明通道的值[0,256) 0为完全透明 255为完全不透明 byte a = (byte)(psrc[ix + srcX + srcY * src_w] >> 24); if (a > 100) { pwin[ix] = psrc[ix + srcX + srcY * src_w]; } } //换到下一行 pwin += win_w; psrc += src_w; } }
源.cpp
#include#include #include #include #include #include #include"tools.hpp" #define ROW 4 #define COL 4 #define INTERVAL 15 //格子间的间隔 #define GRID_SIZE 117 //格子的宽度和高度 //38 * 195 IMAGE bk; //背景 //存储数据的数组 int map[ROW][COL]; int flag = 0; //是否生成一个数字 //定义图片资源 IMAGE imgs[11]; //特殊处理空白图片 IMAGE zero; void loadResource() { loadimage(&bk, "./pieces/bk.png", 584, 734); loadimage(&zero, "./pieces/0.png", GRID_SIZE, GRID_SIZE); for (int i = 2,j = 0; i <= 2048; i *= 2,j++) { char imgPath[50] = { 0 }; //字符串格式化 sprintf_s(imgPath, "./pieces/%d.png", i); //缓冲区(数组) 格式字符串 for (int i = 0; i < 17; i++) //字符数组必须要用for循环做打印|不能用"%s"的方式打印 { printf("%c", imgPath[i]); } putchar('n'); //注意: 图片要一个挨着一个输出 loadimage(&imgs[j], imgPath, GRID_SIZE, GRID_SIZE); //多字节字符集 } } //随机产生2or4 2的概率更高 int createNumber() { if (rand() % 10 != 0) { return 2; } else { return 4; } } //给数组空白处填充一个数 void mapFillNumber() { //随机产生两个下标 while (true) { //多次产生下标的时候,可能会重复 0 1 0 1 虽然概率比较小但还是有可能 int r = rand() % ROW; //0 1 2 3 int c = rand() % COL; //0 1 2 3 //避免出现问题 首先判断原来位置是不是等于 0 如果等于 0 才放入数据 if (map[r][c] == 0) { map[r][c] = createNumber(); return; } } } //初始化 void init() { //设置随机数种子 srand(time(NULL)); //随机产生一个数,并且放到数组里面去 map[?][?] = createNumber(); for (int i = 0; i < 2; i++) { mapFillNumber(); } } //绘制 void draw() { for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { //把每个格子左上角的坐标求出来 int x = k * GRID_SIZE + (k + 1) * INTERVAL + 38-18; int y = i * GRID_SIZE + (i + 1) * INTERVAL + 195-17; switch (map[i][k]) { case 0: drawImg(x, y, &zero); break; case 2: drawImg(x, y, &imgs[0]); break; case 4: drawImg(x, y, &imgs[1]); break; case 8: drawImg(x, y, &imgs[2]); break; case 16: drawImg(x, y, &imgs[3]); break; case 32: drawImg(x, y, &imgs[4]); break; case 64: drawImg(x, y, &imgs[5]); break; case 128: drawImg(x, y, &imgs[6]); break; case 256: drawImg(x, y, &imgs[7]); break; case 512: drawImg(x, y, &imgs[8]); break; case 1024: drawImg(x, y, &imgs[9]); break; case 2048: drawImg(x, y, &imgs[10]); break; } } printf("n"); } } //向上移动 void moveUp() { for (int i = 0; i < COL; i++) { int temp = 0; for (int begin = 1; begin < ROW; begin++) { if (map[begin][i] != 0) { if (map[temp][i] == 0) { map[temp][i] = map[begin][i]; map[begin][i] = 0; } else if (map[temp][i] == map[begin][i]) { map[temp][i] += map[begin][i]; map[begin][i] = 0; temp++; } else { map[temp + 1][i] = map[begin][i]; if (temp + 1 != begin)//如果temp+1和begn不在同一个位置,就让begin所在的位置的数字置空 { map[begin][i] = 0; } temp++; } flag = 1; } } } } //向下移动 void moveDown() { for (int i = 0; i < COL; i++) { int temp = ROW - 1; for (int begin = ROW - 2; begin >= 0; begin--) { if (map[begin][i] != 0) { if (map[temp][i] == 0) { map[temp][i] = map[begin][i]; map[begin][i] = 0; } else if (map[temp][i] == map[begin][i]) { map[temp][i] += map[begin][i]; map[begin][i] = 0; temp--; } else { map[temp - 1][i] = map[begin][i]; if ((temp - 1) != begin) { map[begin][i] = 0; } temp--; } flag = 1; } } } } //向左移动 void moveLeft() { for (int i = 0; i < COL; i++) { int temp = 0; for (int begin = 1; begin < ROW; begin++) { if (map[i][begin] != 0) { if (map[i][temp] == 0) { map[i][temp] = map[i][begin]; map[i][begin] = 0;; } else if (map[i][temp] == map[i][begin]) { map[i][temp] += map[i][begin]; map[i][begin] = 0; temp++; } else { map[i][temp + 1] = map[i][begin]; if (temp + 1 != begin) { map[i][begin] = 0; } temp++; } flag = 1; } } } } //向右移动 void moveRight() { for (int i = 0; i < ROW; i++) { int temp = COL - 1; for (int begin = COL - 2; begin >= 0; begin--) { if (map[i][begin] != 0) { if (map[i][temp] == 0) { map[i][temp] = map[i][begin]; map[i][begin] = 0; } else if (map[i][temp] == map[i][begin]) { map[i][temp] += map[i][begin]; map[i][begin] = 0; temp--; } else { map[i][temp - 1] = map[i][begin]; if (temp - 1 != begin) { map[i][begin] = 0; } temp--; } flag = 1; } } } } //移动格子 void move() { //获取键盘按键 72 80 75 77 int key = _getch(); switch (key) { case 'W': case 'w': case 72: moveUp(); break; case 80: moveDown(); break; case 75: moveLeft(); break; case 77: moveRight(); break; } if (flag == 1) { mapFillNumber(); flag = 0; } } int main() { //窗口 initgraph(584,734, EW_SHOWCONSOLE); init(); loadResource(); drawImg(0, 0, &bk); while (true) { draw(); move(); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%d", map[i][j]); } printf("n"); } } getchar(); return 0; }



