Add ability to change map border

This commit is contained in:
Marcus Huderle 2018-07-07 17:32:54 -05:00
parent 10b6d3a0d3
commit 5bd88e6fef
12 changed files with 294 additions and 143 deletions

View file

@ -301,6 +301,10 @@ void Editor::onConnectionDirectionChanged(QString newDirection) {
ui->comboBox_ConnectionDirection->blockSignals(false);
}
void Editor::onBorderMetatilesChanged() {
displayMapBorder();
}
void Editor::setConnectionsVisibility(bool visible) {
for (QGraphicsPixmapItem* item : map->connection_items) {
item->setVisible(visible);
@ -383,6 +387,7 @@ void Editor::displayMap() {
);
displayMetatiles();
displayBorderMetatiles();
displayCollisionMetatiles();
displayElevationMetatiles();
displayMapEvents();
@ -398,6 +403,15 @@ void Editor::displayMetatiles() {
scene_metatiles->addItem(metatiles_item);
}
void Editor::displayBorderMetatiles() {
scene_selected_border_metatiles = new QGraphicsScene;
selected_border_metatiles_item = new BorderMetatilesPixmapItem(map);
selected_border_metatiles_item->draw();
scene_selected_border_metatiles->addItem(selected_border_metatiles_item);
connect(selected_border_metatiles_item, SIGNAL(borderMetatilesChanged()), this, SLOT(onBorderMetatilesChanged()));
}
void Editor::displayCollisionMetatiles() {
scene_collision_metatiles = new QGraphicsScene;
collision_metatiles_item = new CollisionMetatilesPixmapItem(map);
@ -792,6 +806,43 @@ void MetatilesPixmapItem::updateSelection(QPointF pos, Qt::MouseButton button) {
}
}
void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
QPointF pos = event->pos();
int x = ((int)pos.x()) / 16;
int y = ((int)pos.y()) / 16;
for (int i = 0; i < map->paint_tile_width && (i + x) < 2; i++) {
for (int j = 0; j < map->paint_tile_height && (j + y) < 2; j++) {
int blockIndex = (j + y) * 2 + (i + x);
int tile = map->getSelectedBlockIndex(map->paint_tile_index + i + (j * 8));
(*map->layout->border->blocks)[blockIndex].tile = tile;
}
}
draw();
emit borderMetatilesChanged();
}
void BorderMetatilesPixmapItem::draw() {
QImage image(32, 32, QImage::Format_RGBA8888);
QPainter painter(&image);
QList<Block> *blocks = map->layout->border->blocks;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
int x = i * 16;
int y = j * 16;
int index = j * 2 + i;
QImage metatile_image = Metatile::getMetatileImage(blocks->value(index).tile, map->layout->tileset_primary, map->layout->tileset_secondary);
QPoint metatile_origin = QPoint(x, y);
painter.drawImage(metatile_origin, metatile_image);
}
painter.end();
setPixmap(QPixmap::fromImage(image));
}
void MovementPermissionsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent* event) {
QPointF pos = event->pos();
int x = ((int)pos.x()) / 16;

View file

@ -16,6 +16,7 @@ class MapPixmapItem;
class CollisionPixmapItem;
class ConnectionPixmapItem;
class MetatilesPixmapItem;
class BorderMetatilesPixmapItem;
class CollisionMetatilesPixmapItem;
class ElevationMetatilesPixmapItem;
@ -36,6 +37,7 @@ public:
void setMap(QString map_name);
void displayMap();
void displayMetatiles();
void displayBorderMetatiles();
void displayCollisionMetatiles();
void displayElevationMetatiles();
void displayMapEvents();
@ -78,9 +80,11 @@ public:
QList<QGraphicsPixmapItem*> borderItems;
QGraphicsScene *scene_metatiles = NULL;
QGraphicsScene *scene_selected_border_metatiles = NULL;
QGraphicsScene *scene_collision_metatiles = NULL;
QGraphicsScene *scene_elevation_metatiles = NULL;
MetatilesPixmapItem *metatiles_item = NULL;
BorderMetatilesPixmapItem *selected_border_metatiles_item = NULL;
CollisionMetatilesPixmapItem *collision_metatiles_item = NULL;
ElevationMetatilesPixmapItem *elevation_metatiles_item = NULL;
@ -123,6 +127,7 @@ private slots:
void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
void onConnectionDirectionChanged(QString newDirection);
void onBorderMetatilesChanged();
signals:
void objectsChanged();
@ -351,6 +356,21 @@ protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
};
class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
BorderMetatilesPixmapItem(Map *map_) {
map = map_;
setAcceptHoverEvents(true);
}
Map* map = NULL;
virtual void draw();
signals:
void borderMetatilesChanged();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent*);
};
class MovementPermissionsPixmapItem : public MetatilesPixmapItem {
Q_OBJECT
public:

View file

@ -166,6 +166,9 @@ void MainWindow::setMap(QString map_name) {
//ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect());
ui->graphicsView_Metatiles->setFixedSize(editor->metatiles_item->pixmap().width() + 2, editor->metatiles_item->pixmap().height() + 2);
ui->graphicsView_BorderMetatile->setScene(editor->scene_selected_border_metatiles);
ui->graphicsView_BorderMetatile->setFixedSize(editor->selected_border_metatiles_item->pixmap().width() + 2, editor->selected_border_metatiles_item->pixmap().height() + 2);
ui->graphicsView_Collision->setScene(editor->scene_collision_metatiles);
//ui->graphicsView_Collision->setSceneRect(editor->scene_collision_metatiles->sceneRect());
ui->graphicsView_Collision->setFixedSize(editor->collision_metatiles_item->pixmap().width() + 2, editor->collision_metatiles_item->pixmap().height() + 2);

View file

@ -60,7 +60,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<property name="tabsClosable">
<bool>false</bool>
@ -290,7 +290,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>614</width>
<width>475</width>
<height>621</height>
</rect>
</property>
@ -478,8 +478,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>180</width>
<height>629</height>
<width>358</width>
<height>612</height>
</rect>
</property>
<property name="sizePolicy">
@ -488,7 +488,10 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_5" rowstretch="0" columnstretch="0">
<layout class="QGridLayout" name="gridLayout_5" rowstretch="0,0" columnstretch="0">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@ -501,16 +504,97 @@
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>8</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Border</string>
</property>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="graphicsView_BorderMetatile">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>48</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGraphicsView" name="graphicsView_Metatiles">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>

107
map.cpp
View file

@ -59,35 +59,6 @@ int Map::getHeight() {
return layout->height.toInt(nullptr, 0);
}
Tileset* Map::getBlockTileset(int metatile_index) {
int primary_size = 0x200;
if (metatile_index < primary_size) {
return layout->tileset_primary;
} else {
return layout->tileset_secondary;
}
}
QList<QList<QRgb>> Map::getBlockPalettes(int metatile_index) {
QList<QList<QRgb>> palettes;
for (int i = 0; i < 6; i++) {
palettes.append(layout->tileset_primary->palettes->at(i));
}
for (int i = 6; i < layout->tileset_secondary->palettes->length(); i++) {
palettes.append(layout->tileset_secondary->palettes->at(i));
}
return palettes;
}
int Map::getBlockIndex(int index) {
int primary_size = 0x200;
if (index < primary_size) {
return index;
} else {
return index - primary_size;
}
}
int Map::getSelectedBlockIndex(int index) {
if (index < layout->tileset_primary->metatiles->length()) {
return index;
@ -104,25 +75,6 @@ int Map::getDisplayedBlockIndex(int index) {
}
}
QImage Map::getMetatileTile(int tile) {
Tileset *tileset = getBlockTileset(tile);
int local_index = getBlockIndex(tile);
if (!tileset || !tileset->tiles) {
return QImage();
}
return tileset->tiles->value(local_index, QImage());
}
Metatile* Map::getMetatile(int index) {
Tileset *tileset = getBlockTileset(index);
int local_index = getBlockIndex(index);
if (!tileset || !tileset->metatiles) {
return NULL;
}
Metatile *metatile = tileset->metatiles->value(local_index, NULL);
return metatile;
}
QImage Map::getCollisionMetatileImage(Block block) {
return getCollisionMetatileImage(block.collision);
}
@ -166,57 +118,6 @@ QImage Map::getElevationMetatileImage(int elevation) {
return metatile_image;
}
QImage Map::getMetatileImage(int tile) {
QImage metatile_image(16, 16, QImage::Format_RGBA8888);
Metatile* metatile = getMetatile(tile);
if (!metatile || !metatile->tiles) {
metatile_image.fill(0xffffffff);
return metatile_image;
}
Tileset* blockTileset = getBlockTileset(tile);
if (!blockTileset) {
metatile_image.fill(0xffffffff);
return metatile_image;
}
QList<QList<QRgb>> palettes = getBlockPalettes(tile);
QPainter metatile_painter(&metatile_image);
for (int layer = 0; layer < 2; layer++)
for (int y = 0; y < 2; y++)
for (int x = 0; x < 2; x++) {
Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
QImage tile_image = getMetatileTile(tile_.tile);
if (tile_image.isNull()) {
// Some metatiles specify tiles that are outside the valid range.
// These are treated as completely transparent, so they can be skipped without
// being drawn.
continue;
}
// Colorize the metatile tiles with its palette.
QList<QRgb> palette = palettes.value(tile_.palette);
for (int j = 0; j < palette.length(); j++) {
tile_image.setColor(j, palette.value(j));
}
// The top layer of the metatile has its last color displayed at transparent.
if (layer > 0) {
QColor color(tile_image.color(15));
color.setAlpha(0);
tile_image.setColor(15, color.rgba());
}
QPoint origin = QPoint(x*8, y*8);
metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
}
metatile_painter.end();
return metatile_image;
}
bool Map::blockChanged(int i, Blockdata *cache) {
if (cache == NULL || cache == nullptr) {
return true;
@ -295,7 +196,7 @@ QPixmap Map::renderCollision(bool ignoreCache) {
}
changed_any = true;
Block block = layout->blockdata->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
QImage collision_metatile_image = getCollisionMetatileImage(block);
QImage elevation_metatile_image = getElevationMetatileImage(block);
int map_y = width_ ? i / width_ : 0;
@ -364,7 +265,7 @@ QPixmap Map::render(bool ignoreCache = false) {
}
changed_any = true;
Block block = layout->blockdata->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
int map_y = width_ ? i / width_ : 0;
int map_x = width_ ? i % width_ : 0;
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
@ -397,7 +298,7 @@ QPixmap Map::renderBorder() {
}
changed_any = true;
Block block = layout->border->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
int map_y = i / width_;
int map_x = i % width_;
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
@ -513,7 +414,7 @@ QPixmap Map::renderMetatiles() {
if (i >= primary_length) {
tile += 0x200 - primary_length;
}
QImage metatile_image = getMetatileImage(tile);
QImage metatile_image = Metatile::getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary);
int map_y = i / width_;
int map_x = i % width_;
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);

7
map.h
View file

@ -135,13 +135,8 @@ public:
static QString bgEventsLabelFromName(QString mapName);
int getWidth();
int getHeight();
Tileset* getBlockTileset(int);
int getBlockIndex(int);
int getSelectedBlockIndex(int);
int getDisplayedBlockIndex(int);
Metatile* getMetatile(int);
QImage getMetatileImage(int);
QImage getMetatileTile(int);
QPixmap render(bool ignoreCache);
QPixmap renderMetatiles();
@ -214,8 +209,6 @@ public:
void hoveredElevationTileChanged(int elevation);
void clearHoveredElevationTile();
QList<QList<QRgb> > getBlockPalettes(int metatile_index);
signals:
void paintTileChanged(Map *map);
void paintCollisionChanged(Map *map);

View file

@ -1,6 +0,0 @@
#include "metatile.h"
Metatile::Metatile()
{
tiles = new QList<Tile>;
}

View file

@ -1,16 +0,0 @@
#ifndef METATILE_H
#define METATILE_H
#include "tile.h"
#include <QList>
class Metatile
{
public:
Metatile();
public:
QList<Tile> *tiles = NULL;
int attr;
};
#endif // METATILE_H

View file

@ -19,7 +19,6 @@ SOURCES += main.cpp\
blockdata.cpp \
block.cpp \
tileset.cpp \
metatile.cpp \
tile.cpp \
event.cpp \
editor.cpp \
@ -34,7 +33,6 @@ HEADERS += mainwindow.h \
blockdata.h \
block.h \
tileset.h \
metatile.h \
tile.h \
event.h \
editor.h \

View file

@ -2,7 +2,6 @@
#include "project.h"
#include "tile.h"
#include "tileset.h"
#include "metatile.h"
#include "event.h"
#include <QDebug>

View file

@ -1,6 +1,112 @@
#include "tileset.h"
#include <QPainter>
#include <QImage>
Tileset::Tileset()
{
}
Metatile::Metatile()
{
tiles = new QList<Tile>;
}
QImage Metatile::getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) {
QImage metatile_image(16, 16, QImage::Format_RGBA8888);
Metatile* metatile = Metatile::getMetatile(tile, primaryTileset, secondaryTileset);
if (!metatile || !metatile->tiles) {
metatile_image.fill(0xffffffff);
return metatile_image;
}
Tileset* blockTileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset);
if (!blockTileset) {
metatile_image.fill(0xffffffff);
return metatile_image;
}
QList<QList<QRgb>> palettes = Metatile::getBlockPalettes(primaryTileset, secondaryTileset);
QPainter metatile_painter(&metatile_image);
for (int layer = 0; layer < 2; layer++)
for (int y = 0; y < 2; y++)
for (int x = 0; x < 2; x++) {
Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
QImage tile_image = Metatile::getMetatileTile(tile_.tile, primaryTileset, secondaryTileset);
if (tile_image.isNull()) {
// Some metatiles specify tiles that are outside the valid range.
// These are treated as completely transparent, so they can be skipped without
// being drawn.
continue;
}
// Colorize the metatile tiles with its palette.
QList<QRgb> palette = palettes.value(tile_.palette);
for (int j = 0; j < palette.length(); j++) {
tile_image.setColor(j, palette.value(j));
}
// The top layer of the metatile has its last color displayed at transparent.
if (layer > 0) {
QColor color(tile_image.color(15));
color.setAlpha(0);
tile_image.setColor(15, color.rgba());
}
QPoint origin = QPoint(x*8, y*8);
metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
}
metatile_painter.end();
return metatile_image;
}
Metatile* Metatile::getMetatile(int index, Tileset *primaryTileset, Tileset *secondaryTileset) {
Tileset *tileset = Metatile::getBlockTileset(index, primaryTileset, secondaryTileset);
int local_index = Metatile::getBlockIndex(index);
if (!tileset || !tileset->metatiles) {
return NULL;
}
Metatile *metatile = tileset->metatiles->value(local_index, NULL);
return metatile;
}
QImage Metatile::getMetatileTile(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) {
Tileset *tileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset);
int local_index = Metatile::getBlockIndex(tile);
if (!tileset || !tileset->tiles) {
return QImage();
}
return tileset->tiles->value(local_index, QImage());
}
Tileset* Metatile::getBlockTileset(int metatile_index, Tileset *primaryTileset, Tileset *secondaryTileset) {
int primary_size = 0x200;
if (metatile_index < primary_size) {
return primaryTileset;
} else {
return secondaryTileset;
}
}
int Metatile::getBlockIndex(int index) {
int primary_size = 0x200;
if (index < primary_size) {
return index;
} else {
return index - primary_size;
}
}
QList<QList<QRgb>> Metatile::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset) {
QList<QList<QRgb>> palettes;
for (int i = 0; i < 6; i++) {
palettes.append(primaryTileset->palettes->at(i));
}
for (int i = 6; i < secondaryTileset->palettes->length(); i++) {
palettes.append(secondaryTileset->palettes->at(i));
}
return palettes;
}

View file

@ -1,9 +1,11 @@
#ifndef TILESET_H
#define TILESET_H
#include "metatile.h"
#include "tile.h"
#include <QImage>
class Metatile;
class Tileset
{
public:
@ -24,4 +26,20 @@ public:
QList<QList<QRgb>> *palettes = NULL;
};
class Metatile
{
public:
Metatile();
public:
QList<Tile> *tiles = NULL;
int attr;
static QImage getMetatileImage(int, Tileset*, Tileset*);
static Metatile* getMetatile(int, Tileset*, Tileset*);
static QImage getMetatileTile(int, Tileset*, Tileset*);
static Tileset* getBlockTileset(int, Tileset*, Tileset*);
static int getBlockIndex(int);
static QList<QList<QRgb>> getBlockPalettes(Tileset*, Tileset*);
};
#endif // TILESET_H