使用Qt框架和C++语言实现俄罗斯方块小游戏(大一C++实训)

一、说明

1. 本人大一,能力有限。实训除去教学和写文档只有8天,时间紧迫,边学边做。若觉得代码不行,不喜勿喷。

2.代码基本手搓,过程中使用AI简化优化代码或提供思路,俄罗斯方块基本功能可以实现,具体的见游戏帮助模块,那里详细说明了游戏规则。

3.代码边修边写,注释比较详细,本文不做过多解释,自行阅读代码理解,若对Qt知识不太了解可自行查阅相关资料。

4.本文代码只做基本功能,若想有所创新,可在“未来展望”部分寻找思路。

二、详细代码

Tetris.pro

QT       += core gui
QT       += core sql
QT       += multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    block.cpp \
    main.cpp \
    mainwindow.cpp \
    startwindow.cpp

HEADERS += \
    block.h \
    mainwindow.h \
    startwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES +=

block.h

#ifndef CLOCK_H
#define CLOCK_H
#include <QPainter>
#include <QPoint>
#include <QKeyEvent>
#include <QTimer>
#include <QObject>
#include <QRandomGenerator>
#include <QDateTime>

typedef  QVector<QPoint> povector;

class Block: public QObject
{
    Q_OBJECT;
public:
    int type;   //方块类型
    povector myPoint;  //点集
    int fallSpeed;   //下落速度
    QTimer * fallTimer;   //计时器
    bool isBottom;  //是否到底
    QColor color;   //添加颜色
    povector allPoint1;  //记录已经存在的点

public:
    Block(){}
    Block(int type, povector& allPoints,int score);

    ~Block()
    {
        delete fallTimer;    // 释放定时器内存
    }

    //创建方块
    void createBlock();

    //画出方块
    void drawBlock(QPainter &painter,int x,int y);

    //旋转方块
    void rotateBlock();

    //自动下落
    void autoFallBlock();

    //左移
    void moveLeft();

    //右移
    void moveRight();

    //是否在底部
    bool isAtBottom();

    // 旋转碰撞检测
    bool checkCollision4(povector& points);

    //设置下落速度
    int setSpeed(int score);
};

#endif

block.cpp

#include "block.h"

Block::Block(int type, povector& allPoints,int score)
{
    //初始化方块类型
    this->type = type;

    //点集实时转移
    allPoint1=allPoints;

    //初始不在底部
    isBottom=false;

    // 初始化定时器
    fallTimer = new QTimer(this);
    QObject::connect(fallTimer, &QTimer::timeout, this, &Block::autoFallBlock);
    fallSpeed = setSpeed(score);     // 设置下落速度,单位为毫秒
    fallTimer->start(fallSpeed);   // 启动定时器
}

//创建不同类型的方块
void Block::createBlock()
{
    switch(Block::type)
    {
       //T型
    case 1 :
    {
        //这里的坐标顺序与后面操作有关
        myPoint = {QPoint(0, 0), QPoint(1, 0), QPoint(2, 0), QPoint(1, 1)};
        color = QColor(255, 128, 128);   //浅红色
        break;
    }

        //O型
    case 2 :
    {
        myPoint = {QPoint(0, 0), QPoint(1, 0), QPoint(0, 1), QPoint(1, 1)};
        color = QColor(255, 255, 150);   //浅黄色
        break;
    }

        //S型
    case 3 :
    {
        myPoint = {QPoint(0, 1), QPoint(1, 0), QPoint(1, 1), QPoint(2, 0)};
        color = QColor(173, 255, 195);   //浅绿色
        break;
    }

        //Z型
    case 4 :
    {
        myPoint = {QPoint(0, 0), QPoint(1, 0), QPoint(1, 1), QPoint(2, 1)};
        color = QColor(173, 216, 230);   //浅蓝色
        break;
    }

        //L型
    case 5 :
    {
        myPoint = {QPoint(0, 0), QPoint(0, 1), QPoint(0, 2), QPoint(1, 2)};
        color = QColor(175, 238, 238);    //浅青色
        break;
    }

        //J型
    case 6 :
    {
        myPoint = {QPoint(1, 0), QPoint(1, 1), QPoint(1, 2), QPoint(0, 2)};
        color = QColor(186, 147, 211);   //浅紫色
        break;
    }

        //I型
    case 7 :
    {
        myPoint = {QPoint(0, 0), QPoint(0, 1), QPoint(0, 2), QPoint(0, 3)};
        color = QColor(Qt::lightGray);    //浅灰色
        break;
    }

    default :
    {
        break;
    }
    }
}

//画出方块
void Block::drawBlock(QPainter &painter,int x,int y)
{
    //历遍一个俄罗斯方块的所有点绘图
    for (int i = 0; i < myPoint.size(); i++)
    {
        QPoint point = myPoint[i];
        painter.drawRect(QRect(x+point.x()*30, y+point.y()*30, 30, 30));
    }
}

//左移方块
void Block::moveLeft()
{
    bool valid = true;   //检测移动是否合法

    for (QPoint &point : myPoint)
    {
        if (point.x() == -4)     //为了使方块从中间下落,初始加了120像素,水平方向是12*30,这里从而是-4
        {
            valid = false;
            break;
        }
    }

    if (valid)      //合法才能移动方块,下同
    {
        for (QPoint &point : myPoint)
        {
            point.setX(point.x() - 1);
        }
    }
}

//右移方块
void Block::moveRight()
{
    bool valid = true;

    for (QPoint &point : myPoint)
    {
        if (point.x() == 7)    //为了使方块从中间下落,初始加了120像素,水平方向是12*30,这里从而调整
        {
            valid = false;
            break;
        }
    }

    if (valid)
    {
        for (QPoint &point : myPoint)
        {
            point.setX(point.x() + 1);
        }
    }
}

//旋转方块具体操作
void Block::rotateBlock()
{
    int centerX,centerY,relativeX,relativeY,newX,newY;
    bool valid;          //检测是否可以旋转

    // 保存当前方块的位置
    povector originalPoints = myPoint;
    // 保存旋转后的点集
    povector rotatedPoints = myPoint;

    if (type == 1|| type == 3 || type == 4 || type == 5 || type == 6)  // L, J,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值