Commit 79541e52 authored by Ian Wadham's avatar Ian Wadham

Change the scene over to a pixel-based coordinate system - the same as the...

Change the scene over to a pixel-based coordinate system - the same as the view has. This makes it easier to scale and render pixmaps, sprites, text and lines correctly and all together.

svn path=/branches/work/kgoldrunner-qgv/; revision=1314585
parent ec2382dd
......@@ -160,10 +160,10 @@ void KGrLevelPlayer::init (KGrView * view,
// Connect to the mouse-positioning code in the graphics.
connect (this, SIGNAL (getMousePos(int&,int&)),
view, SLOT (getMousePos(int&,int&)));
view->gameScene(), SLOT (getMousePos(int&,int&)));
connect (this, SIGNAL (setMousePos(int,int)),
view, SLOT (setMousePos(int,int)));
view->gameScene(), SLOT (setMousePos(int,int)));
// Show the layout of this level in the view (KGrCanvas).
int wall = ConcreteWall;
......
......@@ -49,8 +49,13 @@ KGrScene::KGrScene (KGrView * view)
m_tilesWide (FIELDWIDTH + 2 * 2),
m_tilesHigh (FIELDHEIGHT + 2 * 2),
m_tileSize (10),
m_themeChanged (true)
m_themeChanged (true),
m_topLeftX (0),
m_topLeftY (0),
m_mouse (new QCursor())
{
setItemIndexMethod(NoIndex);
m_tiles.fill (0, m_tilesWide * m_tilesHigh);
m_tileTypes.fill (FREE, m_tilesWide * m_tilesHigh);
......@@ -59,6 +64,7 @@ KGrScene::KGrScene (KGrView * view)
KGrScene::~KGrScene()
{
delete m_mouse;
}
void KGrScene::redrawScene ()
......@@ -68,23 +74,19 @@ void KGrScene::redrawScene ()
QSize size = m_view->size();
int tileSize = qMin (size.width() / m_tilesWide,
size.height() / m_tilesHigh);
m_topLeftX = (size.width() - m_tilesWide * tileSize)/2.0;
m_topLeftY = (size.height() - m_tilesHigh * tileSize)/2.0;
setSceneRect (0, 0, size.width(), size.height());
qreal unusedX = (size.width() - m_tilesWide * tileSize)/2.0;
qreal unusedY = (size.height() - m_tilesHigh * tileSize)/2.0;
unusedX = unusedX / tileSize; // Fraction of a tile at L and R.
unusedY = unusedY / tileSize; // Fraction of a tile at T and B.
setSceneRect (-1.0 - unusedX, -1.0 - unusedY,
m_tilesWide + 2.0 * unusedX, m_tilesHigh + 2.0 * unusedY);
int index = 0;
foreach (KGameRenderedItem * tile, m_tiles) {
if (tile) {
setTileSize (tile, tileSize);
setTile (tile, tileSize, index/m_tilesHigh, index%m_tilesHigh);
}
index++;
}
foreach (KGrSprite * sprite, m_sprites) {
setTileSize (sprite, tileSize);
sprite->changeCoordinateSystem (m_topLeftX, m_topLeftY, tileSize);
}
m_sizeChanged = false;
......@@ -135,16 +137,17 @@ void KGrScene::loadBackground (const int level)
m_background->setRenderSize (QSize ((m_tilesWide - 4) * m_tileSize,
(m_tilesHigh - 4) * m_tileSize));
m_background->setPos (1, 1);
m_background->setPos (m_topLeftX + 2 * m_tileSize,
m_topLeftY + 2 * m_tileSize);
// Keep the background behind the level layout.
m_background->setZValue (-1);
m_background->setScale (1.0 / m_tileSize);
}
void KGrScene::setTileSize (KGameRenderedItem * tile, const int tileSize)
void KGrScene::setTile (KGameRenderedItem * tile, const int tileSize,
const int i, const int j)
{
tile->setRenderSize (QSize (tileSize, tileSize));
tile->setScale (1.0 / tileSize);
tile->setPos (m_topLeftX + (i+1) * tileSize, m_topLeftY + (j+1) * tileSize);
}
void KGrScene::setBorderTile (const QString spriteKey, const int x, const int y)
......@@ -155,8 +158,7 @@ void KGrScene::setBorderTile (const QString spriteKey, const int x, const int y)
m_tiles[index] = t;
if (t) {
setTileSize (t, m_tileSize);
t->setPos (x, y);
setTile (t, m_tileSize, x, y);
}
}
......@@ -193,8 +195,7 @@ void KGrScene::paintCell (const int i, const int j, const char type)
m_tileTypes[index] = type;
if (t) {
setTileSize (t, m_tileSize);
t->setPos (i, j);
setTile (t, m_tileSize, i, j);
}
}
......@@ -238,7 +239,7 @@ int KGrScene::makeSprite (const char type, int i, int j)
}
sprite->setFrame (frame1);
setTileSize (sprite, m_tileSize);
sprite->setCoordinateSystem (m_topLeftX, m_topLeftY, m_tileSize);
addItem (sprite); // The sprite can be correctly rendered now.
sprite->move (i, j, frame1);
return spriteId;
......@@ -351,4 +352,31 @@ void KGrScene::deleteAllSprites()
m_sprites.clear();
}
void KGrScene::setMousePos (const int i, const int j)
{
m_mouse->setPos (m_view->mapToGlobal (QPoint (
m_topLeftX + (i + 1) * m_tileSize + m_tileSize/2,
m_topLeftY + (j + 1) * m_tileSize + m_tileSize/2)));
}
void KGrScene::getMousePos (int & i, int & j)
{
QPoint pos = m_view->mapFromGlobal (m_mouse->pos());
i = pos.x();
j = pos.y();
if (! m_view->isActiveWindow()) {
i = -2;
j = -2;
return;
}
// IDW TODO - Check for being outside scene. Use saved m_width and m_height.
i = (i - m_topLeftX)/m_tileSize - 1;
j = (j - m_topLeftY)/m_tileSize - 1;
// Make sure i and j are within the KGoldrunner playing area.
i = (i < 1) ? 1 : ((i > FIELDWIDTH) ? FIELDWIDTH : i);
j = (j < 1) ? 1 : ((j > FIELDHEIGHT) ? FIELDHEIGHT : j);
}
#include "kgrscene.moc"
......@@ -143,6 +143,10 @@ public slots:
void startAnimation (const int id, const bool repeating,
const int i, const int j, const int time,
const Direction dirn, const AnimationType type);
void setMousePos (const int i, const int j);
void getMousePos (int & i, int & j);
private:
/*
* Actions performed whenever the viewport is resized or a different theme
......@@ -179,7 +183,8 @@ private:
* @param tile The element to be resized.
* @param tileSize The new size.
*/
void setTileSize (KGameRenderedItem * tile, const int tileSize);
void setTile (KGameRenderedItem * tile, const int tileSize,
const int i, const int j);
KGrView * m_view;
KGrRenderer * m_renderer;
......@@ -210,6 +215,11 @@ private:
QByteArray m_tileTypes;
bool enemiesShowGold; // Show or conceal if enemies have gold.
int m_topLeftX;
int m_topLeftY;
QCursor * m_mouse;
};
#endif // KGRSCENE_H
......@@ -16,7 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************/
// #include "kgrglobals.h" // IDW test.
#include "kgrsprite.h"
#include "kgrrenderer.h"
......@@ -40,7 +39,10 @@ KGrSprite::KGrSprite (KGameRenderer * renderer, QString & key,
m_dt (0),
m_oldX (-1),
m_oldY (-1),
m_oldFrame (-1)
m_oldFrame (-1),
m_topLeftX (0),
m_topLeftY (0),
m_tileSize (1)
{
}
......@@ -51,11 +53,14 @@ KGrSprite::~KGrSprite()
void KGrSprite::move (double x, double y, int frame)
{
if (frame != m_oldFrame) {
setFrame (frame); // Set the frame in KGameRenderedItem.
// Change the animation frame in KGameRenderedItem.
setFrame (frame);
m_oldFrame = frame;
}
if ((x != m_oldX) || (y != m_oldY)) {
setPos (x, y); // Set the position in the scene.
// Change the position in scene (and view) coordinates.
setPos (m_topLeftX + (x + 1) * m_tileSize,
m_topLeftY + (y + 1) * m_tileSize);
m_oldX = x;
m_oldY = y;
}
......@@ -80,7 +85,7 @@ void KGrSprite::setAnimation (bool repeating, int x, int y, int startFrame,
m_dy = (double) dy / m_ticks;
m_frameTicks = (double) m_ticks / nFrameChanges;
m_frameChange = 0.0;
// kDebug() << "m_ticks" << m_ticks << "dx,dy,dt" << dx << dy << dt << "m_dx,m_dy" << m_dx << m_dy << "m_frameTicks" << m_frameTicks;
// kDebug() << "m_ticks" << m_ticks << "dx,dy,dt" << dx << dy << dt << "m_dx,m_dy" << m_dx << m_dy << "m_frameTicks" << m_frameTicks << "nFrames" << nFrames << "nFrameChanges" << nFrameChanges;
}
void KGrSprite::animate (bool missed)
......@@ -95,7 +100,7 @@ void KGrSprite::animate (bool missed)
return;
}
}
// kDebug() << m_frameCtr << "=" << m_x << m_y << "frame" << m_startFrame + m_frameCtr << m_frameChange;
// kDebug() << missed << m_frameCtr << "=" << m_x << m_y << "frame" << m_startFrame + m_frameCtr << m_frameChange;
// If the clock is running slow, skip an animation step.
if (! missed) {
......@@ -111,3 +116,23 @@ void KGrSprite::animate (bool missed)
m_x = m_x + m_dx;
m_y = m_y + m_dy;
}
void KGrSprite::setCoordinateSystem (int topLeftX, int topLeftY, int tileSize)
{
if (tileSize != m_tileSize) {
setRenderSize (QSize (tileSize, tileSize));
}
m_tileSize = tileSize;
m_topLeftX = topLeftX;
m_topLeftY = topLeftY;
}
void KGrSprite::changeCoordinateSystem(int topLeftX, int topLeftY, int tileSize)
{
setCoordinateSystem (topLeftX, topLeftY, tileSize);
double x = m_oldX;
double y = m_oldY;
m_oldX = m_oldY = -1; // Make it look like a change of position,
move (x, y, m_oldFrame); // to force a recalculation of view coords.
}
......@@ -33,16 +33,18 @@ public:
const char type, const int tickTime = 20);
~KGrSprite();
inline char spriteType () { return m_type; }
inline QPointF currentLoc () { return pos(); }
inline int currentFrame () { return frame(); }
inline void setZ (qreal z) { setZValue(z); }
inline char spriteType () { return m_type; }
inline QPointF currentLoc () { return QPointF (m_x, m_y); }
inline int currentFrame () { return frame(); }
inline void setZ (qreal z) { setZValue(z); }
void move (double x, double y, int frame);
void animate (bool missed);
void setAnimation (bool repeating, int x, int y, int startFrame,
int nFrames, int dx, int dy, int dt,
int nFrameChanges);
void setCoordinateSystem (int topLeftX, int topLeftY, int tileSize);
void changeCoordinateSystem (int topLeftX, int topLeftY, int tileSize);
private:
char m_type;
......@@ -64,6 +66,10 @@ private:
double m_oldX;
double m_oldY;
int m_oldFrame;
int m_topLeftX;
int m_topLeftY;
int m_tileSize;
};
#endif // KGRSPRITE_H
......@@ -25,7 +25,6 @@
KGrView::KGrView (QWidget * parent)
:
QGraphicsView (parent),
m_mouse (new QCursor ()),
m_scene (new KGrScene (this))
{
setScene (m_scene);
......@@ -33,41 +32,6 @@ KGrView::KGrView (QWidget * parent)
KGrView::~KGrView ()
{
delete m_mouse;
}
void KGrView::getMousePos (int & i, int & j)
{
QPointF pos = mapToScene (mapFromGlobal (m_mouse->pos()));
i = pos.x();
j = pos.y();
// The window lacks keyboard focus or is minimized.
if (! isActiveWindow()) {
i = -2;
j = -2;
return;
}
// The pointer is outside the level layout.
if (i < -1 || i > FIELDWIDTH + 2 || j < -1 || j > FIELDHEIGHT + 2) {
i = -1;
j = -1;
return;
}
}
void KGrView::setMousePos (const int i, const int j)
{
QPoint pos = mapFromScene (i, j);
// Puts the cursor at the middle of the starting cell.
int s = m_scene->tileSize().width() / 2;
int x = pos.x() + s;
int y = pos.y() + s;
m_mouse->setPos( mapToGlobal ( QPoint (x, y)));
}
void KGrView::resizeEvent (QResizeEvent *)
......
......@@ -18,7 +18,6 @@
#ifndef KGRVIEW_H
#define KGRVIEW_H
#include <QCursor>
#include <QMouseEvent>
#include <QResizeEvent>
#include <QGraphicsView>
......@@ -32,20 +31,11 @@ public:
KGrView (QWidget * parent);
~KGrView ();
/*
* Get the cursor's position in this widget coordinates.
*/
QPointF mousePos ();
/*
* Get a pointer to the game scene.
*/
KGrScene * gameScene () const { return m_scene; }
public slots:
void getMousePos (int & i, int & j);
void setMousePos (const int i, const int j);
signals:
void mouseClick (int);
void mouseLetGo (int);
......@@ -57,7 +47,6 @@ protected:
virtual void mouseReleaseEvent (QMouseEvent * mouseEvent);
private:
QCursor * m_mouse;
KGrScene * m_scene;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment