import QtQuick 2.0
import QtGraphicalEffects 1.0
import HsQML.Model 1.0
Item {
id: c;
property int tilesWide : 8;
property int tilesHigh : 8;
property bool isVirtual : false;
property color bgColor : 'cornsilk';
property double tileSize : Math.floor(Math.min(
width / tilesWide, height / tilesHigh));
property var tileSource : newTileSource();
property var gridModel : newGrid();
property var plumbedGrid : gridModel.plumb();
signal pressedComplete();
property double countDown;
NumberAnimation on countDown {
id: countAnim;
from: 3; to: 0;
duration: 9000;
running: false;
onStopped: volumeAnim.start();
}
property double n : 0;
NumberAnimation on n {
id: volumeAnim;
from: 0; to: 100 + 0.1;
duration: 5000 * (100 + 0.1);
running: false;
}
property bool gameOver :
(!countAnim.running && !volumeAnim.running) ||
n > (plumbedGrid.maxIndex+1) ||
plumbedGrid.leaks.length == 0;
function start() {
tileSource = newTileSource();
gridModel = newGrid();
if (c.isVirtual) {
virtualMouse.pick();
}
countAnim.restart();
volumeAnim.stop();
n = 0;
}
Rectangle {
width: c.tileSize*c.tilesWide;
height: c.tileSize*c.tilesHigh;
color: c.bgColor;
MouseArea {
id: realMouse;
anchors.fill: parent;
hoverEnabled: true;
}
}
Repeater {
anchors.fill: parent;
model: AutoListModel {
mode: AutoListModel.ByKey;
source: {
var rs = plumbedGrid.leaks;
rs.sort(function(a,b) {return a.idx-b.idx;});
return rs;
}
equalityTest: function(a,b) {
a.idx==b.idx && a.colour==b.colour && a.exitA==b.exitA;}
keyFunction: function(a) {return a.x+'-'+a.y;}
}
Leak {
tileSize: c.tileSize;
tileX: modelData.x;
tileY: modelData.y;
colour: modelData.colour;
exitBearing: modelData.exitA;
trigger: n >= modelData.idx;
}
}
Repeater {
id: tiles;
model: AutoListModel {
source: plumbedGrid.plumbing;
mode: AutoListModel.ByKey;
equalityTest: function(a,b) {
return a.idx==b.idx && a.entryA==b.entryA && a.exitA==b.exitA;}
keyFunction: function(a) {return a.x+"-"+a.y;}
}
Plumb {
tileSize: c.tileSize;
x: modelData.x*c.tileSize;
y: modelData.y*c.tileSize;
entryA: modelData.entryA;
exitA: modelData.exitA;
colour: modelData.colour;
label: modelData.colour;
volume: modelData.idx < 0 ?
0 : Math.min(Math.max(c.n-modelData.idx,0),1.1);
}
}
Text {
visible: c.countDown > 0;
anchors.centerIn: parent;
text: Math.floor(c.countDown+1);
font.pixelSize: c.tileSize*2;
scale: 1+Math.ceil(c.countDown)-c.countDown;
opacity: 0.5-(Math.ceil(c.countDown)-c.countDown)/2;
}
Rectangle {
id: mouseView;
property var mouse: c.gameOver ? noMouse :
(c.isVirtual ? virtualMouse : realMouse);
property int tileX: Math.floor(mouse.mouseX/c.tileSize);
property int tileY: Math.floor(mouse.mouseY/c.tileSize);
property bool tilePlacable:
plumbedGrid.isPlacable(Math.floor(c.n), tileX, tileY);
Connections {
target: mouseView.mouse;
onPressed: {
if (mouseView.tilePlacable) {
c.gridModel = c.gridModel.place(
mouseView.tileX, mouseView.tileY, tileSource.top.tile);
c.tileSource = c.tileSource.next;
}
c.pressedComplete();
}
}
visible: mouseView.mouse.containsMouse;
x: tileX*c.tileSize;
y: tileY*c.tileSize;
width: c.tileSize; height: c.tileSize;
color: 'lightgray'; opacity: 0.5;
Text {
visible: !mouseView.tilePlacable;
anchors.centerIn: parent;
color: 'red';
font.pixelSize: c.tileSize;
text: 'X';
}
}
Item {
id: virtualMouse;
property bool done : false;
property bool active : true;
property double oldTileX : 0;
property double oldTileY : 0;
property double tileX : 0;
property double tileY : 0;
property double dur : 0;
Behavior on tileX {
NumberAnimation {
id: animX;
duration: virtualMouse.dur;
}
}
Behavior on tileY {
NumberAnimation {
id: animY;
duration: virtualMouse.dur;
}
}
NumberAnimation {
id: xyAnim;
duration: virtualMouse.dur;
onStopped: virtualMouse.pressed();
}
function pick() {
if (done) return;
gridModel.pick(c.tileSource, tileX, tileY, Math.floor(c.n));
}
focus: true;
Keys.enabled: true;
Keys.onSpacePressed: done = true;
function move(pos) {
dur = 300*Math.max(1,Math.sqrt(
(tileX-pos.x)*(tileX-pos.x)+(tileY-pos.y)*(tileY-pos.y)));
tileX = pos.x;
tileY = pos.y;
xyAnim.start();
}
Connections {
target: c;
onPressedComplete: virtualMouse.pick();
}
Connections {
target: c.gridModel;
onPicked: virtualMouse.move(pos);
}
property int mouseX : (tileX+0.5)*c.tileSize;
property int mouseY : (tileY+0.5)*c.tileSize;
property bool containsMouse : true;
signal pressed();
Image {
visible: mouseView.mouse == virtualMouse;
x: virtualMouse.mouseX; y: virtualMouse.mouseY;
source: 'mouse.svg'
}
}
Item {
id: noMouse;
property int mouseX : 0;
property int mouseY : 0;
property bool containsMouse : false;
signal pressed();
}
}