QML Advanced Tutorial 3 - Implementing the Game Logic▲
Sélectionnez
/* This script file handles the game logic */
var maxColumn =
10
;
var maxRow =
15
;
var maxIndex =
maxColumn *
maxRow;
var board =
new
Array(maxIndex);
var component;
//Index function used instead of a 2D array
function index(column, row) {
return
column +
(row *
maxColumn);
}
function startNewGame() {
//Calculate board size
maxColumn =
Math.floor(gameCanvas.width /
gameCanvas.blockSize);
maxRow =
Math.floor(gameCanvas.height /
gameCanvas.blockSize);
maxIndex =
maxRow *
maxColumn;
//Close dialogs
dialog.hide();
//Initialize Board
board =
new
Array(maxIndex);
gameCanvas.score =
0
;
for
(var column =
0
; column &
lt; maxColumn; column++
) {
for
(var row =
0
; row &
lt; maxRow; row++
) {
board[index(column, row)] =
null;
createBlock(column, row);
}
}
}
function createBlock(column, row) {
if
(component ==
null)
component =
Qt.createComponent("Block.qml"
);
// Note that if Block.qml was not a local file, component.status would be
// Loading and we should wait for the component's statusChanged() signal to
// know when the file is downloaded and ready before calling createObject().
if
(component.status ==
Component.Ready) {
var dynamicObject =
component.createObject(gameCanvas);
if
(dynamicObject ==
null) {
console.log("error creating block"
);
console.log(component.errorString());
return
false
;
}
dynamicObject.type =
Math.floor(Math.random() *
3
);
dynamicObject.x =
column *
gameCanvas.blockSize;
dynamicObject.y =
row *
gameCanvas.blockSize;
dynamicObject.width =
gameCanvas.blockSize;
dynamicObject.height =
gameCanvas.blockSize;
board[index(column, row)] =
dynamicObject;
}
else
{
console.log("error loading block component"
);
console.log(component.errorString());
return
false
;
}
return
true
;
}
var fillFound; //Set after a floodFill call to the number of blocks found
var floodBoard; //Set to 1 if the floodFill reaches off that node
function handleClick(xPos, yPos) {
var column =
Math.floor(xPos /
gameCanvas.blockSize);
var row =
Math.floor(yPos /
gameCanvas.blockSize);
if
(column &
gt;=
maxColumn ||
column &
lt; 0
||
row &
gt;=
maxRow ||
row &
lt; 0
)
return
;
if
(board[index(column, row)] ==
null)
return
;
//If it's a valid block, remove it and all connected (does nothing if it's not connected)
floodFill(column, row, -
1
);
if
(fillFound &
lt;=
0
)
return
;
gameCanvas.score +=
(fillFound -
1
) *
(fillFound -
1
);
shuffleDown();
victoryCheck();
}
function floodFill(column, row, type) {
if
(board[index(column, row)] ==
null)
return
;
var first =
false
;
if
(type ==
-
1
) {
first =
true
;
type =
board[index(column, row)].type;
//Flood fill initialization
fillFound =
0
;
floodBoard =
new
Array(maxIndex);
}
if
(column &
gt;=
maxColumn ||
column &
lt; 0
||
row &
gt;=
maxRow ||
row &
lt; 0
)
return
;
if
(floodBoard[index(column, row)] ==
1
||
(!
first &
amp;&
amp; type !=
board[index(column, row)].type))
return
;
floodBoard[index(column, row)] =
1
;
floodFill(column +
1
, row, type);
floodFill(column -
1
, row, type);
floodFill(column, row +
1
, type);
floodFill(column, row -
1
, type);
if
(first ==
true
&
amp;&
amp; fillFound ==
0
)
return
; //Can't remove single blocks
board[index(column, row)].opacity =
0
;
board[index(column, row)] =
null;
fillFound +=
1
;
}
function shuffleDown() {
//Fall down
for
(var column =
0
; column &
lt; maxColumn; column++
) {
var fallDist =
0
;
for
(var row =
maxRow -
1
; row &
gt;=
0
; row--
) {
if
(board[index(column, row)] ==
null) {
fallDist +=
1
;
}
else
{
if
(fallDist &
gt; 0
) {
var obj =
board[index(column, row)];
obj.y +=
fallDist *
gameCanvas.blockSize;
board[index(column, row +
fallDist)] =
obj;
board[index(column, row)] =
null;
}
}
}
}
//Fall to the left
var fallDist =
0
;
for
(var column =
0
; column &
lt; maxColumn; column++
) {
if
(board[index(column, maxRow -
1
)] ==
null) {
fallDist +=
1
;
}
else
{
if
(fallDist &
gt; 0
) {
for
(var row =
0
; row &
lt; maxRow; row++
) {
var obj =
board[index(column, row)];
if
(obj ==
null)
continue
;
obj.x -=
fallDist *
gameCanvas.blockSize;
board[index(column -
fallDist, row)] =
obj;
board[index(column, row)] =
null;
}
}
}
}
}
function victoryCheck() {
//Award bonus points if no blocks left
var deservesBonus =
true
;
for
(var column =
maxColumn -
1
; column &
gt;=
0
; column--
)
if
(board[index(column, maxRow -
1
)] !=
null)
deservesBonus =
false
;
if
(deservesBonus)
gameCanvas.score +=
500
;
//Check whether game has finished
if
(deservesBonus ||
!
(floodMoveCheck(0
, maxRow -
1
, -
1
)))
dialog.show("Game Over. Your score is "
+
gameCanvas.score);
}
//only floods up and right, to see if it can find adjacent same-typed blocks
function floodMoveCheck(column, row, type) {
if
(column &
gt;=
maxColumn ||
column &
lt; 0
||
row &
gt;=
maxRow ||
row &
lt; 0
)
return
false
;
if
(board[index(column, row)] ==
null)
return
false
;
var myType =
board[index(column, row)].type;
if
(type ==
myType)
return
true
;
return
floodMoveCheck(column +
1
, row, myType) ||
floodMoveCheck(column, row -
1
, board[index(column, row)].type);
}