C++在游戏领域应用很广,其最大有点是运行效率高,对内存的操作比较直接,因此,我利用此有点写了中国象棋的简洁版,来进行一些简单的下棋操作。接下来是代码
#ifndef PUTTEXT_H_#define PUTTEXT_H_#include <windows.h>#include <string>#include <opencv2/opencv.hpp>using namespace cv;void GetStringSize(HDC hDC, const char* str, int* w, int* h);void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize,const char *fn = "Arial", bool italic = false, bool underline = false);#endif
这是头文件,包含用来处理汉字的一些函数,(opencv不可以直接处理汉字)
接下来便是具体实现过程了
#include<opencv2/opencv.hpp>#include<highgui.hpp>#include<imgcodecs.hpp>#include<core.hpp>#include<imgproc.hpp>#include"标头.h"#include<vector>#include<iostream>#include<math.h>using namespace cv;using namespace std;static Point NoCor;//未修正的坐标static Point Cor;//修正后的坐标static bool Select;//是否被选中int count = 0;//回合次数int Piece;//判断黑白双方int Type;//棋子种类int Corx;//修正后的横坐标int Cory;//修正后的纵坐标int NUM1;int NUM2;static bool Lar;vector<int>INFO{1100,1210,1420,1530,1740,1550,1460,1270,1180,1312,1372,1903,1923,1943,1963,1983,2606,2626,2646,2666,2686,2317,2377,2109,2219,2829,2539,2049,2559,2869,2279,2189 }; //储存棋子的信息,第一位为黑白方判断,第二位为棋子种类,第三位第四位分别为横纵坐标static vector<int>Help(90);//辅助数组,判断该处是否有棋子,并且判断是否可以落子static vector<Point>Judge{Point(0,0),Point(0,0) };//判断class Chess{public:static void Onmouse(int event, int x, int y, int flags, void* userdata);//鼠标事件Chess();~Chess();Point FixCor(Point &NoCor);//鼠标修正函数vector<int> Help;//储存落子的信息};class Chessboard{public:friend Chess;Chessboard();~Chessboard();Mat chessboard;void inichessboard();//初始化棋盘private:int x = 60;int y = 40;int z = 140;};Chessboard::Chessboard(){Mat chessboard = Mat(800, 800, CV_8UC3, Scalar(145, 197, 238));for (int i = 0; i <= 9; i++){line(chessboard, Point(60, y), Point(700, y), Scalar(0, 0, 0), 2);y += 80;}for (int i = 0; i < 9; i++){line(chessboard, Point(x, 40), Point(x, 760), Scalar(0, 0, 0), 2);x += 80;}for (int i = 0; i < 7; i++){line(chessboard, Point(z, 361), Point(z, 439), Scalar(145, 197, 238), 2);z += 80;}line(chessboard, Point(50, 30), Point(710, 30), Scalar(0, 0, 0), 3);line(chessboard, Point(50, 770), Point(710, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(50, 30), Point(50, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(710, 30), Point(710, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(300, 40), Point(460, 200), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 200), Point(460, 40), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 760), Point(460, 600), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 600), Point(460, 760), Scalar(0, 0, 0), 2);putTextZH(chessboard, "楚河", Point(180, 380), (0, 0, 0), 50, "楷体", false, false);putTextZH(chessboard, "汉界", Point(480, 380), (0, 0, 0), 50, "楷体", false, false);for (int i = 0; i < 32; i++){if (INFO[i] > 1000){Piece = INFO[i] / 1000;Type = (INFO[i] - 1000 * Piece) / 100;Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;Point CornC,CornW;/*棋子显示位置*/CornC.x = 60 + 80 * Corx;CornC.y = 40 + 80 * Cory;/*文字显示位置*/CornW.x = CornC.x - 20;CornW.y = CornC.y - 20;circle(chessboard, CornC, 40, Scalar(75, 125, 177), -1, 8, 0);switch (Type){case 0:putTextZH(chessboard, "帅", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;case 1:if (Piece==1){putTextZH(chessboard, "车", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;}else{putTextZH(chessboard, "车", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;}case 2:if (Piece == 1){putTextZH(chessboard, "马", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;}else if (Piece==2){putTextZH(chessboard, "马", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;}case 3:if (Piece == 1){putTextZH(chessboard, "炮", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;}else{putTextZH(chessboard, "炮", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;}case 4:putTextZH(chessboard, "象", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;case 5:if (Piece == 1){putTextZH(chessboard, "士", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;}else{putTextZH(chessboard, "士", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;}case 6:putTextZH(chessboard, "兵", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;case 7:putTextZH(chessboard, "将", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;case 8:putTextZH(chessboard, "相", CornW, Scalar(0, 0, 255), 50, "楷体", false, false);break;case 9:putTextZH(chessboard, "卒", CornW, Scalar(0, 0, 0), 50, "楷体", false, false);break;}}}imshow("Playchess", chessboard);}Chessboard::~Chessboard(){}void Chessboard::inichessboard(){for (int i = 0; i <= 9; i++){line(chessboard, Point(60, y), Point(700, y), Scalar(0, 0, 0), 2);y += 80;}for (int i = 0; i < 9; i++){line(chessboard, Point(x, 40), Point(x, 760), Scalar(0, 0, 0), 2);x += 80;}for (int i = 0; i < 7; i++){line(chessboard, Point(z, 361), Point(z, 439), Scalar(145, 197, 238), 2);z += 80;}line(chessboard, Point(50, 30), Point(710, 30), Scalar(0, 0, 0), 3);line(chessboard, Point(50, 770), Point(710, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(50, 30), Point(50, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(710, 30), Point(710, 770), Scalar(0, 0, 0), 3);line(chessboard, Point(300, 40), Point(460, 200), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 200), Point(460, 40), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 760), Point(460, 600), Scalar(0, 0, 0), 2);line(chessboard, Point(300, 600), Point(460, 760), Scalar(0, 0, 0), 2);}Chess::Chess(){setMouseCallback("Playchess", Onmouse, NULL);Chessboard CB;vector<int>Help(90);for (int k = 0; k < 9; k++){Help[k] = 1;}for (int i = 81; i < 90; i++){Help[i] = 2;}Help[19] = 1;Help[25] = 1;Help[27] = 1;Help[29] = 1;Help[31] = 1;Help[33] = 1;Help[35] = 1;Help[54] = 2;Help[56] = 2;Help[58] = 2;Help[60] = 2;Help[62] = 2;Help[64] = 2;Help[70] = 2;int Fabsx, Fabsy;Point Circle;if (Lar==true){for (int i = 0; i < INFO.size(); i++){int EYE,leg1,leg2;EYE = (Judge[0].x + Judge[1].x) / 2 + 9 * (Judge[0].y + Judge[1].y) / 2;leg1 = (Judge[0].x + Judge[1].x) / 2 + 9 * Judge[0].y;leg2 = Judge[0].x + 9 * (Judge[0].y + Judge[1].y) / 2;cout << leg2 << endl;cout << Help[leg2] << endl;Piece = INFO[i] / 1000;Type = (INFO[i] - 1000 * Piece) / 100;Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;Fabsx = abs(Judge[1].x - Judge[0].x);Fabsy = abs(Judge[1].y - Judge[0].y);NUM1 = Judge[0].x + 9 * Judge[0].y;NUM2 = Judge[1].x + 9 * Judge[1].y;if (Corx == Judge[0].x&&Cory == Judge[0].y){switch (Type){case 7:if (Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 3 && (Fabsx + Fabsy) == 1){if (Help[NUM2] == 0){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}case 0:if (Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 10&&Judge.back().y>6 && (Fabsx + Fabsy) == 1){if (Help[NUM2]==0){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}case 6:if ((Fabsx + Fabsy) == 1){if ((Help[NUM2]+Help[NUM1])==3){INFO[i] = 1000*Piece+100 * Type + 10 * Judge.back().x + Judge.back().y; //ChangeHelp[NUM1] = 0;Help[NUM2] = 2;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if ((Corx==Judge[1].x)&&(Cory==Judge[1].y)){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;Help[NUM1] = 0;Help[NUM2] = 2;break;}}case 9:if ((Fabsx + Fabsy) == 1){if ((Help[NUM2] + Help[NUM1])==3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y; //ChangeHelp[NUM1] = 0;Help[NUM2] = Piece;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;Help[NUM1] = 0;Help[NUM2] = 2;break;}}case 1:if (Judge[1].y==Judge[0].y){int count = 0;int k = Judge[0].x > Judge[1].x ? Judge[0].x : Judge[1].x;for (k ; k < fabs(Judge[1].x-Judge[0].x); k++){if (Help[k]!=0){count++;}}if (count==0){if (Help[NUM1] == Help[NUM2]){break;}else if (Help[NUM2] != Help[NUM1]&&Help[NUM2!=0&&Help[NUM1]!=0]){for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}}if (Judge[1].x == Judge[0].x){int count = 0;int k = Judge[0].y > Judge[1].y ? Judge[0].y : Judge[1].y;for (k; k < fabs(Judge[1].y - Judge[0].y); k++){if (Help[k] != 0){k+=8;count++;}}if (count == 0){if (Help[NUM1] == Help[NUM2]){break;}else if ((Help[NUM2] + Help[NUM1])==3){for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}}case 3:if (Judge[1].y == Judge[0].y){int count = 0;int k = Judge[0].x > Judge[1].x ? Judge[0].x : Judge[1].x;for (k; k < fabs(Judge[1].x - Judge[0].x); k++){if (Help[k] != 0){count++;}}if (count == 0){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}if (count == 1){if (Help[NUM1] == Help[NUM2]){break;}else if ((Help[NUM1] + Help[NUM2]) == 2){for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;Help[NUM2] = Help[NUM1];Help[NUM1] = 0;break;}}}}}if (Judge[1].x == Judge[0].x){int count = 0;int k = Judge[0].y > Judge[1].y ? Judge[0].y : Judge[1].y;for (k; k < fabs(Judge[1].y - Judge[0].y); k++){if (Help[k] != 0){k += 8;count++;}}if (count == 0){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = 1;break;}if (count==1){if (Help[NUM1] == Help[NUM2]){break;}if ((Help[NUM1]+Help[NUM2])==3){for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){Help[NUM2] = Help[NUM1];Help[NUM1] = 0;INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}}}case 5:if ((Fabsx+Fabsy)==2&&Fabsx==Fabsy){if (Piece==1&& Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}if (Piece==2&&Judge.back().x < 6 && Judge.back().x>2 && Judge.back().y < 10 && Judge.back().y>6){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;Help[NUM1] = 0;Help[NUM2] = 1;break;}}case 2:if ((Fabsx+Fabsy)==3){if (Fabsx==2){if (Help[leg1] == 0){if ((Help[NUM1] + Help[NUM2]) == 3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge.back().x&&Cory == Judge.back().y){INFO[k] = 100 * Type + 10 * Corx + Cory;Help[NUM2] = Help[NUM1];Help[NUM1] = 0;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;cout << INFO[i] << endl;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}}if (Fabsy==2){if (Help[leg2]==0){if ((Help[NUM1] + Help[NUM2]) == 3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;Help[NUM2] = Help[NUM1];Help[NUM1] = 0;break;}}}else{INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;cout << INFO[i] << endl;Circle.x = 60 + 80 * Judge[1].x;Circle.y = 40 + 80 * Judge[1].y;Help[NUM1] = 0;Help[NUM2] = Piece;break;}}}}case 4:if (Fabsx==2&&Fabsy==2&&Help[EYE]==0){if (Help[NUM1] == Help[NUM2]){break;}if ((Help[NUM1] + Help[NUM2]) == 3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y; //ChangeHelp[NUM1] = 0;Help[NUM2] = 1;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;Help[NUM1] = 0;Help[NUM2] = 1;break;}case 8:if (Fabsx == 2 && Fabsy == 2 && Help[EYE] == 0){if ((Help[NUM1] + Help[NUM2]) == 3){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge[1].x + Judge[1].y; //ChangeHelp[NUM1] = 0;Help[NUM2] = 2;for (int k = 0; k < INFO.size(); k++){Piece = INFO[k] / 1000;Type = (INFO[k] - 1000 * Piece) / 100;Corx = (INFO[k] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[k] - 1000 * Piece - 100 * Type - 10 * Corx;if (Corx == Judge[1].x&&Cory == Judge[1].y){INFO[k] = 100 * Type + 10 * Corx + Cory;break;}}}if (Help[NUM2] == 0){INFO[i] = 1000 * Piece + 100 * Type + 10 * Judge.back().x + Judge.back().y;Help[NUM1] = 0;Help[NUM2] = 2;;break;}}}Select = false;Lar = false;if (INFO[4]<1000){exit(0);cout << "红方胜利" << endl;}if (INFO[27]<1000){exit(0);cout << "黑方胜利" << endl;}break;}}}}Chess::~Chess(){}Point Chess::FixCor(Point &NoCor){int m, n;m = (NoCor.x - 60) % 80;n = (NoCor.y - 40) % 80;if (m <= 40){Cor.x = (NoCor.x - m - 60) / 80;}else{Cor.x = (NoCor.x - m + 20) / 80;}if (n <= 40){Cor.y = (NoCor.y - n - 40) / 80;}else{Cor.y = (NoCor.y - n + 40) / 80;}return Cor;}void Chess::Onmouse(int event, int x, int y, int flags, void* userdata){if (event==EVENT_LBUTTONDOWN){Chess *p = new Chess();if (Select == true && Lar == false){NoCor.x = x;NoCor.y = y;Cor = p->FixCor(NoCor);Judge[1] = Cor;Lar = true;}if (Lar == false && Select == false){NoCor.x = x;NoCor.y = y;Cor = p->FixCor(NoCor);for (int i = 0; i < INFO.size(); i++){Piece = INFO[i] / 1000;Type = (INFO[i] - 1000 * Piece) / 100;Corx = (INFO[i] - 1000 * Piece - 100 * Type) / 10;Cory = INFO[i] - 1000 * Piece - 100 * Type - 10 * Corx;if (Cor.x == Corx && Cor.y == Cory){Judge[0] = Cor;cout << "Select==false" << endl;Select = true;break;}}}}if (event==EVENT_RBUTTONDOWN){Select = false;Lar = false;}}static void GetStringSize(HDC hDC, const char* str, int* w, int* h){SIZE size;GetTextExtentPoint32A(hDC, str, strlen(str), &size);if (w != 0) *w = size.cx;if (h != 0) *h = size.cy;}static void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline){CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));int x, y, r, b;if (org.x > dst.cols || org.y > dst.rows) return;x = org.x < 0 ? -org.x : 0;y = org.y < 0 ? -org.y : 0;LOGFONTA lf;lf.lfHeight = -fontSize;lf.lfWidth = 0;lf.lfEscapement = 0;lf.lfOrientation = 0;lf.lfWeight = 5;lf.lfItalic = italic; //斜体lf.lfUnderline = underline; //下划线lf.lfStrikeOut = 0;lf.lfCharSet = DEFAULT_CHARSET;lf.lfOutPrecision = 0;lf.lfClipPrecision = 0;lf.lfQuality = PROOF_QUALITY;lf.lfPitchAndFamily = 0;strcpy_s(lf.lfFaceName, fn);HFONT hf = CreateFontIndirectA(&lf);HDC hDC = CreateCompatibleDC(0);HFONT hOldFont = (HFONT)SelectObject(hDC, hf);int strBaseW = 0, strBaseH = 0;int singleRow = 0;char buf[1 << 12];strcpy_s(buf, str);char *bufT[1 << 12]; // 这个用于分隔字符串后剩余的字符,可能会超出。//处理多行{int nnh = 0;int cw, ch;const char* ln = strtok_s(buf, "\n", bufT);while (ln != 0){GetStringSize(hDC, ln, &cw, &ch);strBaseW = max(strBaseW, cw);strBaseH = max(strBaseH, ch);ln = strtok_s(0, "\n", bufT);nnh++;}singleRow = strBaseH;strBaseH *= nnh;}if (org.x + strBaseW < 0 || org.y + strBaseH < 0){SelectObject(hDC, hOldFont);DeleteObject(hf);DeleteObject(hDC);return;}r = org.x + strBaseW > dst.cols ? dst.cols - org.x - 1 : strBaseW - 1;b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;org.x = org.x < 0 ? 0 : org.x;org.y = org.y < 0 ? 0 : org.y;BITMAPINFO bmp = {0 };BITMAPINFOHEADER& bih = bmp.bmiHeader;int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));bih.biSize = sizeof(BITMAPINFOHEADER);bih.biWidth = strBaseW;bih.biHeight = strBaseH;bih.biPlanes = 1;bih.biBitCount = 24;bih.biCompression = BI_RGB;bih.biSizeImage = strBaseH * strDrawLineStep;bih.biClrUsed = 0;bih.biClrImportant = 0;void* pDibData = 0;HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);CV_Assert(pDibData != 0);HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);//color.val[2], color.val[1], color.val[0]SetTextColor(hDC, RGB(255, 255, 255));SetBkColor(hDC, 0);//SetStretchBltMode(hDC, COLORONCOLOR);strcpy_s(buf, str);const char* ln = strtok_s(buf, "\n", bufT);int outTextY = 0;while (ln != 0){TextOutA(hDC, 0, outTextY, ln, strlen(ln));outTextY += singleRow;ln = strtok_s(0, "\n", bufT);}uchar* dstData = (uchar*)dst.data;int dstStep = dst.step / sizeof(dstData[0]);unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;unsigned char* pStr = (unsigned char*)pDibData + x * 3;for (int tty = y; tty <= b; ++tty){unsigned char* subImg = pImg + (tty - y) * dstStep;unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;for (int ttx = x; ttx <= r; ++ttx){for (int n = 0; n < dst.channels(); ++n) {double vtxt = subStr[n] / 255.0;int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n];subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);}subStr += 3;subImg += dst.channels();}}SelectObject(hDC, hOldBmp);SelectObject(hDC, hOldFont);DeleteObject(hf);DeleteObject(hBmp);DeleteDC(hDC);}int main(){Chessboard chessboard;Chess chess;waitKey(0);return 0;}
这就是简单的中国象棋的实现,但是其中仍有很多漏洞,希望各位大佬积极批评指正。