2016-10-16 5 views
1

현재 Qt와 함께 C++로 된 학교용 게임/시뮬레이션을 개발 중입니다. Java에 대한 배경 지식이 있습니다. 제 질문은 800/600 창에서 Qt로 기본 gameloop을 설정하는 방법입니다. paintEvent를 재정의 (override) 해 GraphicsView 윈도우에 드로잉을 시도했지만, 그러한 루프를 설정할 수 없었습니다. 오버라이드 (override)하는 실수가있었습니다.C++/Qt에서 30fps 루프를 설정하는 방법

#include "mainwindow.h" 
#include <QGraphicsView> 
#include "graphicsview.h" 

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) 
{ 
    resize(800, 600); 
    setWindowTitle("A* Pathfinder"); 
    gView = new GraphicsView(this); 
    setCentralWidget(gView); 
} 

MainWindow::~MainWindow() 
{ 

} 

GraphicsView 급 :

#include "graphicsView.h" 

void GraphicsView::paintEvent(QPaintEvent *event) { 
    QPainter painter(this); 
    painter.drawLine(10,10, 100,100); 
} 

graphicsView.h :

#ifndef GRAPHICSVIEW_H 
#define GRAPHICSVIEW_H 

#endif // GRAPHICSVIEW_H 
#include <QGraphicsView> 

class GraphicsView : public QGraphicsView 
{ 
    protected: 
    void paintEvent(QPaintEvent *event); 
}; 

죄송 유사한 질문은 이미 질문있어하지만 난 정말 붙어 오전 내 특정에 대한 도움말을 찾을 수없는 경우 케이스. 다시 말하지만, 30fps로 그래픽을 그릴 수있는 800x600 창을 원합니다.

+0

게임 루프 타이밍 : http://gafferongames.com/game-physics/fix-your-timestep/ –

+1

코드를 일률적으로 형식화하고 특히 들었을 때 들여 쓰기가 일관되게 처리되도록 노력하십시오. 당신이 중요하다고 느끼지는 않을지 모르지만, 특히 익숙하지 않은 코드를 읽을 때는 분명히 그렇습니다. – dkasak

+0

@dkasak sry 포맷팅과 들여 쓰기가 복사 될 때 다소 분실 됨 – thefox1009

답변

2

먼저 잘못된 방향으로 가고 있습니다. QGraphicsView을 재정의 할 필요가 없습니다. 재고가 충분합니다. paintEvent()을 덮어 쓸 필요가 없습니다. 생각했던대로 작동하지 않습니다. 거기에 장면을 렌더링하지 않습니다. 즉, 뷰의 프레임 만 렌더링하는 코드입니다. 즉, 뷰가 포함 된 것이 아니라 빈 뷰가 어떻게 보이는지입니다.

재고 그래픽 항목 (예 : 직사각형, 텍스트, 호 및 기타)이 제공하지 않는 맞춤형 도면이있는 경우 사용자 고유의 QGraphicsItem을 구현하고 paint() 기능을 구현해야합니다. 작동 방식은 모든 항목에 책임이 있습니다. 그림을 그리는 장면은 모든 항목을 관리하고 장면은 장면을 시각화합니다.

고정 속도로 타이머를 실행하고 싶지는 않습니다. 매우 순진하고 열악한 솔루션입니다. 시간 렌더링 및 게임 로직 처리에 소요되는 시간을 고려하지 않으며 꾸준한 프레임 속도를 원할 경우 이러한 변수를 고려해야합니다.

30FPS는 33.33msec마다 프레임을 휘젓다해야한다는 것을 의미합니다. 따라서 이전 프레임이 가져온 시간을 기준으로 모든 후속 프레임을 예약해야합니다. 예를 들어, 이전 프레임에 15 밀리 초가 걸리면 다음을 33.33 - 15 밀리 초 단위로 예약해야 CPU를 유지할 수있는 한 더 세분화 된 제어 및 안정적인 프레임 속도를 얻을 수 있습니다.

정적 기능 QTimer::singleShot()을 사용하여 사용자 정의 간격으로 모든 후속 프레임을 예약 할 수 있습니다.

+1

첫 번째 프레임을 렌더링하고 처리하는 데 충분한 시간이 있다면 고정 된 QTimer도 문제가되지 않습니다. QTimer :: singleShot()은 프레임 당 더 많은 시간을 제공하지 않습니다. QTimer는 루틴에서 소비되는 시간과 관계없이 30fps로 실행됩니다. 두 솔루션 모두에서 프레임을 삭제해야 할 수 있습니다. – juzzlin

+0

나는 사소한 예 이외에 고정 된 간격으로 계속 발사하는 타이머를 사용하지 않을 것이다. 그것은 하나의 스레드를 사용하고 메인 스레드를 블로킹하는데 의존 할 것이고, 이것은 정말로 원하지 않습니다. 따라서 엔진을 확장 할 때 필연적으로 한계와 복잡한 문제가 발생할 것입니다. – dtech

+0

맞습니다.하지만 Qt에서는 세밀한 제어가 어려운 경우가 있습니다. 예를 들어, QQuickFramebufferObject :: Renderer는'virtual void render()'를 제공합니다. 이것은 아마도 60fps에서 호출 될 것입니다. – juzzlin