Saturday, October 23, 2010

Creating Qt game for mobile device with differnt screen size

Till now I have created few Qt games for Maemo 5 (N900) device, and now I wanted to run same games on Symbian device which support Qt.

First problem I encounter doing so is different screen size from N900, in my current game implementation I have hard coded screen size and coordination of game object.

After playing with graphics framework from some time, I created a small prototype application that shows two rectangle one on top left other on bottom right corner and can run on different Symbian device and N900 as well. So first thing I did is to remove all hard coded coordinate and implemented resize event, then scaled all graphics item which are added to graphics scene.

Following is my prototype code.

In below code, I have added QGraphicsView as QMainWindow's central widget and also reimplemented resizeEvent of QMainWindow.
GraphicsWidget::GraphicsWidget(QWidget *parent)
    : QMainWindow(parent)
{    
    _scene = new MyScene();
    _scene->setItemIndexMethod(QGraphicsScene::NoIndex);
    _view = new QGraphicsView(_scene,this);
    _view->setDragMode(QGraphicsView::NoDrag);
    _view->setCacheMode(QGraphicsView::CacheBackground);
    _view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);

    setCentralWidget(_view);

    // Disable scrollbars
    _view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    _view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

void GraphicsWidget::resizeEvent(QResizeEvent* event)
{
    _scene->setSceneRect(_view->rect());
    QWidget::resizeEvent(event);
}

And then in MyScene class, derived from QGraphicsScene, on sceneRectChanged signal i am scaling all item to scale factor according to my reference screen size, which is of n900 device's screen size.
MyScene::MyScene()
    :QGraphicsScene()
{
    item1 = new MyGraphicsItem();
    addItem( item1 );

    item2 = new MyGraphicsItem();
    addItem( item2 );
    QObject::connect(this,SIGNAL(sceneRectChanged(QRectF)),
                    this,SLOT(resize(QRectF)));
}

void MyScene::resize(const QRectF& newRect)
{
    qreal w = (qreal)newRect.width()/800 ;
    qreal h =  (qreal)newRect.height()/480;

    item1->resetMatrix();
    item1->scale(w,h);
    item1->setPos(newRect.topLeft());

    item2->resetMatrix();
    item2->scale(w,h);
    item2->setPos(newRect.width()-(item2->boundingRect().width()*w),
            newRect.height() - (item2->boundingRect().height()*h));
}
Finally in main function, I am showing QMainWindow in full screen mode.
int main(int argc, char* argv[] )
{
    QApplication app(argc,argv);
    GraphicsWidget widget;
    widget.showFullScreen();
    return app.exec();
}
Following are snaps from prototype running on emulator for different device.



No comments:

Post a Comment