Browse Source

Support multi-block painting

Marcus Huderle 6 years ago
parent
commit
940fb1b65c
4 changed files with 57 additions and 21 deletions
  1. 44
    17
      editor.cpp
  2. 2
    1
      editor.h
  3. 5
    3
      map.cpp
  4. 6
    0
      map.h

+ 44
- 17
editor.cpp View File

271
     setPixmap(map->renderMetatiles());
271
     setPixmap(map->renderMetatiles());
272
 }
272
 }
273
 
273
 
274
-void MetatilesPixmapItem::pick(uint tile) {
275
-    map->paint_tile = tile;
276
-    emit map->paintTileChanged(map);
277
-}
278
-
279
 void MetatilesPixmapItem::updateCurHoveredMetatile(QPointF pos) {
274
 void MetatilesPixmapItem::updateCurHoveredMetatile(QPointF pos) {
280
     int x = ((int)pos.x()) / 16;
275
     int x = ((int)pos.x()) / 16;
281
     int y = ((int)pos.y()) / 16;
276
     int y = ((int)pos.y()) / 16;
299
     QPointF pos = event->pos();
294
     QPointF pos = event->pos();
300
     int x = ((int)pos.x()) / 16;
295
     int x = ((int)pos.x()) / 16;
301
     int y = ((int)pos.y()) / 16;
296
     int y = ((int)pos.y()) / 16;
302
-    //qDebug() << QString("(%1, %2)").arg(x).arg(y);
303
-    int width = pixmap().width() / 16;
304
-    int height = pixmap().height() / 16;
305
-    if ((x >= 0 && x < width) && (y >=0 && y < height)) {
306
-        pick(y * width + x);
307
-    }
297
+    map->paint_metatile_initial_x = x;
298
+    map->paint_metatile_initial_y = y;
299
+    updateSelection(event->pos());
308
 }
300
 }
309
 void MetatilesPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
301
 void MetatilesPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
310
     updateCurHoveredMetatile(event->pos());
302
     updateCurHoveredMetatile(event->pos());
311
-    mousePressEvent(event);
303
+    updateSelection(event->pos());
312
 }
304
 }
313
 void MetatilesPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
305
 void MetatilesPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
314
-    mousePressEvent(event);
306
+    updateSelection(event->pos());
307
+}
308
+void MetatilesPixmapItem::updateSelection(QPointF pos) {
309
+    int x = ((int)pos.x()) / 16;
310
+    int y = ((int)pos.y()) / 16;
311
+    int width = pixmap().width() / 16;
312
+    int height = pixmap().height() / 16;
313
+    if ((x >= 0 && x < width) && (y >=0 && y < height)) {
314
+        int baseTileX = x < map->paint_metatile_initial_x ? x : map->paint_metatile_initial_x;
315
+        int baseTileY = y < map->paint_metatile_initial_y ? y : map->paint_metatile_initial_y;
316
+        map->paint_tile = baseTileY * 8 + baseTileX;
317
+        map->paint_tile_width = abs(map->paint_metatile_initial_x - x) + 1;
318
+        map->paint_tile_height = abs(map->paint_metatile_initial_y - y) + 1;
319
+        emit map->paintTileChanged(map);
320
+    }
315
 }
321
 }
316
 
322
 
317
 void CollisionMetatilesPixmapItem::updateCurHoveredMetatile(QPointF pos) {
323
 void CollisionMetatilesPixmapItem::updateCurHoveredMetatile(QPointF pos) {
345
         QPointF pos = event->pos();
351
         QPointF pos = event->pos();
346
         int x = (int)(pos.x()) / 16;
352
         int x = (int)(pos.x()) / 16;
347
         int y = (int)(pos.y()) / 16;
353
         int y = (int)(pos.y()) / 16;
348
-        Block *block = map->getBlock(x, y);
349
-        if (block) {
350
-            block->tile = map->paint_tile;
351
-            map->_setBlock(x, y, *block);
354
+        // Snap the selected position to the top-left of the block boundary.
355
+        // This allows painting via dragging the mouse to tile the painted region.
356
+        int xDiff = x - map->paint_tile_initial_x;
357
+        int yDiff = y - map->paint_tile_initial_y;
358
+        if (xDiff < 0 && xDiff % map->paint_tile_width != 0) xDiff -= map->paint_tile_width;
359
+        if (yDiff < 0 && yDiff % map->paint_tile_height != 0) yDiff -= map->paint_tile_height;
360
+
361
+        x = map->paint_tile_initial_x + (xDiff / map->paint_tile_width) * map->paint_tile_width;
362
+        y = map->paint_tile_initial_y + (yDiff / map->paint_tile_height) * map->paint_tile_height;
363
+        for (int i = 0; i < map->paint_tile_width && i + x < map->getWidth(); i++)
364
+        for (int j = 0; j < map->paint_tile_height && j + y < map->getHeight(); j++) {
365
+            int actualX = i + x;
366
+            int actualY = j + y;
367
+            Block *block = map->getBlock(actualX, actualY);
368
+            if (block) {
369
+                block->tile = map->paint_tile + i + (j * 8);
370
+                map->_setBlock(actualX, actualY, *block);
371
+            }
352
         }
372
         }
353
         if (event->type() == QEvent::GraphicsSceneMouseRelease) {
373
         if (event->type() == QEvent::GraphicsSceneMouseRelease) {
354
             map->commit();
374
             map->commit();
374
     Block *block = map->getBlock(x, y);
394
     Block *block = map->getBlock(x, y);
375
     if (block) {
395
     if (block) {
376
         map->paint_tile = block->tile;
396
         map->paint_tile = block->tile;
397
+        map->paint_tile_width = 1;
398
+        map->paint_tile_height = 1;
377
         emit map->paintTileChanged(map);
399
         emit map->paintTileChanged(map);
378
     }
400
     }
379
 }
401
 }
451
     map->clearHoveredTile();
473
     map->clearHoveredTile();
452
 }
474
 }
453
 void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
475
 void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
476
+    QPointF pos = event->pos();
477
+    int x = ((int)pos.x()) / 16;
478
+    int y = ((int)pos.y()) / 16;
479
+    map->paint_tile_initial_x = x;
480
+    map->paint_tile_initial_y = y;
454
     emit mouseEvent(event, this);
481
     emit mouseEvent(event, this);
455
 }
482
 }
456
 void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
483
 void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {

+ 2
- 1
editor.h View File

248
         connect(map, SIGNAL(paintTileChanged(Map*)), this, SLOT(paintTileChanged(Map *)));
248
         connect(map, SIGNAL(paintTileChanged(Map*)), this, SLOT(paintTileChanged(Map *)));
249
     }
249
     }
250
     Map* map = NULL;
250
     Map* map = NULL;
251
-    virtual void pick(uint);
252
     virtual void draw();
251
     virtual void draw();
252
+private:
253
+    void updateSelection(QPointF pos);
253
 protected:
254
 protected:
254
     virtual void updateCurHoveredMetatile(QPointF pos);
255
     virtual void updateCurHoveredMetatile(QPointF pos);
255
 private slots:
256
 private slots:

+ 5
- 3
map.cpp View File

454
     int y = i / w;
454
     int y = i / w;
455
     painter->save();
455
     painter->save();
456
     painter->setPen(QColor(0xff, 0xff, 0xff));
456
     painter->setPen(QColor(0xff, 0xff, 0xff));
457
-    painter->drawRect(x * 16, y * 16, 15, 15);
457
+    int rectWidth = paint_tile_width * 16;
458
+    int rectHeight = paint_tile_height * 16;
459
+    painter->drawRect(x * 16, y * 16, rectWidth - 1, rectHeight -1);
458
     painter->setPen(QColor(0, 0, 0));
460
     painter->setPen(QColor(0, 0, 0));
459
-    painter->drawRect(x * 16 - 1, y * 16 - 1, 17, 17);
460
-    painter->drawRect(x * 16 + 1, y * 16 + 1, 13, 13);
461
+    painter->drawRect(x * 16 - 1, y * 16 - 1, rectWidth + 1, rectHeight + 1);
462
+    painter->drawRect(x * 16 + 1, y * 16 + 1, rectWidth - 3, rectHeight - 3);
461
     painter->restore();
463
     painter->restore();
462
 }
464
 }
463
 
465
 

+ 6
- 0
map.h View File

138
     QImage image;
138
     QImage image;
139
     QPixmap pixmap;
139
     QPixmap pixmap;
140
     QList<QImage> metatile_images;
140
     QList<QImage> metatile_images;
141
+    int paint_metatile_initial_x;
142
+    int paint_metatile_initial_y;
141
     int paint_tile;
143
     int paint_tile;
144
+    int paint_tile_width = 1;
145
+    int paint_tile_height = 1;
146
+    int paint_tile_initial_x;
147
+    int paint_tile_initial_y;
142
     int paint_collision;
148
     int paint_collision;
143
     int paint_elevation;
149
     int paint_elevation;
144
 
150