diff options
| author | Samu Laaksonen <laaksonen.sj@gmail.com> | 2012-12-10 23:47:03 +0200 |
|---|---|---|
| committer | Samu Laaksonen <laaksonen.sj@gmail.com> | 2012-12-10 23:47:03 +0200 |
| commit | ad19e537066742e1a5f9bbb8c3549a47480a33c1 (patch) | |
| tree | 2f48c08f22bea31756f784495d3c50cd9736e889 /src/ActionScene.cpp | |
| parent | 9674c5ea91912d07f4726140ca2c88669c03f874 (diff) | |
| download | prism-ad19e537066742e1a5f9bbb8c3549a47480a33c1.tar.gz prism-ad19e537066742e1a5f9bbb8c3549a47480a33c1.zip | |
Box2d integration
Very crude and buggy
Needs to be much better
Diffstat (limited to 'src/ActionScene.cpp')
| -rw-r--r-- | src/ActionScene.cpp | 654 |
1 files changed, 373 insertions, 281 deletions
diff --git a/src/ActionScene.cpp b/src/ActionScene.cpp index c10bcf6..436d2a8 100644 --- a/src/ActionScene.cpp +++ b/src/ActionScene.cpp @@ -1,281 +1,373 @@ -#include <QPainter> -#include <QPainterPath> -#include <QColor> -#include <QBrush> -#include <QDebug> -#include <QGraphicsPixmapItem> -#include <QGraphicsSceneMouseEvent> -#include <QKeyEvent> - -#include <QSettings> - -#include <QApplication> -#include <QTime> -#include <QFileInfo> -#include <QMessageBox> - -#include "MainWindow.h" -#include "GameView.h" -#include "Hero.h" -#include "ParallaxScrollerStatic.h" -#include "Collectible.h" -#include "HeadsUpDisplay.h" - -#include "layer.h" -#include "objectgroup.h" -#include "mapobject.h" -#include "tile.h" -#include "tilelayer.h" - -#include "Box2D/Dynamics/b2World.h" - -#include "ActionScene.h" - -using Tiled::Map; -using Tiled::MapReader; -using Tiled::OrthogonalRenderer; -using Tiled::Layer; -using Tiled::ObjectGroup; -using Tiled::Tile; -using Tiled::TileLayer; - -ActionScene::ActionScene(const QString &name, const QRectF &rect, GameView *parent) - : GameScene(name, parent) -{ - setSceneRect(rect); - m_clearAlert = false; - m_mapReader = new Tiled::MapReader; - - m_map = 0; - m_mapRenderer = 0; - - m_hud = new HeadsUpDisplay(sceneRect().width(), sceneRect().height(), this, this); - - // start setting up the world here - //b2Vec2 gravity(0.0f, -10.0f); - //m_physicalWorld = new b2World(gravity); - //m_physicalWorld->SetAllowSleeping(true); - - // initialize rand here - qsrand(QTime::currentTime().msec()); - // TODO: implement some logic to randomize color bubbles given to player - - //m_hero = new Hero(this, QPointF(100, 300)); - //connect(m_hero, SIGNAL(removeMe()), this, SLOT(removeSprite())); -} - -ActionScene::~ActionScene() -{ - if (m_map) - delete m_map; - if (m_mapReader) - delete m_mapReader; - if (m_mapRenderer) - delete m_mapRenderer; - - if(m_physicalWorld) - ;//delete m_physicalWorld; -} - -void ActionScene::updateLogic() -{ - if(!m_clearAlert) - { - advance(); - update(); - } -} - -void ActionScene::keyPressEvent(QKeyEvent *event) -{ - QGraphicsScene::keyPressEvent(event); - - switch(event->key()) - { - // arrow up - case 16777235: - break; - // arrow down - case 16777237: - break; - // arrow left - case 16777234: - break; - // arrow right - case 16777236 : - break; - // button a - case 65: - break; - // button s - case 83: - break; - // button d - case 68 : - break; - case 16777216 : - gameView()->changeScene(gameView()->getScene("LevelSelectionScene")); - break; - default: - qDebug() << event->key(); - break; - } -} - -void ActionScene::drawBackground(QPainter *painter, const QRectF &rect) -{ - -} - -void ActionScene::drawForeground(QPainter *painter, const QRectF &rect) -{ - painter->drawPixmap(rect.x(), rect.y(), sceneRect().width(), sceneRect().height(), *m_hud); -} - -void ActionScene::loadMap(QString target) -{ - QFileInfo f(target); - m_levelName = f.fileName(); - - QSettings set; - m_levelScore = set.value(m_levelName).toInt(); - - m_map = m_mapReader->readMap(target); - - if (m_map == NULL) - { - qDebug() << "error:" << m_mapReader->errorString(); - return; - } - - m_mapRenderer = new Tiled::OrthogonalRenderer(m_map); - - qDebug() << "size" << m_map->width() << "x" << m_map->height(); - qDebug() << "layers" << m_map->layerCount(); - - for(int layer = 0; layer < m_map->layerCount(); layer++) - { - QString type = m_map->layerAt(layer)->property("type"); - - if (type == "solid") - { - Tiled::TileLayer* solidTiles = NULL; - solidTiles = m_map->layerAt(layer)->asTileLayer(); - - for(int w = 0; w < solidTiles->width(); w++) - { - for (int h = 0; h < solidTiles->height(); h++) - { - Tiled::Cell cell; - cell = solidTiles->cellAt(w, h); - - if(!cell.isEmpty()) - { - QGraphicsPixmapItem *solidTile = new QGraphicsPixmapItem(0, this); - solidTile->setData(ITEM_OBJECTNAME, QString("SolidGround")); - solidTile->setPos(w * m_map->tileWidth(), - h * m_map->tileHeight()); - solidTile->setZValue(1); - solidTile->setPixmap(cell.tile->image()); - m_mapPixmapItems.append(solidTile); - } - } - } - } - else - { - QImage img(m_map->width() * m_map->tileWidth(), - m_map->height() * m_map->tileHeight(), - QImage::Format_ARGB32); - - QPainter painter(&img); - m_mapRenderer->drawTileLayer(&painter, m_map->layerAt(layer)->asTileLayer()); - - QPixmap mapPixmap = QPixmap::fromImage(img); - m_mapPixmaps.append(mapPixmap); - - qDebug() << "hasAlpha" << mapPixmap.hasAlpha() << "\n" - << "hasAlphaChannel" << mapPixmap.hasAlphaChannel(); - - QGraphicsPixmapItem* mapPixmapItem = addPixmap(mapPixmap); - mapPixmapItem->setPos(0, 0); - mapPixmapItem->setShapeMode(QGraphicsPixmapItem::MaskShape); - - mapPixmapItem->setPixmap(mapPixmap); - - if (type == "covering") - { - mapPixmapItem->setData(ITEM_OBJECTNAME, QString("Covering")); - mapPixmapItem->setZValue(2); - } - else if (type == "coveringBg") - { - mapPixmapItem->setData(ITEM_OBJECTNAME, QString("CoveringBg")); - mapPixmapItem->setZValue(-1); - } - - m_mapPixmapItems.append(mapPixmapItem); - } - } - - QVector<QString> colors; - colors.append("red"); colors.append("blue"); colors.append("green"); - - for (int i = 0; i < colors.size(); i++) - { - Tiled::ObjectGroup* color = NULL; - - if(m_map->indexOfLayer(colors.at(i)) >= 0) - color = m_map->layerAt(m_map->indexOfLayer(colors.at(i)))->asObjectGroup(); - - if(color) - { - Q_FOREACH(Tiled::MapObject *obj, color->objects()) - { - Collectible* colorbubble = new Collectible(0, this); - colorbubble->setData(ITEM_OBJECTNAME, QString(colors.at(i))); - connect(colorbubble, SIGNAL(removeMe()), this, SLOT(removeSprite())); - colorbubble->setPos((obj->x()) * m_map->tileWidth(), - (obj->y() - 1) * m_map->tileHeight()); - - colorbubble->setZValue(1); - - qDebug() << obj->position() << colorbubble->pos(); - } - } - } - - m_clearAlert = false; -} - -void ActionScene::unloadMap() -{ - foreach(QGraphicsPixmapItem* removableItem, m_mapPixmapItems) - { - removeItem(removableItem); - } - - for(int i = m_mapPixmapItems.size() - 1; i > 0; i++) - delete m_mapPixmapItems.at(i); - - m_mapPixmapItems.clear(); - - m_mapPixmaps.clear(); - - if (m_mapRenderer) - delete m_mapRenderer; - if (m_map) - delete m_map; -} - -void ActionScene::removeSprite() -{ - qDebug() << "removing a sprite"; - - Sprite* sp = (Sprite*) sender(); - if(sp) - { - removeItem(sp); - sp->deleteLater(); - } -} +#include <QPainter>
+#include <QPainterPath>
+#include <QColor>
+#include <QBrush>
+#include <QDebug>
+#include <QGraphicsPixmapItem>
+#include <QGraphicsSceneMouseEvent>
+#include <QKeyEvent>
+
+#include <QSettings>
+
+#include <QApplication>
+#include <QTime>
+#include <QFileInfo>
+#include <QMessageBox>
+
+#include "MainWindow.h"
+#include "GameView.h"
+#include "Hero.h"
+#include "ParallaxScrollerStatic.h"
+#include "Collectible.h"
+#include "HeadsUpDisplay.h"
+
+#include "layer.h"
+#include "objectgroup.h"
+#include "mapobject.h"
+#include "tile.h"
+#include "tilelayer.h"
+
+#include "Box2d/Dynamics/b2World.h"
+#include "Box2d/Dynamics/b2Fixture.h"
+#include "Box2d/Collision/Shapes/b2PolygonShape.h"
+#include "Box2d/Collision/Shapes/b2EdgeShape.h"
+
+#include "common.h"
+
+#include "ActionScene.h"
+
+using Tiled::Map;
+using Tiled::MapReader;
+using Tiled::OrthogonalRenderer;
+using Tiled::Layer;
+using Tiled::ObjectGroup;
+using Tiled::Tile;
+using Tiled::TileLayer;
+
+ActionScene::ActionScene(const QString &name, const QRectF &rect, GameView *parent)
+ : GameScene(name, parent)
+{
+ setSceneRect(rect);
+ m_clearAlert = false;
+ m_mapReader = new Tiled::MapReader;
+
+ m_map = 0;
+ m_mapRenderer = 0;
+
+ m_hud = new HeadsUpDisplay(sceneRect().width(), sceneRect().height(), this, this);
+
+ // start setting up the world here
+ b2Vec2 gravity(0.0f, 10.0f);
+ m_world = new b2World(gravity);
+ m_world->SetAllowSleeping(true);
+
+ // initialize rand here
+ qsrand(QTime::currentTime().msec());
+ // TODO: implement some logic to randomize color bubbles given to player
+
+ QString appDir = qApp->applicationDirPath();
+
+ m_hero = new Hero(this, QPointF(150, 150));
+ m_hero->loadAnimations(QString(appDir + "/data/gfx/characters/hero/"));
+
+ //connect(m_hero, SIGNAL(removeMe()), this, SLOT(removeSprite()));
+}
+
+ActionScene::~ActionScene()
+{
+ if (m_map)
+ delete m_map;
+ if (m_mapReader)
+ delete m_mapReader;
+ if (m_mapRenderer)
+ delete m_mapRenderer;
+
+ if(m_world)
+ delete m_world;
+}
+
+void ActionScene::updateLogic()
+{
+ if(!m_clearAlert)
+ {
+ // Collision logic through sheer awesomeness of Box2D, FTW.
+ m_world->Step(1.0f / FPS, 5, 5);
+ m_world->ClearForces();
+
+ advance();
+ update();
+ m_hud->update();
+ }
+}
+
+void ActionScene::keyPressEvent(QKeyEvent *event)
+{
+ //QGraphicsScene::keyPressEvent(event);
+
+ b2Body *body = m_hero->getFixture()->GetBody();
+
+ switch(event->key())
+ {
+ // arrow up
+ case 16777235:
+ body->ApplyForce(b2Vec2(5.0f, -20.0f), body->GetWorldCenter());
+ break;
+ // arrow down
+ case 16777237:
+ break;
+ // arrow left
+ case 16777234:
+ body->ApplyForce(b2Vec2(-10.0f, 0), body->GetWorldCenter());
+ break;
+ // arrow right
+ case 16777236 :
+ body->ApplyForce(b2Vec2(10.0f, 0), body->GetWorldCenter());
+ break;
+ // button a
+ case 65:
+ m_hud->toggleRedColor();
+ m_hero->toggleRedColor();
+ break;
+ // button s
+ case 83:
+ m_hud->toggleGreenColor();
+ m_hero->toggleGreenColor();
+ break;
+ // button d
+ case 68 :
+ m_hud->toggleBlueColor();
+ m_hero->toggleBlueColor();
+ break;
+ case 16777216 :
+ gameView()->changeScene(gameView()->getScene("LevelSelectionScene"));
+ break;
+ default:
+ qDebug() << event->key();
+ break;
+ }
+}
+
+void ActionScene::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ return;
+}
+
+void ActionScene::drawForeground(QPainter *painter, const QRectF &rect)
+{
+ //painter->drawPixmap(rect.x(), rect.y(), sceneRect().width(), sceneRect().height(), *m_hud);
+}
+
+void ActionScene::addBlock(const QRectF &rect, const QPointF &pos, QGraphicsPixmapItem* tile)
+{
+ b2BodyDef def;
+ def.position.Set(P2M(pos.x()), P2M(pos.y()));
+ def.userData = tile;
+ b2Body *body = m_world->CreateBody(&def);
+
+ b2PolygonShape box;
+ box.SetAsBox(P2M(rect.width()/2), P2M(rect.height()/2),
+ b2Vec2(P2M(rect.width()/2), P2M(rect.height()/2)), 0);
+
+ b2Fixture *fixture = body->CreateFixture(&box, 0);
+
+ b2Filter filter;
+ fixture->SetFilterData(filter);
+
+ // Setup a circular reference, we can get the body from the item
+ // and the item from the body. Dunno if needed though :-)
+ tile->setData(0, qVariantFromValue(static_cast<void *>(fixture)));
+}
+
+void ActionScene::addBlock(qreal w, qreal h, qreal x, qreal y, QGraphicsPixmapItem* tile)
+{
+ addBlock(QRectF(0, 0, w, h), QPointF(x, y), tile);
+}
+
+void ActionScene::addEdge(const b2Vec2 &v1, const b2Vec2 &v2)
+{
+ QGraphicsLineItem *li = new QGraphicsLineItem(M2P(v1.x), M2P(v1.y),
+ M2P(v2.x), M2P(v2.y));
+ li->setPen(QPen(Qt::transparent));
+ addItem(li);
+
+ b2BodyDef def;
+ b2Body *body = m_world->CreateBody(&def);
+
+ b2EdgeShape edge;
+ edge.Set(v1, v2);
+
+ b2FixtureDef fixdef;
+ fixdef.friction = 0.25f;
+ fixdef.density = 0;
+ fixdef.shape = &edge;
+ fixdef.userData = li;
+
+ b2Fixture *fixture = body->CreateFixture(&fixdef);
+
+ // Setup a circular reference, we can get the fixture from the item
+ // and the item from the fixture. Dunno if needed though :-)
+ li->setData(0, qVariantFromValue(static_cast<void *>(fixture)));
+}
+
+void ActionScene::loadMap(QString target)
+{
+ QFileInfo f(target);
+ m_levelName = f.fileName();
+
+ QSettings set;
+ m_levelScore = set.value(m_levelName).toInt();
+
+ m_map = m_mapReader->readMap(target);
+
+ if (m_map == NULL)
+ {
+ qDebug() << "error:" << m_mapReader->errorString();
+ return;
+ }
+
+ m_mapRenderer = new Tiled::OrthogonalRenderer(m_map);
+
+ qDebug() << "size" << m_map->width() << "x" << m_map->height();
+ qDebug() << "layers" << m_map->layerCount();
+
+ for(int layer = 0; layer < m_map->layerCount(); layer++)
+ {
+ QString type = m_map->layerAt(layer)->property("type");
+
+ if (type == "solid")
+ {
+ Tiled::TileLayer* solidTiles = NULL;
+ solidTiles = m_map->layerAt(layer)->asTileLayer();
+
+ for(int w = 0; w < solidTiles->width(); w++)
+ {
+ for (int h = 0; h < solidTiles->height(); h++)
+ {
+ Tiled::Cell cell;
+ cell = solidTiles->cellAt(w, h);
+
+ if(!cell.isEmpty())
+ {
+ QGraphicsPixmapItem *solidTile = new QGraphicsPixmapItem(0, this);
+ solidTile->setData(ITEM_OBJECTNAME, QString("SolidGround"));
+ solidTile->setPos(w * m_map->tileWidth(),
+ h * m_map->tileHeight());
+ solidTile->setZValue(1);
+ solidTile->setPixmap(cell.tile->image());
+ addBlock(m_map->tileWidth(), m_map->tileHeight(),
+ w * m_map->tileWidth(),
+ h * m_map->tileHeight(),
+ solidTile);
+ m_mapPixmapItems.append(solidTile);
+ }
+ }
+ }
+ }
+ else
+ {
+ QImage img(m_map->width() * m_map->tileWidth(),
+ m_map->height() * m_map->tileHeight(),
+ QImage::Format_ARGB32);
+
+ QPainter painter(&img);
+ m_mapRenderer->drawTileLayer(&painter, m_map->layerAt(layer)->asTileLayer());
+
+ QPixmap mapPixmap = QPixmap::fromImage(img);
+ m_mapPixmaps.append(mapPixmap);
+
+ qDebug() << "hasAlpha" << mapPixmap.hasAlpha() << "\n"
+ << "hasAlphaChannel" << mapPixmap.hasAlphaChannel();
+
+ QGraphicsPixmapItem* mapPixmapItem = addPixmap(mapPixmap);
+ mapPixmapItem->setPos(0, 0);
+ mapPixmapItem->setShapeMode(QGraphicsPixmapItem::MaskShape);
+
+ mapPixmapItem->setPixmap(mapPixmap);
+
+ if (type == "covering")
+ {
+ mapPixmapItem->setData(ITEM_OBJECTNAME, QString("Covering"));
+ mapPixmapItem->setZValue(2);
+ }
+ else if (type == "coveringBg")
+ {
+ mapPixmapItem->setData(ITEM_OBJECTNAME, QString("CoveringBg"));
+ mapPixmapItem->setZValue(-1);
+ }
+
+ m_mapPixmapItems.append(mapPixmapItem);
+ }
+ }
+
+ QVector<QString> colors;
+ colors.append("red"); colors.append("blue"); colors.append("green");
+
+ for (int i = 0; i < colors.size(); i++)
+ {
+ Tiled::ObjectGroup* color = NULL;
+
+ if(m_map->indexOfLayer(colors.at(i)) >= 0)
+ color = m_map->layerAt(m_map->indexOfLayer(colors.at(i)))->asObjectGroup();
+
+ if(color)
+ {
+ Q_FOREACH(Tiled::MapObject *obj, color->objects())
+ {
+ Collectible* colorbubble = new Collectible(0, this);
+ colorbubble->setData(ITEM_OBJECTNAME, QString(colors.at(i)));
+ connect(colorbubble, SIGNAL(removeMe()), this, SLOT(removeSprite()));
+ colorbubble->setPos((obj->x()) * m_map->tileWidth(),
+ (obj->y() - 1) * m_map->tileHeight());
+
+ colorbubble->setZValue(1);
+
+ qDebug() << obj->position() << colorbubble->pos();
+ }
+ }
+ }
+
+ const int w = sceneRect().width() / 8;
+ const int h = sceneRect().height();
+ // top, bottom, left, right walls
+ addEdge(b2Vec2(0, 0), b2Vec2(P2M(w), 0));
+ addEdge(b2Vec2(0, P2M(h-1)), b2Vec2(P2M(w), P2M(h-1)));
+ addEdge(b2Vec2(0, 0), b2Vec2(0, P2M(h)));
+ addEdge(b2Vec2(P2M(w-1), 0), b2Vec2(P2M(w-1), P2M(h)));
+
+ m_hero->bindToWorld(m_world);
+ m_hero->updatePosition(100, 100);
+
+ m_clearAlert = false;
+}
+
+void ActionScene::unloadMap()
+{
+ foreach(QGraphicsPixmapItem* removableItem, m_mapPixmapItems)
+ {
+ removeItem(removableItem);
+ }
+
+ for(int i = m_mapPixmapItems.size() - 1; i > 0; i++)
+ delete m_mapPixmapItems.at(i);
+
+ m_mapPixmapItems.clear();
+
+ m_mapPixmaps.clear();
+
+ if (m_mapRenderer)
+ delete m_mapRenderer;
+ if (m_map)
+ delete m_map;
+}
+
+void ActionScene::removeSprite()
+{
+ qDebug() << "removing a sprite";
+
+ Sprite* sp = (Sprite*) sender();
+ if(sp)
+ {
+ removeItem(sp);
+ sp->deleteLater();
+ }
+}
|
