PDA

View Full Version : 4 in a row



vinayaka
16th June 2011, 09:06
Hai all,
I am developing my own ;) 4 in a row game in qt. while we play the ball falls from top to bottom of the grid the problem is that it feels like ball falls over through the grid . But I want the feel that ball falls through inside the grid . I tried what i know? but no use:confused:. Is there any way to do so?
thanx in advance .

Rachol
16th June 2011, 10:40
Could you describe a little more what is your current implementation?

vinayaka
16th June 2011, 11:42
hai rachol,
There is a 7x7 grid(image). There are two players one is comp: and another is user. There are two balls . now the ball falls to the bottom from top when we clicked on the desired position but through over the grid(Image). I want to get a feel that ball is falling through the grid cells and get placed in the position

Rachol
16th June 2011, 11:58
Ok,

But how did you think to implement it?

QGraphicsView or custom QWidgets?

vinayaka
16th June 2011, 12:02
Using QWidgets

wysota
16th June 2011, 12:17
So why are you posting your problem in Qt Quick forum?

vinayaka
16th June 2011, 12:24
by mistake

wysota
16th June 2011, 12:40
So how does your widget look like? How did you implement it?

vinayaka
20th June 2011, 09:32
I named my Qwidget as mainwidget and coded like this:

ui->mainwidget->setStyleSheet("background-image: url(content/Pics/M_CCholder.png); "
"background-position: top left; ");


it works for me but the problem remains the same?

Rachol
20th June 2011, 09:49
Well, because you are setting background to your main widget on top of which all the children widgets are drawn, it doesn't work the way you wished for.

What about placing another backgroundWidget on top of your mainwidget? Or using QStackedLayout::StackAll and having your backgroundWidget being the current widget in the layout?

vinayaka
20th June 2011, 10:56
hai rachol,
I did so and it worked too but there are more than 1 ball. Can you tell me how can I move the ball .Is there any animation property to add to get the ball move?

Added after 6 minutes:

I solved a problem(more than 1 ball problem). but how can I animate the ball

Added after 12 minutes:

Is this the correct way to have one ball

ui->induwidget->setStyleSheet("background-image: url(content/Pics/balla.png); "
"background-position: top left ; background-repeat:none;");

Rachol
20th June 2011, 11:10
I am afraid, you have to do the animation yourself. There isn't such functionality in Qt, unless you are using QML.

vinayaka
20th June 2011, 11:58
so how can I animate that ball. ball is set in Qwidget. can use Qml here to animate ball(i think this is a stupid ?)

Rachol
20th June 2011, 12:16
Please take a look at http://doc.qt.nokia.com/latest/qml-advtutorial.html. I think this would be the best starting point for creating "4 in row" game

wysota
20th June 2011, 13:00
Is there any other code in your application besides stylesheets?

vinayaka
20th June 2011, 13:25
not now . I deleted the codes now In have only stylesheets:)..
if i do this project in qml only is it possible to open pro: in visual studio?

wysota
20th June 2011, 14:01
if i do this project in qml only is it possible to open pro: in visual studio?
Possibility of opening the .pro file in Visual Studio doesn't depend on whether your're using qml or not.

vinayaka
20th June 2011, 14:21
I mean only qml project file with Javascript

wysota
20th June 2011, 14:43
You can open any text file you want in Visual Studio.

vinayaka
21st June 2011, 14:09
hai I cahnged my code to Qml and js



import Qt 4.7


import "content"
import "content/Four_in_a_row.js" as Games

Rectangle {
id: game

property bool running: true
width: display.width; height: display.height + 10

Image {
id: boardImage
source: "content/pics/My_grid.png"
}


Column {
id: display

Grid {
id: board
width: boardImage.width; height: boardImage.height
columns: 3

Repeater {
model: 9

Four {
width: board.width/3
height: board.height/3

onClicked: {
if (game.running && Games.Play(index)) {
if (!Games.Move(index, "k"))
Games.computerTurn();
}
}
}
}
}


}

}


My_grid.png is a grid image. now it work like tic_tac_toe. I want to animate the ball as its falling through the grid(that's my aim).can I use 2 Grid in a qml file? how can I use it?

wysota
21st June 2011, 14:13
What do you need a second grid for?

vinayaka
22nd June 2011, 06:31
When I place grid Image in Grid I get the grid image in front of the ball.but when I put all two(ball and grid image ) in Grid it doesn't .Is it the right way ?

Added after 25 minutes:

I got it now. will be back with another doubt:):cool:

wysota
22nd June 2011, 09:14
You don't have to place each item in a grid. You can place items wherever you want them to be by specifying their X and Y coordinates.

vinayaka
23rd June 2011, 09:26
where should and what I write animation to move the ball? (when we click in the grid a ball will be created I want the ball to fall through the grid image at the clicked column and get placed in the empty position). I used to do it using states and transitions but it doesn't work .Is it the right way to do?

Rachol
23rd June 2011, 09:39
Yes, animations and transitions are the correct way to do it

vinayaka
23rd June 2011, 09:41
sorry rachol i have to edit the prev post . it DOESN'T work for me.

Rachol
23rd June 2011, 09:50
Have you tried this example: http://doc.qt.nokia.com/latest/qml-smoothedanimation.html ?

wysota
23rd June 2011, 10:10
Declare an animation element, attach it to your ball and run the animation.

vinayaka
27th June 2011, 11:23
import Qt 4.7

Item {
signal clicked

states: [
State { name: "a"; PropertyChanges { target: image; source: "pics/balla.png" } },
State { name: "b"; PropertyChanges { target: image; source: "pics/ballb.png" } }
]

Image {
id: image
anchors.centerIn: parent
}

MouseArea {
anchors.fill: parent
onClicked: parent.clicked()
}
}


this is my code for the 2 balls. where should i write animation to move my ball when clicked in a column of my 7X6 grid.

my goal is that if we click in 1st column of the vacant grid it should get placed in last row of that grid and if we again click in the same column ball should get placed 2nd last row the same grid. should I write code in js to get the ball placed? can someone help me?

wysota
27th June 2011, 13:25
You need to declare an Animation element that will do the animation itself and then write a piece of javascript code that will setup and trigger the animation. The script should be invoked upon clicking the column (so probably in some MouseArea element).

vinayaka
28th June 2011, 08:13
Item {
signal clicked
property bool running: true
signal pressed

width: board.width/7
height: board.height/5


states: [
State { name: "You"; PropertyChanges { target: image; source: "content/pics/M_CCblackChess.png" } },
State { name: "Computer"; PropertyChanges { target: image; source: "content/pics/M_CCredChess.png" } }
]

Transition {
to: "you"




NumberAnimation {
target:image
property : "x"
from:0
to:boardImage.width/2 -30
duration:1000
easing.type: Easing.OutBack

}



}

Image {
id: image
anchors.centerIn: parent
}

MouseArea {
id:mousearea
anchors.fill: parent
//onClicked: parent.clicked()
// Animation.running:true
onClicked: {
if (game.running && Logic.canPlayAtPos(index)) {

if (!Logic.makeMove(index, "You"))
Logic.computerTurn();
}
}



}
}


hi wysota, did i code in the correct way? if not plz guide me?

wysota
28th June 2011, 10:24
Not really, I don't see the point of setting up a transition between states. If you want states, then the transition has to occur after a player has made his move, not during that move. You need a simple PropertyAnimation (or similar) that will animate the "y" property of the element clicked.

vinayaka
28th June 2011, 10:45
If you want states, then the transition has to occur after a player has made his move, not during that move

i don't get what you said. so then what should i do ?

wysota
28th June 2011, 11:39
I have already told you twice. Declare a PropertyAnimation element that will animate the "y" property of a stone. When the player clicks the column when the stone is supposed to be dropped, calculate the value of "y" where the stone should be after the drop, assign the value to the animation, bind the stone item with the animation and trigger the animation.

import QtQuick 1.0

Rectangle {

width: 360
height: 360

Rectangle {
id: stone
width: 40
height: width
radius: width
color: "red"
border.width: 2
border.color: "black"
x: 300
y: 30
smooth: true
}
PropertyAnimation {
id: anim
property: "y"


}

MouseArea {
anchors.fill: parent
onClicked: {
anim.loops = 1
anim.target = stone
anim.to = 310
anim.duration = 1000
anim.running = true
}
}
}

vinayaka
28th June 2011, 12:24
thank u wysota
i wrote only animation.running=true. u helped me a lot thanx:)

wysota
28th June 2011, 13:46
Here is my implementation of the game. Somewhat crude but it works.

vinayaka
29th June 2011, 07:54
thanx wysota. but i am not able to open it. it shows error message

Added after 35 minutes:

How can we set a frameless window in qml

wysota
29th June 2011, 08:52
thanx wysota. but i am not able to open it. it shows error message
What error?


How can we set a frameless window in qml
We can't since qml doesn't deal with windows. You have to do that in C++.

Rachol
29th June 2011, 09:13
The archive is corrupt.

wysota
29th June 2011, 09:21
Find a better archive manager. The attachment is fine, I just unpacked it without problems.

vinayaka
29th June 2011, 10:41
thank u very much wysota. I got it . thanx again.....:):):):)

vinayaka
1st July 2011, 08:39
Rectangle {
width: 320
height: 480
id:mainPage

Image {
id: firstPage
width: mainPage.width;height: mainPage.height
source: "pics/M_FCCmainScreen1.jpg"
}


Rectangle{
id:playIcon
width: mainPage.width/5;height: mainPage.height/5
color: "transparent"
x:mainPage.width/4;y:-40
Image {
anchors.fill: parent
id: playImage
source: "pics/M_playDown.png"
}


SequentialAnimation on y {
loops: 1

SmoothedAnimation { target: playIcon; property: "y"; to: 200; duration: 1500; }
// SmoothedAnimation { target: playIcon; property: "x"; to:75; duration: 1500; }
//SmoothedAnimation { target: playIcon; property: ""; to: 400; duration: 1500; }

}




MouseArea{
id:playArea
anchors.fill: parent
onClicked: {
playImage.source="pics/M_playUp.png"
}
}


}
}



In this code when we click in "M_playDown.png" image it get changed to "M_playUp.png". I want to load a new page here asking "who goes first"?. I used Loader here to load the page


MouseArea{

i MouseArea{
id:playArea
anchors.fill: parent
onEntered: {playImage.source="pics/M_playUp.png"}
onClicked: {
loader.source = "Game.qml" }
}


I want it to load in vertical orientation. can some one help me in this.

wysota
1st July 2011, 11:18
What is the problem?

vinayaka
1st July 2011, 11:43
My output is this.

When we click in the play button
[IMG]http://img825.imageshack.us/img825/623/unled12x.png (http://imageshack.us/photo/my-images/825/unled12x.png/)



we get this image.

but at the same time a new page should come from the bottom of the screen asking who goes first( I used Listview and orientation: Qt.Horizontal)but didn't get the desired result(may be problem of my code).

wysota
1st July 2011, 13:54
The code you posted is not enough to determine what is wrong or even what you are trying to do. I would just use a state machine that would slide the screen for me, I certainly don't see a point in using some separate qml file for asking which player should go first (as if it made any difference whatsoever) and I definitely see no use for ListView here.

Using "Behavior on y" and adding an animation there should be enough to do what you want.

import QtQuick 1.0

Rectangle {
width: 360
height: 360
id: rct
Text {
id: txt
anchors.centerIn: parent
text: "Hello World"
}
MouseArea {
anchors.fill: parent
onClicked: {
newtxt.opacity = 1
txt.opacity = 0
newtxt.y = txt.y
}
}

Text {
id: newtxt
text: "Goodbye World"
opacity: 0
y: 360
anchors.horizontalCenter: parent.horizontalCenter

Behavior on y {
SmoothedAnimation { }
}
}
}

vinayaka
6th July 2011, 14:28
thanx
I have more than one page to do so. I mean when we click to the play icon a new page will come from the vertical direction seeking who goes first? if we click an option another page arrives containing 4 in a row game in horizontal direction or if we click cancel icon from this page it wil show the first page (in horizontal direction)

http://img36.imageshack.us/img36/1968/unledhbm.png (http://imageshack.us/photo/my-images/36/unledhbm.png/) [/URL]
how can we inactive a page. Exit game is a new page which comes up when we click main menu icon. but the problem i can still play the game .how can disable that.

wysota
6th July 2011, 16:13
Change opacity of the page to 0. Or disable interactive areas of the page (like MouseArea elements).

vinayaka
8th July 2011, 07:41
hai , mainmenu( in the above image lose it controls after on click).

when we click in the mainmenu exit msg page(i call it as letmeout.qml) is shown with choice letmeout and keep playing. if we click keep playing. the exit msg page's opacity changes to 0. we can play then but have no control on main menu button.it doesn't work anymore

LetMeOut.qml

import QtQuick 1.0
//Exit msg........

Item{
id:exitItem
width: exitAlert.width;height: exitAlert.height
PauseAnimation { id:pausing;duration: 5000 }
//exitAlert open ups...
Rectangle {
id:exitAlert
width: 320
height: 480
color: "#60FFFFFF"
x:-width+width-5
y:-height+60
MouseArea{id:exitAlertArea;anchors.fill: parent;
onClicked: {exitAlert.opacity=0}
}
PropertyAnimation{id:exitAnim;target:exitAlert;pro perty: "x";to:exitAlert.width+200;duration: 2000 }
Image {
width: parent.width/1.1
height: parent.height/2.5
id: exitIcon
source: "pics/M_exitAlertCl.png"
anchors.centerIn: parent
}
//LetMeOut Icon .....
Rectangle{
width: letMeOutImage.width;height: letMeOutImage
id:letMeOutId
color: "transparent"
x:exitIcon.width-259
y:exitIcon.height+90


Image {
id: letMeOutImage
source: "pics/M_letUpCl.png"
}
MouseArea{id:letMeOutArea
anchors.fill:letMeOutImage
onClicked: {
letMeOutImage.source="pics/M_letDownCl.png"
loadFirstPage.source="Mainpage.qml"
keepPlaying.opacity=0

}
}
Loader{id:loadFirstPage
y:-280
x:-exitAlert.width+285
}
}
//LetMeOut Icon ends.....

//////////////////////////////////////////////////////////////

//KeepPlaying starts...../**
Rectangle{

id:keepPlaying
width:keepPlayIcon.width;height: keepPlayIcon.height
color: "transparent"
x:letMeOutId.x+135
y:letMeOutId.y

MouseArea{
id:keepPlayArea
anchors.fill: parent
onPressed: { keepPlayIcon.source="pics/M_keepDownCl.png"}
onClicked: {
exitItem.opacity=0
}
}
Image {
id: keepPlayIcon
source: "pics/M_keepUpCl.png"

}


}


}
//exitAlert closed....
}




Mainmenu

//mainMenu in gamescreen
Rectangle{id:mainMenu
anchors.bottom: playGround1.bottom
width: gameCanvas.width/4;height: gameCanvas.height/8
color: "transparent"
MouseArea{id:menuArea
anchors.fill: mainMenuImage
onClicked: {
loadletmeout.source="LetMeOut.qml"}

}
Image {
id: mainMenuImage
source: "pics/M_mainMenuUp.png"
anchors.centerIn: parent
width: parent.width;height: parent.height
}

Loader {
id: loadletmeout
focus: true
}


}

//mainMenu ends

}

vinayaka
11th July 2011, 06:53
Rectangle{id:mainMenu
anchors.bottom: playGround1.bottom
width: gameCanvas.width/4;height: gameCanvas.height/8
color: "transparent"

Timer {
interval: 500; running: menuArea.pressed ; repeat: true
onTriggered: loadletmeout.source="LetMeOut.qml"
//triggeredOnStart: true
}
Image {
id: mainMenuImage
source: "pics/M_mainMenuUp.png"
anchors.centerIn: parent
width: parent.width;height: parent.height
}
MouseArea{id:menuArea
anchors.fill: parent
onPressed: {loadletmeout.source="LetMeOut.qml"}
}



Loader {
id: loadletmeout
focus: true
}


}


Even if i added Timer Menuarea button doesn't work after one click. Is there any problem in the code? what can I do ?

vinayaka
19th July 2011, 13:45
hai wysota, how can we change the opacity of the win balls from the core.js(in your code). i want to set a state instead of opacity . i did it but the problem is that the rest of the balls state change instead of the win balls. i want to change the first ball's state to state "blue" and second ball to "black". how can i do it? any help would be great.
thanx in advance.

vinayaka
25th July 2011, 14:53
hai this i have a problem in the javascript.
the horizontal position not changes its state when it wins(bottom row works fine, no other rows most of the times donot change its state when it wins). all diagonal and vertical position works well.can you help me i this?(if we command the "diagonall" code all the horizontal win row change its state)


function checkWin(col, row) {
ply = ply == 0 ? 1 : 0
var connected = 1
var connected1 = 1

var curCol = col
var type = board[index(col,row)].type
var connArr = new Array()
connArr.push(board[index(col,row)])

var ind;
// go left
for(var i = col-1; i>=0; i--) {
ind = index(i,row)
if(board[ind]==null) break;
if(board[ind].type != type)
break;
connArr.push(board[ind])
// console.log(board.toString());
connected++;
connected1++;

}
for(var i = col+1; i<=7; i++) {
ind = index(i,row)
if(board[ind]==null) break;
if(board[ind].type != type)
break;
connArr.push(board[ind])
connected++;
connected1++;

}
if(connected<4) {
connArr = []
connArr.push(board[index(col,row)])
connected = 1
connected = 1

}
// go up
for(var i = row-1; i>=0; i--) {
ind = index(col,i)
if(board[ind]==null) break;
if(board[ind].type != type)
break;
connArr.push(board[ind])
connected++;
connected1++;

}

for(var i = row+1; i<=6; i++) {
ind = index(col,i)
if(board[ind]==null) break;
if(board[ind].type != type)
break;
connArr.push( board[ind])
connected++;
connected1++;

}
if(connected<4) {
connArr = []
connArr.push(board[index(col,row)])
connected = 1

}
// go left-up
for(var i = 1; col-i>=0 && row-i>=0; i++) {
ind = index(col-i,row-i)
if(board[index(col-i,row-i)]==null) break;
if(board[index(col-i,row-i)].type != type)
break;
connArr.push( board[ind])
connected++;
}

for(var i = 1; col+i<=5 && row+i<=5; i++) {
ind = index(col+i,row+i)
if(board[index(col+i,row+i)]==null) break;
if(board[index(col+i,row+i)].type != type)
break;
connArr.push( board[ind])
connected++;
}
if(connected<4) {
connArr = []
connArr.push(board[index(col,row)])
connected = 1
}
// go right-up
for(var i = 1; col+i<=6 && row-i>=0; i++) {
ind = index(col+i,row-i)
if(board[index(col+i,row-i)]==null) break;
if(board[index(col+i,row-i)].type != type)
break;
connArr.push( board[ind])
connected++;
}
for(var i = 1; col-i>=0 && row+i<=5; i++) {
ind = index(col-i,row+i)
if(board[index(col-i,row+i)]==null) break;
if(board[index(col-i,row+i)].type != type)
break;
connArr.push( board[ind])
connected++;
}

for(var u=0;u<=42;u++)
{
if(connArr.length==4 && ply==0)
{
connArr[u].state="red"
mainMenu.opacity=0;
playAgain.opacity=1;
help.opacity=0;
quit.opacity=1;
gameFinished1();
scoreBoard.scorer();

}
else if(connArr.length==4 && ply!=0)
{
connArr[u].state="black"
mainMenu.opacity=0;
playAgain.opacity=1;
help.opacity=0;
quit.opacity=1;
gameFinished();
scoreBoard.scoreb();

}
}