diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2008-11-27 19:56:26 +0100 |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2008-11-27 19:57:31 +0100 |
commit | f2fb35cc3a227e8966bab9a9380fe9a543874eb6 (patch) | |
tree | 2c2aa66ab21ff5f455425f9f16d1f1c937c9ee61 | |
parent | 2ec40e64cf4d870c1f86640570b06bb498abcc2f (diff) |
Add soldier item.
-rw-r--r-- | main.cpp | 8 | ||||
-rw-r--r-- | mazescene.cpp | 193 | ||||
-rw-r--r-- | mazescene.h | 43 | ||||
-rw-r--r-- | soldier/O01.png | bin | 0 -> 1419 bytes | |||
-rw-r--r-- | soldier/O02.png | bin | 0 -> 1384 bytes | |||
-rw-r--r-- | soldier/O03.png | bin | 0 -> 1266 bytes | |||
-rw-r--r-- | soldier/O04.png | bin | 0 -> 1276 bytes | |||
-rw-r--r-- | soldier/O05.png | bin | 0 -> 1399 bytes | |||
-rw-r--r-- | soldier/O06.png | bin | 0 -> 1305 bytes | |||
-rw-r--r-- | soldier/O07.png | bin | 0 -> 1251 bytes | |||
-rw-r--r-- | soldier/O08.png | bin | 0 -> 1311 bytes | |||
-rw-r--r-- | soldier/O09.png | bin | 0 -> 1377 bytes | |||
-rw-r--r-- | soldier/O10.png | bin | 0 -> 1457 bytes | |||
-rw-r--r-- | soldier/O11.png | bin | 0 -> 1410 bytes | |||
-rw-r--r-- | soldier/O12.png | bin | 0 -> 1297 bytes | |||
-rw-r--r-- | soldier/O13.png | bin | 0 -> 1362 bytes | |||
-rw-r--r-- | soldier/O14.png | bin | 0 -> 1349 bytes | |||
-rw-r--r-- | soldier/O15.png | bin | 0 -> 1394 bytes | |||
-rw-r--r-- | soldier/O16.png | bin | 0 -> 1417 bytes | |||
-rw-r--r-- | soldier/O17.png | bin | 0 -> 1432 bytes | |||
-rw-r--r-- | soldier/O18.png | bin | 0 -> 1472 bytes | |||
-rw-r--r-- | soldier/O19.png | bin | 0 -> 1338 bytes | |||
-rw-r--r-- | soldier/O20.png | bin | 0 -> 1302 bytes | |||
-rw-r--r-- | soldier/O21.png | bin | 0 -> 1400 bytes | |||
-rw-r--r-- | soldier/O22.png | bin | 0 -> 1331 bytes | |||
-rw-r--r-- | soldier/O23.png | bin | 0 -> 1301 bytes | |||
-rw-r--r-- | soldier/O24.png | bin | 0 -> 1399 bytes | |||
-rw-r--r-- | soldier/O25.png | bin | 0 -> 1372 bytes | |||
-rw-r--r-- | soldier/O26.png | bin | 0 -> 1415 bytes | |||
-rw-r--r-- | soldier/O27.png | bin | 0 -> 1394 bytes | |||
-rw-r--r-- | soldier/O28.png | bin | 0 -> 1333 bytes | |||
-rw-r--r-- | soldier/O29.png | bin | 0 -> 1350 bytes | |||
-rw-r--r-- | soldier/O30.png | bin | 0 -> 1369 bytes | |||
-rw-r--r-- | soldier/O31.png | bin | 0 -> 1375 bytes | |||
-rw-r--r-- | soldier/O32.png | bin | 0 -> 1386 bytes | |||
-rw-r--r-- | soldier/O33.png | bin | 0 -> 1440 bytes | |||
-rw-r--r-- | soldier/O34.png | bin | 0 -> 1434 bytes | |||
-rw-r--r-- | soldier/O35.png | bin | 0 -> 1325 bytes | |||
-rw-r--r-- | soldier/O36.png | bin | 0 -> 1294 bytes | |||
-rw-r--r-- | soldier/O37.png | bin | 0 -> 1375 bytes | |||
-rw-r--r-- | soldier/O38.png | bin | 0 -> 1357 bytes | |||
-rw-r--r-- | soldier/O39.png | bin | 0 -> 1293 bytes | |||
-rw-r--r-- | soldier/O40.png | bin | 0 -> 1383 bytes |
43 files changed, 175 insertions, 69 deletions
@@ -7,9 +7,11 @@ int main(int argc, char **argv) QPixmapCache::setCacheLimit(100 * 1024); // 100 MB const char *map = - "#####&##" + "###&####" "# #" - "# #### #" + "& #" + "# #" + "# ##?# #" "& # #" "# @@ &" "# @@ # #" @@ -18,7 +20,7 @@ int main(int argc, char **argv) "$ #" "#&&&&&&#"; - MazeScene *scene = new MazeScene(map, 8, 10); + MazeScene *scene = new MazeScene(map, 8, 12); View view; view.setScene(scene); diff --git a/mazescene.cpp b/mazescene.cpp index 08a0676..f4a3c73 100644 --- a/mazescene.cpp +++ b/mazescene.cpp @@ -48,6 +48,7 @@ MazeScene::MazeScene(const char *map, int width, int height) types['@'] = 2; types['%'] = 3; types['$'] = 4; + types['?'] = 5; int type; for (int y = 0; y < height; ++y) { @@ -156,11 +157,49 @@ void MazeScene::drawBackground(QPainter *painter, const QRectF &rect) painter->fillRect(rect, g); } +ProjectedItem::ProjectedItem(const QRectF &bounds, bool shadow) + : m_bounds(bounds) + , m_shadowItem(0) +{ + if (shadow) { + m_shadowItem = new QGraphicsRectItem(bounds, this); + m_shadowItem->setPen(Qt::NoPen); + m_shadowItem->setZValue(10); + } + + m_targetRect = m_bounds; +} + +void ProjectedItem::setPosition(const QPointF &a, const QPointF &b) +{ + m_a = a; + m_b = b; +} + WallItem::WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int type) - : m_a(a) - , m_b(b) + : ProjectedItem(QRectF(-0.5, -0.5, 1.0, 1.0)) , m_type(type) { + setPosition(a, b); + + static QImage brown = QImage("brown.png").convertToFormat(QImage::Format_RGB32); + static QImage book = QImage("book.png").convertToFormat(QImage::Format_RGB32); + static QImage door = QImage("door.png").convertToFormat(QImage::Format_RGB32); + + switch (type) { + case -1: + setImage(door); + break; + case 1: + setImage(book); + break; + case 2: + break; + default: + setImage(brown); + break; + } + static const char *urls[] = { "http://www.google.com", @@ -171,12 +210,6 @@ WallItem::WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int typ "http://chaos.troll.no/~tavestbo/webkit" }; - m_shadowItem = new QGraphicsRectItem(boundingRect(), this); - m_shadowItem->setPen(Qt::NoPen); - m_shadowItem->setZValue(10); - - m_targetRect = boundingRect(); - qreal scale = 0.8; QPalette palette; @@ -199,6 +232,8 @@ WallItem::WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int typ view->resize(480, 320); // not soo big view->setViewport(new QWidget); // no OpenGL here childWidget = view; + } else if (type == 5) { + scene->addEntity(new Entity(QPointF(3.5, 3.5))); } else if (type == 0 || type == 2) { static int index; if (index == 0) { @@ -239,15 +274,18 @@ WallItem::WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int typ m_childItem->translate(-center.x(), -center.y()); } -void WallItem::setDepths(qreal za, qreal zb) +void ProjectedItem::setDepths(qreal za, qreal zb) { + if (!m_shadowItem) + return; + const qreal falloff = 40; const int maxAlpha = 180; int va = int(falloff * zb); int vb = int(falloff * za); - if (va >= maxAlpha && vb >= maxAlpha) { - m_shadowItem->setBrush(QColor(0, 0, 0, maxAlpha)); + if (va == vb || va >= maxAlpha && vb >= maxAlpha) { + m_shadowItem->setBrush(QColor(0, 0, 0, qMin(maxAlpha, va))); } else { qreal xa = 0; qreal xb = 1; @@ -272,49 +310,45 @@ void WallItem::setDepths(qreal za, qreal zb) } } -QRectF WallItem::boundingRect() const +QRectF ProjectedItem::boundingRect() const { - return QRectF(-0.5, -0.5, 1, 1); + return m_bounds; } -void WallItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +void ProjectedItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - static QImage brown = QImage("brown.png").convertToFormat(QImage::Format_RGB32); - static QImage book = QImage("book.png").convertToFormat(QImage::Format_RGB32); - static QImage door = QImage("door.png").convertToFormat(QImage::Format_RGB32); - - if (m_type != 2) { - if (m_type == 1) { - painter->drawImage(boundingRect(), book, book.rect()); - } else if (m_type == -1) { - QRectF target = m_targetRect.translated(0.5, 0.5); - QRectF source = QRectF(0, 0, door.width() * (1 - target.x()), door.height()); - painter->drawImage(m_targetRect, door, source); - } else { - painter->drawImage(boundingRect(), brown, brown.rect()); - } + if (!m_image.isNull()) { + QRectF target = m_targetRect.translated(0.5, 0.5); + QRectF source = QRectF(0, 0, m_image.width() * (1 - target.x()), m_image.height()); + painter->drawImage(m_targetRect, m_image, source); } } -void WallItem::setAnimationTime(qreal time) +void ProjectedItem::setAnimationTime(qreal time) { QRectF rect = boundingRect(); m_targetRect = QRectF(QPointF(rect.left() + rect.width() * time, rect.top()), rect.bottomRight()); - m_shadowItem->setRect(m_targetRect); + if (m_shadowItem) + m_shadowItem->setRect(m_targetRect); update(); } -static void updateTransform(WallItem *item, const QPointF &a, const QPointF &b, const QPointF &cameraPos, qreal cameraAngle, qreal time) +void ProjectedItem::setImage(const QImage &image) +{ + m_image = image; +} + +void ProjectedItem::updateTransform(const QPointF &cameraPos, qreal cameraAngle, qreal time) { QTransform rotation = rotatingTransform(cameraAngle); rotation.translate(-cameraPos.x(), -cameraPos.y()); - QPointF ca = rotation.map(a); - QPointF cb = rotation.map(b); + QPointF ca = rotation.map(m_a); + QPointF cb = rotation.map(m_b); if (ca.y() <= 0 && cb.y() <= 0) { - item->setVisible(false); + setVisible(false); return; } @@ -324,27 +358,17 @@ static void updateTransform(WallItem *item, const QPointF &a, const QPointF &b, const qreal tz = 0.5 * (ca.y() + cb.y()); const qreal fov = 0.5; - QTransform project(mx, 0, mz * fov, 0, 1, 0, tx, 0.04 * qSin(10 * time), tz * fov); - - item->setVisible(true); - item->setZValue(-tz); - item->setTransform(project); - - item->setDepths(QLineF(QPointF(), ca).length(), QLineF(QPointF(), cb).length()); - - // embed recursive scene - if (QGraphicsProxyWidget *child = item->childItem()) { - View *view = qobject_cast<View *>(child->widget()); - if (view && !view->scene()) { - const char *map = "#$###" - "# #" - "# @ #" - "# #" - "#####"; - MazeScene *embeddedScene = new MazeScene(map, 5, 5); - view->setScene(embeddedScene); - } - } + const QTransform project(mx, 0, mz * fov, 0, 1, 0, tx, 0.04 * qSin(10 * time), tz * fov); + + const qreal za = QLineF(QPointF(), ca).length(); + const qreal zb = QLineF(QPointF(), cb).length(); + const qreal zm = QLineF(QPointF(), (ca + cb) / 2).length(); + + setVisible(true); + setZValue(-zm); + setTransform(project); + + setDepths(za, zb); } void MazeScene::keyPressEvent(QKeyEvent *event) @@ -405,8 +429,26 @@ void MazeScene::move() if (m_dirty) { m_dirty = false; - foreach (WallItem *item, m_walls) - updateTransform(item, item->a(), item->b(), m_cameraPos, m_cameraAngle, m_walkTime * 0.001); + foreach (WallItem *item, m_walls) { + item->updateTransform(m_cameraPos, m_cameraAngle, m_walkTime * 0.001); + if (item->isVisible()) { + // embed recursive scene + if (QGraphicsProxyWidget *child = item->childItem()) { + View *view = qobject_cast<View *>(child->widget()); + if (view && !view->scene()) { + const char *map = "#$###" + "# #" + "# @ #" + "# #" + "#####"; + MazeScene *embeddedScene = new MazeScene(map, 5, 5); + view->setScene(embeddedScene); + } + } + } + } + foreach (Entity *entity, m_entities) + entity->updateTransform(m_cameraPos, m_cameraAngle, m_walkTime * 0.001); setFocusItem(0); // setVisible(true) might give focus to one of the items update(); } @@ -452,3 +494,40 @@ void MazeScene::toggleRenderer() else view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); } + +const QImage toAlpha(const QImage &image) +{ + if (image.isNull()) + return image; + QRgb alpha = image.pixel(0, 0); + QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + QRgb *data = reinterpret_cast<QRgb *>(result.bits()); + int size = image.width() * image.height(); + for (int i = 0; i < size; ++i) + if (data[i] == alpha) + data[i] = 0; + return result; +} + +Entity::Entity(const QPointF &pos) + : ProjectedItem(QRectF(-0.3, -0.3, 0.6, 0.8), false) + , m_pos(pos) +{ + static QImage img = toAlpha(QImage("soldier/O01.png").convertToFormat(QImage::Format_RGB32)); + setImage(img); +} + +void Entity::updateTransform(const QPointF &cameraPos, qreal cameraRotation, qreal time) +{ + QPointF delta = cameraPos - m_pos; + delta /= QLineF(QPointF(), delta).length(); + delta = rotatingTransform(90.1).map(delta); + setPosition(m_pos - delta, m_pos + delta); + ProjectedItem::updateTransform(cameraPos, cameraRotation, time); +} + +void MazeScene::addEntity(Entity *entity) +{ + addItem(entity); + m_entities << entity; +} diff --git a/mazescene.h b/mazescene.h index 4eec9e7..f310082 100644 --- a/mazescene.h +++ b/mazescene.h @@ -16,16 +16,36 @@ public: void resizeEvent(QResizeEvent *event); }; -class WallItem : public QGraphicsItem +class ProjectedItem : public QGraphicsItem { public: - WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int type); + ProjectedItem(const QRectF &bounds, bool shadow = true); QPointF a() const { return m_a; } QPointF b() const { return m_b; } QRectF boundingRect() const; + + void setPosition(const QPointF &a, const QPointF &b); + void updateTransform(const QPointF &cameraPos, qreal cameraRotation, qreal time); + void setDepths(qreal za, qreal zb); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void setAnimationTime(qreal time); + void setImage(const QImage &image); + +private: + QPointF m_a; + QPointF m_b; + QRectF m_bounds; + QRectF m_targetRect; + QImage m_image; + QGraphicsRectItem *m_shadowItem; +}; + +class WallItem : public ProjectedItem +{ +public: + WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int type); QGraphicsProxyWidget *childItem() const { @@ -34,16 +54,19 @@ public: int type() const { return m_type; } - void setDepths(qreal za, qreal zb); - void setAnimationTime(qreal time); - private: - QPointF m_a; - QPointF m_b; QGraphicsProxyWidget *m_childItem; - QGraphicsRectItem *m_shadowItem; int m_type; - QRectF m_targetRect; +}; + +class Entity : public ProjectedItem +{ +public: + Entity(const QPointF &pos); + void updateTransform(const QPointF &cameraPos, qreal cameraRotation, qreal time); + +private: + QPointF m_pos; }; class MazeScene : public QGraphicsScene @@ -52,6 +75,7 @@ class MazeScene : public QGraphicsScene public: MazeScene(const char *map, int width, int height); + void addEntity(Entity *entity); void addWall(const QPointF &a, const QPointF &b, int type); void drawBackground(QPainter *painter, const QRectF &rect); @@ -74,6 +98,7 @@ private: QVector<WallItem *> m_doors; QVector<QGraphicsItem *> m_floorTiles; QVector<QPushButton *> m_buttons; + QVector<Entity *> m_entities; QPointF m_cameraPos; qreal m_cameraAngle; diff --git a/soldier/O01.png b/soldier/O01.png Binary files differnew file mode 100644 index 0000000..9e754f3 --- /dev/null +++ b/soldier/O01.png diff --git a/soldier/O02.png b/soldier/O02.png Binary files differnew file mode 100644 index 0000000..3918443 --- /dev/null +++ b/soldier/O02.png diff --git a/soldier/O03.png b/soldier/O03.png Binary files differnew file mode 100644 index 0000000..22f2fff --- /dev/null +++ b/soldier/O03.png diff --git a/soldier/O04.png b/soldier/O04.png Binary files differnew file mode 100644 index 0000000..0c7ea8c --- /dev/null +++ b/soldier/O04.png diff --git a/soldier/O05.png b/soldier/O05.png Binary files differnew file mode 100644 index 0000000..c541c61 --- /dev/null +++ b/soldier/O05.png diff --git a/soldier/O06.png b/soldier/O06.png Binary files differnew file mode 100644 index 0000000..d91a26b --- /dev/null +++ b/soldier/O06.png diff --git a/soldier/O07.png b/soldier/O07.png Binary files differnew file mode 100644 index 0000000..abff46a --- /dev/null +++ b/soldier/O07.png diff --git a/soldier/O08.png b/soldier/O08.png Binary files differnew file mode 100644 index 0000000..63b20d3 --- /dev/null +++ b/soldier/O08.png diff --git a/soldier/O09.png b/soldier/O09.png Binary files differnew file mode 100644 index 0000000..c7dbbaa --- /dev/null +++ b/soldier/O09.png diff --git a/soldier/O10.png b/soldier/O10.png Binary files differnew file mode 100644 index 0000000..a4ed116 --- /dev/null +++ b/soldier/O10.png diff --git a/soldier/O11.png b/soldier/O11.png Binary files differnew file mode 100644 index 0000000..2b5f535 --- /dev/null +++ b/soldier/O11.png diff --git a/soldier/O12.png b/soldier/O12.png Binary files differnew file mode 100644 index 0000000..f340e38 --- /dev/null +++ b/soldier/O12.png diff --git a/soldier/O13.png b/soldier/O13.png Binary files differnew file mode 100644 index 0000000..04ef91f --- /dev/null +++ b/soldier/O13.png diff --git a/soldier/O14.png b/soldier/O14.png Binary files differnew file mode 100644 index 0000000..d69ec92 --- /dev/null +++ b/soldier/O14.png diff --git a/soldier/O15.png b/soldier/O15.png Binary files differnew file mode 100644 index 0000000..e6ff2a5 --- /dev/null +++ b/soldier/O15.png diff --git a/soldier/O16.png b/soldier/O16.png Binary files differnew file mode 100644 index 0000000..802b664 --- /dev/null +++ b/soldier/O16.png diff --git a/soldier/O17.png b/soldier/O17.png Binary files differnew file mode 100644 index 0000000..9bfcd34 --- /dev/null +++ b/soldier/O17.png diff --git a/soldier/O18.png b/soldier/O18.png Binary files differnew file mode 100644 index 0000000..52e3345 --- /dev/null +++ b/soldier/O18.png diff --git a/soldier/O19.png b/soldier/O19.png Binary files differnew file mode 100644 index 0000000..1e84f81 --- /dev/null +++ b/soldier/O19.png diff --git a/soldier/O20.png b/soldier/O20.png Binary files differnew file mode 100644 index 0000000..38fe974 --- /dev/null +++ b/soldier/O20.png diff --git a/soldier/O21.png b/soldier/O21.png Binary files differnew file mode 100644 index 0000000..6a28fe3 --- /dev/null +++ b/soldier/O21.png diff --git a/soldier/O22.png b/soldier/O22.png Binary files differnew file mode 100644 index 0000000..3682abe --- /dev/null +++ b/soldier/O22.png diff --git a/soldier/O23.png b/soldier/O23.png Binary files differnew file mode 100644 index 0000000..96cf54e --- /dev/null +++ b/soldier/O23.png diff --git a/soldier/O24.png b/soldier/O24.png Binary files differnew file mode 100644 index 0000000..749251f --- /dev/null +++ b/soldier/O24.png diff --git a/soldier/O25.png b/soldier/O25.png Binary files differnew file mode 100644 index 0000000..bb16926 --- /dev/null +++ b/soldier/O25.png diff --git a/soldier/O26.png b/soldier/O26.png Binary files differnew file mode 100644 index 0000000..9b72fa3 --- /dev/null +++ b/soldier/O26.png diff --git a/soldier/O27.png b/soldier/O27.png Binary files differnew file mode 100644 index 0000000..055905d --- /dev/null +++ b/soldier/O27.png diff --git a/soldier/O28.png b/soldier/O28.png Binary files differnew file mode 100644 index 0000000..10fd001 --- /dev/null +++ b/soldier/O28.png diff --git a/soldier/O29.png b/soldier/O29.png Binary files differnew file mode 100644 index 0000000..f3f39f7 --- /dev/null +++ b/soldier/O29.png diff --git a/soldier/O30.png b/soldier/O30.png Binary files differnew file mode 100644 index 0000000..34016ed --- /dev/null +++ b/soldier/O30.png diff --git a/soldier/O31.png b/soldier/O31.png Binary files differnew file mode 100644 index 0000000..a60da51 --- /dev/null +++ b/soldier/O31.png diff --git a/soldier/O32.png b/soldier/O32.png Binary files differnew file mode 100644 index 0000000..1d4498a --- /dev/null +++ b/soldier/O32.png diff --git a/soldier/O33.png b/soldier/O33.png Binary files differnew file mode 100644 index 0000000..ab31f6f --- /dev/null +++ b/soldier/O33.png diff --git a/soldier/O34.png b/soldier/O34.png Binary files differnew file mode 100644 index 0000000..03439cd --- /dev/null +++ b/soldier/O34.png diff --git a/soldier/O35.png b/soldier/O35.png Binary files differnew file mode 100644 index 0000000..9ff4cf9 --- /dev/null +++ b/soldier/O35.png diff --git a/soldier/O36.png b/soldier/O36.png Binary files differnew file mode 100644 index 0000000..aa1ce3f --- /dev/null +++ b/soldier/O36.png diff --git a/soldier/O37.png b/soldier/O37.png Binary files differnew file mode 100644 index 0000000..e5a7c01 --- /dev/null +++ b/soldier/O37.png diff --git a/soldier/O38.png b/soldier/O38.png Binary files differnew file mode 100644 index 0000000..4967e82 --- /dev/null +++ b/soldier/O38.png diff --git a/soldier/O39.png b/soldier/O39.png Binary files differnew file mode 100644 index 0000000..d3a182d --- /dev/null +++ b/soldier/O39.png diff --git a/soldier/O40.png b/soldier/O40.png Binary files differnew file mode 100644 index 0000000..2e7db2e --- /dev/null +++ b/soldier/O40.png |