summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2008-11-27 19:56:26 +0100
committerSamuel Rødal <sroedal@trolltech.com>2008-11-27 19:57:31 +0100
commitf2fb35cc3a227e8966bab9a9380fe9a543874eb6 (patch)
tree2c2aa66ab21ff5f455425f9f16d1f1c937c9ee61
parent2ec40e64cf4d870c1f86640570b06bb498abcc2f (diff)
Add soldier item.
-rw-r--r--main.cpp8
-rw-r--r--mazescene.cpp193
-rw-r--r--mazescene.h43
-rw-r--r--soldier/O01.pngbin0 -> 1419 bytes
-rw-r--r--soldier/O02.pngbin0 -> 1384 bytes
-rw-r--r--soldier/O03.pngbin0 -> 1266 bytes
-rw-r--r--soldier/O04.pngbin0 -> 1276 bytes
-rw-r--r--soldier/O05.pngbin0 -> 1399 bytes
-rw-r--r--soldier/O06.pngbin0 -> 1305 bytes
-rw-r--r--soldier/O07.pngbin0 -> 1251 bytes
-rw-r--r--soldier/O08.pngbin0 -> 1311 bytes
-rw-r--r--soldier/O09.pngbin0 -> 1377 bytes
-rw-r--r--soldier/O10.pngbin0 -> 1457 bytes
-rw-r--r--soldier/O11.pngbin0 -> 1410 bytes
-rw-r--r--soldier/O12.pngbin0 -> 1297 bytes
-rw-r--r--soldier/O13.pngbin0 -> 1362 bytes
-rw-r--r--soldier/O14.pngbin0 -> 1349 bytes
-rw-r--r--soldier/O15.pngbin0 -> 1394 bytes
-rw-r--r--soldier/O16.pngbin0 -> 1417 bytes
-rw-r--r--soldier/O17.pngbin0 -> 1432 bytes
-rw-r--r--soldier/O18.pngbin0 -> 1472 bytes
-rw-r--r--soldier/O19.pngbin0 -> 1338 bytes
-rw-r--r--soldier/O20.pngbin0 -> 1302 bytes
-rw-r--r--soldier/O21.pngbin0 -> 1400 bytes
-rw-r--r--soldier/O22.pngbin0 -> 1331 bytes
-rw-r--r--soldier/O23.pngbin0 -> 1301 bytes
-rw-r--r--soldier/O24.pngbin0 -> 1399 bytes
-rw-r--r--soldier/O25.pngbin0 -> 1372 bytes
-rw-r--r--soldier/O26.pngbin0 -> 1415 bytes
-rw-r--r--soldier/O27.pngbin0 -> 1394 bytes
-rw-r--r--soldier/O28.pngbin0 -> 1333 bytes
-rw-r--r--soldier/O29.pngbin0 -> 1350 bytes
-rw-r--r--soldier/O30.pngbin0 -> 1369 bytes
-rw-r--r--soldier/O31.pngbin0 -> 1375 bytes
-rw-r--r--soldier/O32.pngbin0 -> 1386 bytes
-rw-r--r--soldier/O33.pngbin0 -> 1440 bytes
-rw-r--r--soldier/O34.pngbin0 -> 1434 bytes
-rw-r--r--soldier/O35.pngbin0 -> 1325 bytes
-rw-r--r--soldier/O36.pngbin0 -> 1294 bytes
-rw-r--r--soldier/O37.pngbin0 -> 1375 bytes
-rw-r--r--soldier/O38.pngbin0 -> 1357 bytes
-rw-r--r--soldier/O39.pngbin0 -> 1293 bytes
-rw-r--r--soldier/O40.pngbin0 -> 1383 bytes
43 files changed, 175 insertions, 69 deletions
diff --git a/main.cpp b/main.cpp
index a27194c..4e872a0 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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
new file mode 100644
index 0000000..9e754f3
--- /dev/null
+++ b/soldier/O01.png
Binary files differ
diff --git a/soldier/O02.png b/soldier/O02.png
new file mode 100644
index 0000000..3918443
--- /dev/null
+++ b/soldier/O02.png
Binary files differ
diff --git a/soldier/O03.png b/soldier/O03.png
new file mode 100644
index 0000000..22f2fff
--- /dev/null
+++ b/soldier/O03.png
Binary files differ
diff --git a/soldier/O04.png b/soldier/O04.png
new file mode 100644
index 0000000..0c7ea8c
--- /dev/null
+++ b/soldier/O04.png
Binary files differ
diff --git a/soldier/O05.png b/soldier/O05.png
new file mode 100644
index 0000000..c541c61
--- /dev/null
+++ b/soldier/O05.png
Binary files differ
diff --git a/soldier/O06.png b/soldier/O06.png
new file mode 100644
index 0000000..d91a26b
--- /dev/null
+++ b/soldier/O06.png
Binary files differ
diff --git a/soldier/O07.png b/soldier/O07.png
new file mode 100644
index 0000000..abff46a
--- /dev/null
+++ b/soldier/O07.png
Binary files differ
diff --git a/soldier/O08.png b/soldier/O08.png
new file mode 100644
index 0000000..63b20d3
--- /dev/null
+++ b/soldier/O08.png
Binary files differ
diff --git a/soldier/O09.png b/soldier/O09.png
new file mode 100644
index 0000000..c7dbbaa
--- /dev/null
+++ b/soldier/O09.png
Binary files differ
diff --git a/soldier/O10.png b/soldier/O10.png
new file mode 100644
index 0000000..a4ed116
--- /dev/null
+++ b/soldier/O10.png
Binary files differ
diff --git a/soldier/O11.png b/soldier/O11.png
new file mode 100644
index 0000000..2b5f535
--- /dev/null
+++ b/soldier/O11.png
Binary files differ
diff --git a/soldier/O12.png b/soldier/O12.png
new file mode 100644
index 0000000..f340e38
--- /dev/null
+++ b/soldier/O12.png
Binary files differ
diff --git a/soldier/O13.png b/soldier/O13.png
new file mode 100644
index 0000000..04ef91f
--- /dev/null
+++ b/soldier/O13.png
Binary files differ
diff --git a/soldier/O14.png b/soldier/O14.png
new file mode 100644
index 0000000..d69ec92
--- /dev/null
+++ b/soldier/O14.png
Binary files differ
diff --git a/soldier/O15.png b/soldier/O15.png
new file mode 100644
index 0000000..e6ff2a5
--- /dev/null
+++ b/soldier/O15.png
Binary files differ
diff --git a/soldier/O16.png b/soldier/O16.png
new file mode 100644
index 0000000..802b664
--- /dev/null
+++ b/soldier/O16.png
Binary files differ
diff --git a/soldier/O17.png b/soldier/O17.png
new file mode 100644
index 0000000..9bfcd34
--- /dev/null
+++ b/soldier/O17.png
Binary files differ
diff --git a/soldier/O18.png b/soldier/O18.png
new file mode 100644
index 0000000..52e3345
--- /dev/null
+++ b/soldier/O18.png
Binary files differ
diff --git a/soldier/O19.png b/soldier/O19.png
new file mode 100644
index 0000000..1e84f81
--- /dev/null
+++ b/soldier/O19.png
Binary files differ
diff --git a/soldier/O20.png b/soldier/O20.png
new file mode 100644
index 0000000..38fe974
--- /dev/null
+++ b/soldier/O20.png
Binary files differ
diff --git a/soldier/O21.png b/soldier/O21.png
new file mode 100644
index 0000000..6a28fe3
--- /dev/null
+++ b/soldier/O21.png
Binary files differ
diff --git a/soldier/O22.png b/soldier/O22.png
new file mode 100644
index 0000000..3682abe
--- /dev/null
+++ b/soldier/O22.png
Binary files differ
diff --git a/soldier/O23.png b/soldier/O23.png
new file mode 100644
index 0000000..96cf54e
--- /dev/null
+++ b/soldier/O23.png
Binary files differ
diff --git a/soldier/O24.png b/soldier/O24.png
new file mode 100644
index 0000000..749251f
--- /dev/null
+++ b/soldier/O24.png
Binary files differ
diff --git a/soldier/O25.png b/soldier/O25.png
new file mode 100644
index 0000000..bb16926
--- /dev/null
+++ b/soldier/O25.png
Binary files differ
diff --git a/soldier/O26.png b/soldier/O26.png
new file mode 100644
index 0000000..9b72fa3
--- /dev/null
+++ b/soldier/O26.png
Binary files differ
diff --git a/soldier/O27.png b/soldier/O27.png
new file mode 100644
index 0000000..055905d
--- /dev/null
+++ b/soldier/O27.png
Binary files differ
diff --git a/soldier/O28.png b/soldier/O28.png
new file mode 100644
index 0000000..10fd001
--- /dev/null
+++ b/soldier/O28.png
Binary files differ
diff --git a/soldier/O29.png b/soldier/O29.png
new file mode 100644
index 0000000..f3f39f7
--- /dev/null
+++ b/soldier/O29.png
Binary files differ
diff --git a/soldier/O30.png b/soldier/O30.png
new file mode 100644
index 0000000..34016ed
--- /dev/null
+++ b/soldier/O30.png
Binary files differ
diff --git a/soldier/O31.png b/soldier/O31.png
new file mode 100644
index 0000000..a60da51
--- /dev/null
+++ b/soldier/O31.png
Binary files differ
diff --git a/soldier/O32.png b/soldier/O32.png
new file mode 100644
index 0000000..1d4498a
--- /dev/null
+++ b/soldier/O32.png
Binary files differ
diff --git a/soldier/O33.png b/soldier/O33.png
new file mode 100644
index 0000000..ab31f6f
--- /dev/null
+++ b/soldier/O33.png
Binary files differ
diff --git a/soldier/O34.png b/soldier/O34.png
new file mode 100644
index 0000000..03439cd
--- /dev/null
+++ b/soldier/O34.png
Binary files differ
diff --git a/soldier/O35.png b/soldier/O35.png
new file mode 100644
index 0000000..9ff4cf9
--- /dev/null
+++ b/soldier/O35.png
Binary files differ
diff --git a/soldier/O36.png b/soldier/O36.png
new file mode 100644
index 0000000..aa1ce3f
--- /dev/null
+++ b/soldier/O36.png
Binary files differ
diff --git a/soldier/O37.png b/soldier/O37.png
new file mode 100644
index 0000000..e5a7c01
--- /dev/null
+++ b/soldier/O37.png
Binary files differ
diff --git a/soldier/O38.png b/soldier/O38.png
new file mode 100644
index 0000000..4967e82
--- /dev/null
+++ b/soldier/O38.png
Binary files differ
diff --git a/soldier/O39.png b/soldier/O39.png
new file mode 100644
index 0000000..d3a182d
--- /dev/null
+++ b/soldier/O39.png
Binary files differ
diff --git a/soldier/O40.png b/soldier/O40.png
new file mode 100644
index 0000000..2e7db2e
--- /dev/null
+++ b/soldier/O40.png
Binary files differ