小伙伴关心的问题:qt构建项目 *** ,目标桌面(如何构建qt),本文通过数据整理汇集了qt构建项目 *** ,目标桌面(如何构建qt)相关信息,下面一起看看。

qt构建项目  *** ,目标桌面(如何构建qt)

1,简介

QT实现中国象棋单机版,本来以为会花费不少时间的。由于之前2个游戏项目的练手,这个主要只在走棋算法部分花了些时间研究,最后一共2个晚上完成。

由于只是QT学习,没有考虑更多复杂功能,比如人机对战等,那个可能算法就得花很长时间。

2,效果

3,设计思路

准备2个棋盘棋子图片:

棋子类:

#pragma once #include "qpainter.h" enum ITEM_TYPE{ ITEM_SHUAI = 0, //帅 ITEM_SHI, //士 ITEM_XIANG, //象 ITEM_JU, //车 ITEM_MA, //马 ITEM_PAO, //炮 ITEM_BING, //兵 ITEM_MAX, }; enum ITEM_COLOR{ COLOR_RED = 0, //红方 COLOR_BLACK, //黑方 COLOR_MAX, }; class Item { public: Item(){} Item(ITEM_TYPE t,ITEM_COLOR c,QPoint pt); ~Item(void); public: ITEM_TYPE m_type; //棋子类型 ITEM_COLOR m_color; //红方黑方 QPoint m_pt; //位置 bool m_bShow; //是否显示,实现选中时闪烁效果 };

可以看到,棋子类型的定义和图片中棋子顺序一致,是为了直接以此枚举值计算棋子在图片中的位置。

MainWindow.h:其中主要逻辑都在mousePressEvent 鼠标响应:

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "Item.h" #include "qmap.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void InitItems(); //初始化所有棋子位置 void NewGame(); //新游戏 bool FindItemAtPoint(QPoint pt,Item& item); //给定一个棋盘上的点,查找是否存在棋子 bool DeleteItemAtPoint(QPoint pt,bool& bDeleteSHUAI); //bDeleteSHUAI:是否打掉的是“帅”或“将” void SetItemShow(Item item,bool bShow); //设置棋子显隐 bool MoveItem(Item item,QPoint ptMoveTo); //走棋逻辑 void ChangeItemPoint(QPoint ptItem,QPoint pt); //改变棋子位置属性 void DrawItem(QPainter& painter,Item item); //绘制棋子 //获取棋子能移动的区域 void GetMoveArea(Item item,QVector<QPoint>& area); void GetMoveArea_JU(Item item,QVector<QPoint>& area); void GetMoveArea_MA(Item item,QVector<QPoint>& area); void GetMoveArea_XIANG(Item item,QVector<QPoint>& area); void GetMoveArea_SHI(Item item,QVector<QPoint>& area); void GetMoveArea_SHUAI(Item item,QVector<QPoint>& area); void GetMoveArea_PAO(Item item,QVector<QPoint>& area); void GetMoveArea_BING(Item item,QVector<QPoint>& area); protected: void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *); void timerEvent(QTimerEvent *); private: Ui::MainWindow *ui; int m_nItemWidth; int m_nItemHeight; QPixmap m_ItemsImage; //棋子图片 QVector<Item> m_items; //所有棋子 Item m_SelectedItem; bool m_bExistSelectedItem; //是否已存在选中的棋子 bool m_bIsRedTurn; //当前该红方下 }; #endif // MAINWINDOW_H

其中主要逻辑都在mousePressEvent 鼠标响应:

//鼠标点击,走棋、吃棋等逻辑 void MainWindow::mousePressEvent(QMouseEvent * e) { //获得鼠标点所对应的棋盘点pt QPoint pt; pt.setX( (e->pos().x() - START_X ) / RECT_WIDTH); pt.setY( (e->pos().y() - START_Y ) / RECT_HEIGHT); //是否有选中的棋子 if(m_bExistSelectedItem) { //已存在棋子,判断鼠标点击的是否是选中棋子 if (pt == m_SelectedItem.m_pt) { //再次点击已经选择的棋子,什么也不做 return; } //点击其它棋子 Item ClickedItem; if (FindItemAtPoint(pt,ClickedItem)) { //点击的同色的另外一个棋子,改选 if ( (m_bIsRedTurn && ClickedItem.m_color == COLOR_RED) || (!m_bIsRedTurn && ClickedItem.m_color != COLOR_RED)) { SetItemShow(m_SelectedItem,true); m_SelectedItem = ClickedItem; return; } } //点击的异色棋子,判断是否能走能吃 QVector<QPoint> moveArea; GetMoveArea(m_SelectedItem,moveArea); //获取已选择棋子的可移动区域 if (moveArea.contains(pt)) { //包含当前鼠标点中的棋子,则能吃 bool bDeleteSHUAI = false; DeleteItemAtPoint(pt,bDeleteSHUAI); ChangeItemPoint(m_SelectedItem.m_pt,pt); if (bDeleteSHUAI) { QString str = m_bIsRedTurn?QStringLiteral("红方胜利!"):QStringLiteral("黑方胜利!"); QMessageBox::information(NULL, "GAME OVER ",str, QMessageBox::Yes , QMessageBox::Yes); NewGame(); return ; } m_bExistSelectedItem = false; m_bIsRedTurn = !m_bIsRedTurn; update(); return ; } else { //不能走到该位置 return ; } } else { //当前没有选中棋子 Item ClickedItem; if (FindItemAtPoint(pt,ClickedItem)) { //如果点中一个棋子,是当前走棋方的颜色,就选中了 if ( (m_bIsRedTurn && ClickedItem.m_color == COLOR_RED) || (!m_bIsRedTurn && ClickedItem.m_color == COLOR_BLACK)) { m_SelectedItem = ClickedItem; m_bExistSelectedItem = true; return; } } } }

里面最重要的就是这个GetMoveArea 函数,用来获取每个棋子的可走动的区域:

void MainWindow::GetMoveArea(Item item,QVector<QPoint>& moveArea) { switch (item.m_type) { case ITEM_JU: { GetMoveArea_JU(item,moveArea); break; } case ITEM_MA: { GetMoveArea_MA(item,moveArea); break; } case ITEM_XIANG: { GetMoveArea_XIANG(item,moveArea); break; } case ITEM_SHI: { GetMoveArea_SHI(item,moveArea); break; } case ITEM_SHUAI: { GetMoveArea_SHUAI(item,moveArea); break; } case ITEM_PAO: { GetMoveArea_PAO(item,moveArea); break; } case ITEM_BING: { GetMoveArea_BING(item,moveArea); break; } } }

比如对于棋子“马”,求可以走到的位置:

void MainWindow::GetMoveArea_MA( Item item,QVector<QPoint>& moveArea ) { //棋子“马”的计算可移动区域算法简介: //1,求出8个待选位置,8个位置的偏移是(-2,-1)(-2,1)(2,-1)(2,1)(1,-2)(1,2)(-1,-2)(-1,2)存在关系:|x|+|y|=3 //2,判断待选位置是否在棋盘内 //3,判断中间是否有卡位的棋子 //4,位置上是否已存在同色棋子 Item item2; for (int i = -2; i<=2; i++) { for(int j = -2; j<=2; j++) { if (qAbs(i) + qAbs(j) == 3) { QPoint ptNew = item.m_pt + QPoint(i,j); if (ptNew.x() >= 0 && ptNew.x() <= 8 && ptNew.y()>=0 && ptNew.y() <= 9) { } else { continue; } //求该方向行走路线的 卡位元素位置 QPoint ptDirect(0,0); if (qAbs(i) > qAbs(j)) { if (i>0) { ptDirect = QPoint(1,0); } else { ptDirect = QPoint(-1,0); } } else { if (j>0) { ptDirect = QPoint(0,1); } else { ptDirect = QPoint(0,-1); } } QPoint ptHit = item.m_pt + ptDirect; //马的卡位元素位置 if (FindItemAtPoint(ptHit,item2)) { //卡位 continue; } if (FindItemAtPoint(ptNew ,item2) && item.m_color == item2.m_color) { //有本组item continue; } moveArea.append(ptNew); } } } }

其它棋子类似,就是仔细处理下就OK了。

4,源码

源码已上传至群文件,可在学习群免费下载!

群号码:917341904

群名称:Qt实战学习群

更多qt构建项目 *** ,目标桌面(如何构建qt)相关信息请关注本站,本文仅仅做为展示!