Qt c ++乒乓球方向

时间:2016-05-29 01:37:52

标签: c++ qt pong

c ++,qt

现在我正在编写乒乓球比赛的球方向部分。

对我来说,我的想法看起来没问题,但效果并不好。

我的想法是这样的。

par_x,par_y是现在的球位置。 pre_x,pre_y是之前的球位置。

此代码是移动球的部分。

请告诉我错误的想法。 我不知道哪里出错了。

它建立得很好,但是球并没有向正确的方向反弹。它移动到其他方式或坚持边界。

此代码为mainwindow.h和mainwindow.cpp

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QCheckBox>
#include <QDebug>
#include <QPainter>
#include <QImage>
#include <QPixmap>
#include <QLabel>
#include <QPalette>
#include <QWidget>
#include <QtEvents>
#include <QPushButton>
#include <QFocusFrame>
#include <QMap>
#include <QString>
#include <QThread>
#include <math.h>
#include <QVector>

class Ball: public QThread
{
    Q_OBJECT

private:
    int x, y;
    int pre_x, pre_y;
    int par_x, par_y;

public:
    Ball(){x=380; y=490;}
    int get_x();
    int get_y();
    void set_x(int x);
    void set_y(int y);
    void set_posx(int x, int oper);
    void set_posy(int y, int oper);
    void oper_switch(int flag);
    void direction(int now);
    QVector <int> vector_x;
    QVector <int> vector_y;
    QVector <int> :: iterator it;

protected:
    void run();

signals:
    int sig();

};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QImage      *img_bar, *img_ball, *img_background, *img_GameBack;
    QPixmap     *buf_bar, *buf_ball, *buf_background, *buf_GameBack ;
    QLabel      *lbl_bar, *lbl_ball, *lbl_background, *lbl_GameBack ;
    QWidget     *backWidget;
    Ball        *ball;
    QPushButton *btn[3];


private slots:
    void        btn_click();
    void        ball_move();

protected:
    virtual void keyPressEvent(QKeyEvent *event);
    virtual void keyReleaseEvent(QKeyEvent *event);

};
#endif // MAINWINDOW_H






 #include "mainwindow.h"
#include "ui_mainwindow.h"

int bar_x = 350;    // Bar
const int bar_y = 500;
int btn_y = 350;  // Button position
int key_flag = 0;
int oper_flag = 0;
int bar_ball = 0;
int t = 0;

MainWindow::MainWindow(QWidget *parent)
{
       ball = new Ball();
       img_background = new QImage();
       buf_background = new QPixmap();

       if(img_background->load("C://Users//user//Documents//BreaOut//Background.png"))
       {
           *buf_background = QPixmap::fromImage(*img_background);
           *buf_background = buf_background->scaled(800,600);    
       }
       else
       {
          qDebug("Image can't find.");
       }

      lbl_background = new QLabel(this);
      lbl_background->setPixmap(*buf_background);
      lbl_background->resize(buf_background->width(),buf_background->height()); 
      lbl_background->move(0,0);
      lbl_background->show();

    for(int i = 0; i < 2; i++)
    {
        switch(i)
        {
            case 0 :
            {
                btn[i] = new QPushButton(QString("Game Start").arg(i), this);
                break;
            }
            case 1 :
            {
                btn[i] = new QPushButton(QString("How to play game?").arg(i), this);
                break;
            }
        }
        btn[i] -> setGeometry(325, btn_y, 150, 40);
        btn_y += 50;
    }

    connect(btn[0], SIGNAL(clicked()), this, SLOT(btn_click()));



     img_GameBack = new QImage();
     buf_GameBack = new QPixmap();

     if(img_GameBack->load("C://Users//user//Documents//BreaOut//GameBack.png"))
     {
         *buf_GameBack = QPixmap::fromImage(*img_GameBack);
         *buf_GameBack = buf_GameBack->scaled(800,600);    // 이미지 크기 조정
     }
     else
     {
        qDebug("Image can't find.");
     }

    lbl_GameBack = new QLabel(this);
    lbl_GameBack->setPixmap(*buf_GameBack);
    lbl_GameBack->resize(buf_GameBack->width(),buf_GameBack->height());
    lbl_GameBack->move(0,0);
    lbl_GameBack->setVisible(false);


        /*! 바 이미지 삽입*/
        img_bar = new QImage();
        buf_bar = new QPixmap();

        if(img_bar->load("C://Users//user//Documents//BreaOut//bar.png"))
        {
            *buf_bar = QPixmap::fromImage(*img_bar);
            *buf_bar = buf_bar->scaled(80,18);    // 이미지 크기 조정
        }
        else
        {
           qDebug("Image can't find.");
        }

       lbl_bar = new QLabel(this);
       lbl_bar->setPixmap(*buf_bar);
       lbl_bar->resize(buf_bar->width(),buf_bar->height()); 
           lbl_bar->move(bar_x, bar_y);
       //    lbl_bar->show();
           lbl_bar->setVisible(false);


    img_ball = new QImage();
    buf_ball = new QPixmap();

    if(img_ball->load("C://Users//user//Documents//BreaOut//Ball.png"))
    {
        *buf_ball = QPixmap::fromImage(*img_ball);
        *buf_ball = buf_ball->scaled(12,12);    // 이미지 크기 조정
    }
    else
    {
         qDebug("Image can't find.");
    }

    lbl_ball = new QLabel(this);

    lbl_ball->setVisible(false); connect(ball, SIGNAL(sig()), this, SLOT(ball_move()));
    lbl_ball->setPixmap(*buf_ball);
    lbl_ball->resize(buf_ball->width(),buf_ball->height()); 
    lbl_ball->move(ball->get_x(), ball->get_y());
    lbl_ball->show();
    lbl_ball->setVisible(false);

   connect(ball, SIGNAL(sig()), this, SLOT(ball_move()));

    QString brk1, brk2, brk3;
    brk1 = "X://parkjh688//Breakout//Brick1.png";
    brk2 = "X://parkjh688//Breakout//Brick2.png";
    brk3 = "X://parkjh688//Breakout//Brick3.png";

   /* QMap<QString, QMap<int, int> > m1 = { {brk1,1,1}, {brk1,1,1}, {brk1,1,1}, {brk1,1,1}, {brk1,1,1}, {brk1,1,1},
                                          {brk2,1,1}, {brk2,1,1}, {brk2,1,1}, {brk2,1,1}, {brk2,1,1}, {brk2,1,1},
                                          {brk3,1,1}, {brk3,1,1}, {brk3,1,1}, {brk3,1,1}, {brk3,1,1}, {brk3,1,1}};

    QMap<QString, QMap<int, int> > :: iterator it1;
    QMap<int, int> :: iterator it2;



    for(it1=m.begin(); it1 != m.end() ; it1++)
    {

    }*/


  //  for( it1 = m.begin() ; it1 != m.end() ; it1++)



    setWindowTitle("BreakOut");
    setFixedSize(800, 600);

}

MainWindow::~MainWindow()
{

}

void MainWindow::btn_click()
{
    lbl_background->setVisible(false);
    lbl_GameBack->setVisible(true);

    for(int i = 0; i < 2; i++)
    {
        btn[i]->setVisible(false);
    }

    lbl_bar->setVisible(true);
    lbl_ball->setVisible(true);
    key_flag = 1;
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{

    Q_UNUSED(event);

    qDebug("Key Press Event.");


   if(key_flag == 1){

        switch(event->key())
        {
        case Qt::Key_A: // A가 눌렸을 때
            if( bar_x > 0)
            {
                bar_x -=20;                  // lbl_bar를 움직이기 위한 좌표 변경
                qDebug() << bar_x;
                if(bar_ball == 0)
                {
                    ball->set_posx(20,1);
                    lbl_ball->move(ball->get_x(),ball->get_y());   
                    lbl_bar->move(bar_x,bar_y);   
                }
                    lbl_bar->move(bar_x,bar_y);  
            }
            lbl_bar->show();
            break;

        case Qt::Key_D: // D가 눌렸을 때
            if( bar_x < 720)
            {
                bar_x+=20;
                if(bar_ball == 0)
                {
                    ball->set_posx(20,0);
                    lbl_ball->move(ball->get_x(),ball->get_y());   
                    lbl_bar->move(bar_x,bar_y);
                }
                    lbl_bar->move(bar_x,bar_y);
            }
            lbl_bar->show(); break;
            break;

        case Qt::Key_W:
             ball->start();
             bar_ball = 1;
            break;

        default:
            break;
        }
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent*event)
{
    Q_UNUSED(event);
}

void MainWindow::ball_move()
{
    lbl_ball->move(ball->get_x(), ball->get_y());
    lbl_ball->show();
}

int Ball::get_x(){ return x; }

int Ball::get_y(){ return y; }

/* oper 0 : +=
 * oper 1 : -= */
void Ball::set_posx(int x, int oper)
{
    switch(oper)
    {
    case 0: this->x += x; break;

    case 1: this->x -= x; break;
    }
}

void Ball::set_posy(int y, int oper)
{
    switch(oper)
    {
    case 0: this->y += y; break;
    case 1: this->y -= y; break;
    }
}

void Ball::run()
{
    bool stop = false;
    int now = 0;
    int lock = 1;

    while(!stop)
    {
        vector_x.push_back(x);
        vector_y.push_back(y);

      /*  for(it = vector_x.begin(); it != vector_x.end(); it++)
                qDebug() << "x:" << (*it);

        for(it = vector_y.begin(); it != vector_y.end(); it++)
                qDebug() << "Y:" << (*it);*/

       if(y < 5)
       {
         //  oper_flag = 1;
         //  oper_switch(oper_flag);

          now = 3;

          it = vector_x.end();
          it -= 2;
          pre_x = (*it);
          par_x = x;
        //  qDebug() << "pre_x: " << pre_x;
        //  qDebug() << "X    : " << x;

          it = vector_y.end();
          it -= 2;
          pre_y = (*it);
          par_y = y;
        //  qDebug() << "pre_y: " << pre_y;
        //   qDebug() << "Y    : " << y;
       }
       else if( ((bar_x < x) && (x < bar_x+80)) &&
                                ((bar_y < y) && (y < bar_y+30)) )
       {
            //oper_flag = 0;
           now = 4;

           it = vector_x.end();
           it -= 2;
           pre_x = (*it);
           par_x = x;
           qDebug() << "pre_x: " << pre_x;
           qDebug() << "X    : " << x;

           it = vector_y.end();
           it -= 2;
           pre_y = (*it);
           par_y = y;
           qDebug() << "pre_y: " << pre_y;
           qDebug() << "Y    : " << y;

         qDebug() << "Bar Collision.";
       }
       else if(x > 785)
       {
           //oper_flag = 3;
           now = 2;

           it = vector_x.end();
           it -= 2;
           pre_x = (*it);
           par_x = x;
           qDebug() << "pre_x: " << pre_x;
           qDebug() << "X    : " << x;

           it = vector_y.end();
           it -= 2;
           pre_y = (*it);
           par_y = y;
           qDebug() << "pre_y: " << pre_y;
           qDebug() << "Y    : " << y;
       }
       else if(x < 0)
       {
           //oper_flag = 3;
           now = 1;

           it = vector_x.end();
           it -= 2;
           pre_x = (*it);
           par_x = x;
           qDebug() << "pre_x: " << pre_x;
           qDebug() << "X    : " << x;

           it = vector_y.end();
           it -= 2;
           pre_y = (*it);
           par_y = y;
           qDebug() << "pre_y: " << pre_y;
           qDebug() << "Y    : " << y;
           lock = 0;
       }
       else if( y > 580)
       {
                stop = true;
                qDebug() << "Thread Finish.";
       }
        //oper_switch(oper_flag);
       direction(now);
       sig();
        msleep(20);
    }
}

void Ball::set_x(int x) { this->x = x;  }

void Ball::set_y(int y) { this->y = y; }

void Ball::direction(int now)
{
    float theta, r;

    theta = atan2( (float)(par_y-pre_y), (float)(par_x-pre_x) ) *180 / 3.1415f;


    qDebug() << r;

    if(now == 0)
    {
        x += 2;
        y -= 5;
    }
    else if(now == 1)
    {
        if( (par_x<pre_x) && (par_y<pre_y) )
        {
            x += sin(theta)*10;
            y -= cos(theta)*10;
        }
        else if( (par_x<pre_x) && (par_y>pre_y) )
        {
            x += sin(theta)*3;
            y += cos(theta)*3;
        }
    }
    else if(now == 2)
    {

       // vector_x.clear();
       // vector_y.clear();

        if( (par_x>pre_x) && (par_y>pre_y) )   // |
        {                                     // \/
            x -= sin(theta)*10;
            y += cos(theta)*10;
        }
        else if( (par_x>pre_x) && (par_y<pre_y) )
        {
            x -= sin(theta)*10;
            y -= cos(theta)*10;
        }
    }
    else if(now == 3)
    {

        if( (par_x>pre_x) && (par_y<pre_y) )    // ->
        {
            x += cos(theta)*10;
            y += sin(theta)*10;
        }
        else if( (par_x<pre_x) && (par_y<pre_y))    // <-
        {
            x -= cos(theta)*10;
            y += sin(theta)*10;
        }

    }
    else // now == 4
    {
     //   vector_x.clear();
     //   vector_y.clear();

        if( (par_x>pre_x) && (par_y>pre_y) ) // ->
        {
            x += cos(theta)*10;
            y -= sin(theta)*10;
        }
        else if( (par_x<pre_x) && (par_y>pre_y) )
        {
            x -= cos(theta)*10;
            y -= sin(theta)*10;
        }
    }

}

/*
void Ball::oper_switch(int flag)
{
    float theta;

    it = vector_x.end();
    it -= 2;
    qDebug() << (*it);

    pre_x = (*it);

    it = vector_y.end();
    //pre_y = vector_y.at(it--);

    // theta = atan2( (float)(y-pre_y), (float)(x-pre_x) ) *180 / 3.1415f;

    switch(flag)
    {
    case 0:
        y -= 2, x += 2;
        break;
    case 1:
        y += 2; x += 2;
        theta = atan2( (float)(y-pre_y), (float)(x-pre_x) ) *180 / 3.1415f;
        x += cos(theta);
        y -= sin(theta);
        break;
    case 3:
        y -= 2; x-=2; break;
    }
}*/

ball direction

1 个答案:

答案 0 :(得分:1)

不知道这会回答你的问题有多好,但我不能很好地掌握你在这里想做什么,因为你的代码中没有任何评论,也不能隐式运行你的代码,因为我需要所有的库和你正在使用的任何东西,这对我来说太过分了。

但是,您是否考虑过从不同角度重新训练整个球的运动?看起来你正在做很多不必要的工作来移动那个球,你为什么不把它当作笛卡尔网格系统的一个点呢?例如:

double x; //position of ball on x axis, global variable
double y; //position of ball on y axis, global variable
double speed = 1; //speed of ball, global variable

void move()
{
    //the operation below will move the ball in a 45 degree angle to the
    //top-right for every drawn frame
    x += speed;
    y += speed;
}

此外,你也可以用这种方式改变球的方向,只需根据球朝向的当前象限改变x和y的增量值。例如,在示例中,球将在象限1中行进,并且将其发送到左下方,它将在象限3的方向上。只需确保x和y的速度之和保持相同。数字,否则球将根据角度的大小加速/减速。

希望这会有所帮助:)