最近流行俄罗斯方块,来一个Qt版本的,90行

lxyppc 2012-03-02 04:02:52
最近流行俄罗斯方块,来一个Qt版本的,算法代码90行,加上main.cpp中的内容不到100行
mainwindow.h 中的内容
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
#define EXT(x,c) (((x)&8)>>3)*c,(((x)&4)>>2)*c,(((x)&2)>>1)*c,((x)&1)*c
#define PAT(l1,l2,l3,l4,c) { {EXT(l1,c)},{EXT(l2,c)},{EXT(l3,c)},{EXT(l4,c)} }
static unsigned int patten = 0, state = 0, patten2 = 0, state2 = 0, score = 0;
static unsigned char map[28][18] = {{0}};
static unsigned char pats[7][4][4][4] = {
{ PAT(0,6,6,0,1),PAT(0,6,6,0,1),PAT(0,6,6,0,1),PAT(0,6,6,0,1) }, // box
{ PAT(4,4,6,0,2),PAT(0,7,4,0,2),PAT(6,2,2,0,2),PAT(0,2,14,0,2) }, // L
{ PAT(2,2,6,0,3),PAT(0,4,7,0,3),PAT(6,4,4,0,3),PAT(0,14,2,0,3) }, // J
{ PAT(0,6,3,0,4),PAT(2,6,4,0,4),PAT(0,6,3,0,4),PAT(2,6,4,0,4) }, // Z
{ PAT(0,3,6,0,2),PAT(4,6,2,0,2),PAT(0,3,6,0,2),PAT(4,6,2,0,2) }, // S
{ PAT(0,7,2,0,3),PAT(2,6,2,0,3),PAT(0,2,7,0,3),PAT(2,3,2,0,3) }, // T
{ PAT(4,4,4,4,1),PAT(0,15,0,0,1),PAT(4,4,4,4,1),PAT(0,15,0,0,1) } }; // line
class MainWindow : public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0) : QMainWindow(parent),timer(new QTimer(this)){
setGeometry(400,400,400,400);
timer->setInterval(500);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
}
public slots: void onTimer(void){ keyPressEvent(0); }
protected:
int blockDrop(bool real = true){
for(int i=0;i<4 && real;i++){
*(int*)&map[i+curpos.y()][curpos.x()] |= *(int*)&pats[patten%7][state&3][i][0];
if(strlen((char*)&map[i+curpos.y()][0])==17){
memmove(&map[5][0],&map[4][0], (i+curpos.y() - 4)*18);
initRow(4); score++;
}
}
patten = patten2; state = state2;
curpos = QPoint(7,0);
while(!isValid(curpos.x(),curpos.y()) && curpos.y()<6)curpos.ry()++;
if(curpos.y()>=6) timer->stop();
return patten2 = qrand(), state2 = qrand();
}
void paintEvent(QPaintEvent *){
QPainter painter(this);
QVector<QRgb> table;
table<<qRgb(200,200,200)<<qRgb(128,0,0)<<qRgb(0,0,128)<<qRgb(0,128,0)<<qRgb(128,128,0);
QImage img((uchar*)map,18,28,18,QImage::Format_Indexed8);
img.setColorTable(table);
painter.drawImage(10,10,img.scaled(18*15,28*15),4*15,4*15,10*15,20*15);
QImage img2((const uchar*)pats[patten2%7][state2&3],4,4,4,QImage::Format_Indexed8);
img2.setColorTable(table);
if(timer->isActive())painter.drawImage(13*15,10,img2.scaled(4*15,4*15));
QImage img3((const uchar*)pats[patten%7][state&3],4,4,4,QImage::Format_Indexed8);
img3.setColorTable(table);
img3.setColor(0,0);
if(timer->isActive())painter.drawImage((curpos.x()-4)*15+10,(curpos.y()-4)*15+10,img3.scaled(4*15,4*15));
painter.drawText(190,100,QString("score: %1").arg(score));
if(!timer->isActive())painter.drawText(190,140,QString("Game over. Press 'P'"));
}
virtual void keyPressEvent ( QKeyEvent * e ){
if(!timer->isActive()){
if(e->key() == Qt::Key_Space || e->key() == Qt::Key_P){
memset(map,0,sizeof(map)); // initial map
memset(map[24],0x1,18*4);
memset(map[0],0x1,18*4);
for(int i=4;i<24;i++)initRow(i);
qsrand(QTime::currentTime().msec());
timer->start(); score = 0;
patten2 = qrand(); state2 = qrand();
blockDrop(false);
}
}else if(!e || e->key() == Qt::Key_Down || e->key() == Qt::Key_S){
isValid(curpos.x(),curpos.y()+1) ? curpos.ry()++ : blockDrop();
}else if(e->key() == Qt::Key_Left || e->key() == Qt::Key_A){
if(isValid(curpos.x()-1,curpos.y())) curpos.rx()--;
}else if(e->key() == Qt::Key_Right || e->key() == Qt::Key_D){
if(isValid(curpos.x()+1,curpos.y())) curpos.rx()++;
}else if(e->key() == Qt::Key_Up || e->key() == Qt::Key_W){
state++;
if(!isValid(curpos.x(),curpos.y())) state--;
}
update();
}
bool isValid(int x, int y){
for(int i=0;i<4;i++) for(int j=0;j<4;j++)
if(pats[patten%7][state&3][i][j] && map[y+i][x+j]) return false;
return true;
}
void initRow(int i) { *(long*)&map[i][0] = 0x01010101; *(long*)&map[i][14] = 0x010101; }
QTimer* timer;
QPoint curpos;
};
#endif // MAINWINDOW_H
...全文
348 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
老邓 2012-03-04
  • 打赏
  • 举报
回复
厉害,收藏了!
zhangke19891001 2012-03-04
  • 打赏
  • 举报
回复
太强大了
whyboysa 2012-03-02
  • 打赏
  • 举报
回复
领教了。。。好帖子。
wandaoyongshi 2012-03-02
  • 打赏
  • 举报
回复
强大,吃饭完再慢慢看。
xiachm 2012-03-02
  • 打赏
  • 举报
回复
牛X,学习了。
lxyppc 2012-03-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mrpre 的回复:]

能不能打开说一下思路。比如如何转动方块
[/Quote]
方块转动是预先就定义好了的,在pats数组中
       }else if(e->key() == Qt::Key_Up || e->key() == Qt::Key_W){
state++;
if(!isValid(curpos.x(),curpos.y())) state--;
}

这段代码就是将方块旋转到下一个状态,然后看有无碰撞,如果有碰撞,就把状态旋转回来,没有就保持新的状态

pats[patten2%7][state2&3]
这个就是取当前方块,patten是方块类型,state是方块旋转状态
最后得到一个4X4的数组表示当前方块
Mrpre 2012-03-02
  • 打赏
  • 举报
回复
能不能打开说一下思路。比如如何转动方块
lxyppc 2012-03-02
  • 打赏
  • 举报
回复
main.cpp中的内容
#include <QtGui>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

16,229

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧