天天看點

Qt遊戲程式設計——飛機大戰——補充

補充包:

#ifndef SUPPLY_H
#define SUPPLY_H

#include "flyer.h"

class Supply : public Flyer
{
public:
    Supply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent = 0)
        :Flyer(w, h, speed, pixs, scene, parent) {

    }
    ~Supply() {

    }
    QRectF boundingRect() const {
        return m_pixs.at(0).rect();
    }
    QPainterPath shape() const {
        QPainterPath path;
        path.addRect(boundingRect());
        return path;
    }
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
        Q_UNUSED(option);
        Q_UNUSED(widget);
        painter->drawPixmap(0, 0, m_pixs.at(0));
    }
    void advance(int) {
        if (!checkPos(DOWN)) {
            posLost();
            return;
        }
        QPointF pos = scenePos();
        pos.ry() += m_speed;
        setPos(pos);
    }

    void posLost() {
        setVisible(false);
        deleteLater();
    }

    void doCollide() {

    }

    void fall() {
        setVisible(false);
        deleteLater();
    }
};

#endif // SUPPLY_H      

補充包——血包

#ifndef BLOODSUPPLY_H
#define BLOODSUPPLY_H

#include "supply.h"

class BloodSupply : public Supply
{
public:
    BloodSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent = 0);
    ~BloodSupply();
    int name() const;
};

#endif // BLOODSUPPLY_H      
#include "bloodsupply.h"

BloodSupply::BloodSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent)
    :Supply(w, h, speed, pixs, scene, parent) {

}

BloodSupply::~BloodSupply() {

}

int BloodSupply::name() const
{
    return BLOODSUPPLYNAME;
}      

補充包——炸彈包

#ifndef BOMBSUPPLY_H
#define BOMBSUPPLY_H

#include "supply.h"

class BombSupply : public Supply
{
public:
    BombSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent = 0);
    ~BombSupply();
    int name() const;
};

#endif // BOMBSUPPLY_H      
#include "bombsupply.h"

BombSupply::BombSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent):
    Supply(w, h, speed, pixs, scene, parent) {

}

BombSupply::~BombSupply() {

}

int BombSupply::name() const {
    return BOMBSUPPLYNAME;
}      

補充包——子彈包

#ifndef BULLETSUPPLY_H
#define BULLETSUPPLY_H

#include "supply.h"

class BulletSupply : public Supply
{
public:
    BulletSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent = 0);
    ~BulletSupply();
    int name() const;
};

#endif // BULLETSUPPLY_H      
#include "bulletsupply.h"

BulletSupply::BulletSupply(qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent):
    Supply(w, h, speed, pixs, scene, parent) {

}

BulletSupply::~BulletSupply() {

}


int BulletSupply::name() const {
    return BULLETSUPPLYNAME;
}      

炸彈:

#ifndef PLAYERBOMB_H
#define PLAYERBOMB_H

#include "bullet.h"
#include "enemybullet.h"

class Bomb : public Bullet
{
public:
    Bomb(qreal angel, qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent = 0);
    ~Bomb();
    QPainterPath shape() const;
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    int name() const;
    void advance(int);
    void posLost();
    void doCollide();
    void fall();
};

#endif // BOMB_H      
#include "bomb.h"

Bomb::Bomb(qreal angel, qreal w, qreal h, qreal speed, const QPixmaps &pixs, QGraphicsScene *scene, QGraphicsItem *parent)
    :Bullet(angel, w, h, speed, pixs, scene, parent) {

}

Bomb::~Bomb() {

}

QRectF Bomb::boundingRect() const {
    return m_pixs.at(m_pixpos).rect();
}

QPainterPath Bomb::shape() const
{
    QPainterPath path;
    path.addRect(boundingRect());
    return path;
}

void Bomb::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    painter->drawPixmap(0, 0, m_pixs.at(m_pixpos));
}

int Bomb::name() const
{
    return BOMBNAME;
}

void Bomb::advance(int)
{
    if (!checkPos(UP) || !checkPos(DOWN) || !checkPos(LEFT) || !checkPos(RIGHT)) {
        posLost();
        return;
    }
    m_step++;
    if (m_step == BOMBPIXSTEP) {
        m_step = 0;
        m_pixpos++;
        if (m_pixpos == 2) m_pixpos = 0;
    }
    QPointF pos = scenePos();
    pos.rx() -= xSpeed;
    pos.ry() -= ySpeed;
    setPos(pos);
    doCollide();
}

void Bomb::posLost() {
    setVisible(false);
    deleteLater();
}

void Bomb::doCollide()
{
    foreach (QGraphicsItem *t, collidingItems()) {
        if (t->type() != UnFlyer::TYPE) {
            Flyer *flyer = static_cast<Flyer*>(t);
            switch (flyer->name()) {
            case ENEMYBULLETNAME:
                flyer->fall();
                break;
            }
        }
    }
}

void Bomb::fall() {
    setVisible(false);
    deleteLater();
}      

随機數

#ifndef RANDOMIZER_H
#define RANDOMIZER_H

#include <QObject>

class Randomizer : public QObject
{
    Q_OBJECT
public:
    static int creat(int x);
    static int creat(int x, int y);
private:
    explicit Randomizer(QObject *parent = 0);
};

#endif // RANDOMIZER_H      
#include "randomizer.h"

Randomizer::Randomizer(QObject *parent) : QObject(parent) {}

int Randomizer::creat(int x)
{
    return qrand() % x;
}

int Randomizer::creat(int x, int y)
{
    return qrand() % (y - x) + x;
}      

菜單

#ifndef MENUWIDGET_H
#define MENUWIDGET_H

#include <QDialog>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QPushButton>

class MenuWidget : public QDialog
{
    Q_OBJECT
public:
    explicit MenuWidget(bool isRunning, QWidget *parent = 0);
signals:
    void sig_newGame();
    void sig_quit();
protected slots:
    void slt_quit();
    void slt_newGame();

private:
    QPushButton *m_new;
    QPushButton *m_back;
    QPushButton *m_quit;
    bool states;
    void initUI();
};

#endif // MENUWIDGET_H      
#include "menuwidget.h"

MenuWidget::MenuWidget(bool isRunning, QWidget *parent) : QDialog(parent), states(isRunning) {
    setWindowFlags(Qt::FramelessWindowHint);
    initUI();
    setMinimumSize(150,300);
    setMaximumSize(150,300);
    move(parent->rect().center() - QPoint(150/2,300/2));
    connect(m_new, SIGNAL(clicked()), this, SLOT(slt_newGame()));
    connect(m_quit, SIGNAL(clicked()), this ,SLOT(slt_quit()));
    connect(m_back, SIGNAL(clicked()), this, SLOT(close()));

}

void MenuWidget::initUI()
{
    m_new = new QPushButton("New Game");
    m_back = new QPushButton("Back");
    m_quit = new QPushButton("Quit");

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addStretch();
    mainLayout->addWidget(m_new);
    mainLayout->addWidget(m_back);
    mainLayout->addWidget(m_quit);
    mainLayout->addStretch();
    setLayout(mainLayout);

    if (states) {
        m_new->setDisabled(true);

    } else {
        m_back->setDisabled(true);
    }
}

void MenuWidget::slt_quit()
{
    emit sig_quit();
    close();
}

void MenuWidget::slt_newGame()
{
    emit sig_newGame();
    close();
}      

控制台(遊戲邏輯, 注釋的代碼崩了)

#ifndef SPACE_H
#define SPACE_H

#include "planefactory.h"
#include "playerPlane.h"
#include "bloodsupply.h"
#include "bombsupply.h"
#include "bulletsupply.h"
#include "randomizer.h"
#include "menuwidget.h"

class Space : public QGraphicsView
{
    Q_OBJECT
public:
    Space(QWidget *parent = 0);
    void init();
    void bloodsupply();
    void bombsupply();
    void bulletsupply();
    void enemys();
protected:
    void mouseDoubleClickEvent(QMouseEvent *event);
private:
    //QGraphicsTextItem *scoretext, *bloodtext, *bombtext;
    QGraphicsScene *m_scene;
    QTimer *m_timer;
    PlayerPlane *m_player;
    uint m_scores, m_bloods, m_bombs, m_level, m_step;
    bool boss;//boss戰辨別
    bool isRunning;
signals:
    void sig_menu();
protected slots:
    void slt_newGame();
    void slt_playerDead();
    void slt_startGame();
    void slt_pauseGame();
    void slt_updata();
    void slt_addscore(int);
    void slt_menu();
    //void slt_updateScore(int);
    //void slt_updateBlood(int);
    //void slt_updateBomb(int);
};

#endif // SPACE_H      
#include "space.h"

Space::Space(QWidget *parent) : QGraphicsView(parent), boss(false),  isRunning(false) {
    m_scene = new QGraphicsScene;
    m_scene->setSceneRect(0, 0, SCENEWIDTH, SCENEHEIGHT);
    setScene(m_scene);

    setWindowFlags(Qt::FramelessWindowHint);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setCacheMode(QGraphicsView::CacheBackground);
    setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
    setOptimizationFlags(QGraphicsView::DontClipPainter | QGraphicsView::DontSavePainterState);
    setRenderHint(QPainter::Antialiasing);

    QPixmap pix(SCENEWIDTH, SCENEHEIGHT);
    pix.load(background);
    QPixmap temp = pix.scaled(SCENEWIDTH, SCENEHEIGHT, Qt::KeepAspectRatioByExpanding);
    setBackgroundBrush(temp);

    m_timer = new QTimer;
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slt_updata()));
    connect(this, SIGNAL(sig_menu()), this, SLOT(slt_menu()));

    init();
}

void Space::init() {
//    scoretext = new QGraphicsTextItem("0");
//    scoretext->setPos(0, 0);
//    m_scene->addItem(scoretext);

//    bloodtext = new QGraphicsTextItem("0");
//    bloodtext->setPos(0, 10);
//    m_scene->addItem(bloodtext);


//    bombtext = new QGraphicsTextItem("0");
//    bombtext->setPos(0, 20);
//    m_scene->addItem(bombtext);

    m_scores = 0, m_bloods = PLAYERPLANEBLOOD, m_bombs = 0, m_level = 1, m_step = 0;
    QPixmaps t;
    t.append(QPixmap(playerplane0));
    t.append(QPixmap(playerplane1));
    t.append(QPixmap(playerplane2));
    t.append(QPixmap(playerplane3));
    m_player = new PlayerPlane(PLAYERPLANEBLOOD, PLAYERPLANESIZE, PLAYERPLANESIZE, PLAYERPLANESPEED, t, m_scene);
    m_player->setFocus();
    connect(m_player, SIGNAL(sig_fall()), this, SLOT(slt_playerDead()));
    //connect(m_player, SIGNAL(sig_score(int)), this, SLOT(slt_updateScore(int)));
    //connect(m_player, SIGNAL(sig_blood(int)), this, SLOT(slt_updateBlood(int)));
    //connect(m_player, SIGNAL(sig_bomb(int)), this, SLOT(slt_updateBomb(int)));
}

void Space::slt_newGame()
{
    m_scene->clear();
    init();
    m_timer->start(50);
    isRunning = true;
}

void Space::slt_playerDead()
{
    m_timer->stop();
    isRunning = false;
}

void Space::slt_startGame()
{
    if (isRunning) m_timer->start(50);
}

void Space::slt_pauseGame()
{
    if (isRunning) m_timer->stop();
}

void Space::slt_updata()
{
    m_scene->advance();
    m_step++;
    if (m_step % 50 == 0 && !boss) {
        enemys();
    }
    if (m_step % 233 == 0) {
        bulletsupply();
    }
    if (m_step % 666 == 0) {
        bombsupply();
        m_step = 0;
    }
    if (m_step % 2333 == 0) {
        bloodsupply();
    }
}

void Space::slt_addscore(int score)
{
    m_scores += score;
    if (score == BOSSSCORE) {
        boss = false;
        m_level = 1;
        m_scores = 0;
        //slt_updateScore(m_scores);
    }
    if (m_scores != 0 && m_scores % 50 == 0) {
        m_level++;
        if (m_level == 7) m_level = 1;
    }
}

void Space::bloodsupply()
{
    QPixmaps t;
    t.append(QPixmap(bloodsupplypix));
    BloodSupply *bloodsupply = new BloodSupply(BLOODSUPPLYSIZE, BLOODSUPPLYSIZE, BLOODSUPPLYSPEED, t, m_scene);
    qreal x = Randomizer::creat(SCENEWIDTH - BLOODSUPPLYSIZE);
    bloodsupply->setPos(x, 0);
}

void Space::bombsupply()
{
    QPixmaps t;
    t.append(QPixmap(bombsupplypix));
    BloodSupply *bombsupply = new BloodSupply(BOMBSUPPLYSIZE, BOMBSUPPLYSIZE, BOMBSUPPLYSPEED, t, m_scene);
    qreal x = Randomizer::creat(SCENEWIDTH - BOMBSUPPLYSIZE);
    bombsupply->setPos(x, 0);
}

void Space::bulletsupply()
{
    QPixmaps t;
    t.append(QPixmap(bulletsupplypix));
    uint x = Randomizer::creat(SCENEWIDTH - BULLETSUPPLYSIZE);
    BulletSupply *bulletsupply = new BulletSupply(BULLETSUPPLYSIZE, BULLETSUPPLYSIZE, BULLETSUPPLYSPEED, t, m_scene);
    bulletsupply->setPos(x,0);
}

void Space::enemys()
{
    if (m_level == 6) {
        PlaneFactory::BossPlanes bossplanes = PlaneFactory::bcreator(1, scene());
        foreach (Boss *b, bossplanes) {
            int x = Randomizer::creat(SCENEWIDTH - BOSSSIZE);
            b->setPos(x, 0);
            connect(b, SIGNAL(sig_score(int)), this, SLOT(slt_addscore(int)));
        }
        boss = true;
    }
    else {
        PlaneFactory::FishPlanes fishplanes = PlaneFactory::fcreator(m_level, scene());
        foreach (Fish *f, fishplanes) {
            int z =  Randomizer::creat(6);
            if (z == 1) {
                int y = Randomizer::creat(SCENEHEIGHT / 2 - FISHSIZE);
                f->setPos(0, y);
            }
            else if (z == 2) {
                int y = Randomizer::creat(SCENEHEIGHT / 2 - FISHSIZE);
                f->setPos(SCENEWIDTH - FISHSIZE, y);
            }
            else {
                int x = Randomizer::creat(SCENEWIDTH - FISHSIZE);
                f->setPos(x, 0);
            }
            connect(f, SIGNAL(sig_score(int)), this, SLOT(slt_addscore(int)));
        }
    }
}

void Space::slt_menu()
{
    if (isRunning) {
        slt_pauseGame();
        QScopedPointer<MenuWidget> w(new MenuWidget(true, this));
        connect(w.data(), SIGNAL(sig_newGame()), this, SLOT(slt_newGame()));
        connect(w.data(), SIGNAL(sig_quit()), this, SLOT(close()));
        w->setModal(true);
        w->show();
        w->exec();
        slt_startGame();
    }
    else {
        QScopedPointer<MenuWidget> w(new MenuWidget(false, this));
        connect(w.data(), SIGNAL(sig_newGame()), this, SLOT(slt_newGame()));
        connect(w.data(), SIGNAL(sig_quit()), this, SLOT(close()));
        w->setModal(true);
        w->show();
        w->exec();
    }
}

void Space::mouseDoubleClickEvent(QMouseEvent *event) {
    event->accept();
    emit sig_menu();
}

//void Space::slt_updateScore(int score) {
//    QString text = QString::number(score, 10);
//    scoretext->setPlainText(text);
//}

//void Space::slt_updateBlood(int blood) {
//    QString text = QString::number(blood, 10);
//    bloodtext->setPlainText(text);
//}

//void Space::slt_updateBomb(int bomb) {
//    QString text = QString::number(bomb, 10);
//    bombtext->setPlainText(text);
//}      

其他物體(暫時沒用,可以添加增加遊戲性)

#ifndef UNFLYER_H
#define UNFLYER_H

#include <QtWidgets>
#include "global.h"

class UnFlyer : public QGraphicsObject {
    Q_OBJECT
public:
    UnFlyer(QGraphicsItem *parent = 0);
    ~UnFlyer();
    enum {TYPE = UserType + 1};
    int type() const;
};

#endif // UNFLYER_H      
#include "unflyer.h"

UnFlyer::UnFlyer(QGraphicsItem *parent) : QGraphicsObject(parent) {

}

UnFlyer::~UnFlyer() {

}

int UnFlyer::type() const {
    return UserType + 1;
}