Offer me a good QML exercise
-
Hi,
I've read this online book until this section, end of chapter 5. And also practiced almost all examples. Now I want to test myself by an exercise. I haven't started chapter 6 yet.
According to these 5 chapters, what exercise do you offer me please?
The exercise should be good but not too hard. :)
I may also request assistance during solving it if I can't cope with that.Tanks.
-
Hi,
I've read this online book until this section, end of chapter 5. And also practiced almost all examples. Now I want to test myself by an exercise. I haven't started chapter 6 yet.
According to these 5 chapters, what exercise do you offer me please?
The exercise should be good but not too hard. :)
I may also request assistance during solving it if I can't cope with that.Tanks.
@tomy hi,
the first thing, that comes to my mind, seeing states and animations covered in this section, would be a basic an intersection similator.- Implementing the logic of trafic lights for the most efficient trafficflow
- Car animation, picture of car, accelerating, decelerating or consistant speed depending on the current state of the traffic light
- If you're feeling adventurous add a button for the User to insert cars into the system.
Last part would most likly the most difficult one.
But, thats just my idea, maybe someone else has a better one :)
-
Hi! If you really have no idea, make a good old pocket calculator. Otherwise I'd say, don't waste your time on throw-away-code but start building something useful.
-
@tomy hi,
the first thing, that comes to my mind, seeing states and animations covered in this section, would be a basic an intersection similator.- Implementing the logic of trafic lights for the most efficient trafficflow
- Car animation, picture of car, accelerating, decelerating or consistant speed depending on the current state of the traffic light
- If you're feeling adventurous add a button for the User to insert cars into the system.
Last part would most likly the most difficult one.
But, thats just my idea, maybe someone else has a better one :)
@J.Hilk
Hi,
It seems very good. A wide picture! It will be 3D I think.
(Although I didn't mean only the last chapter, 5, all chapters 1 to 5!) :)Is it useful as well, or just a test criterion for me!? I'm ready to get my hands dirty but what about this idea:
Up to now I've created a very good calculator program and a spreadsheet app using Qt. Although I'm not as familiar with QML as Qt but what's your opinion to plan the infrastructure of a good & useful QML app?
If you agree, of course, I can fill the blanks of the puzzle (the whole useful program) using what I've learnt until now, and go on and complete the app alongside with reading and progressing with the next chapters of the book, until the program will be completed and useful for users. -
@tomy hi,
the first thing, that comes to my mind, seeing states and animations covered in this section, would be a basic an intersection similator.- Implementing the logic of trafic lights for the most efficient trafficflow
- Car animation, picture of car, accelerating, decelerating or consistant speed depending on the current state of the traffic light
- If you're feeling adventurous add a button for the User to insert cars into the system.
Last part would most likly the most difficult one.
But, thats just my idea, maybe someone else has a better one :)
-
Hi! If you really have no idea, make a good old pocket calculator. Otherwise I'd say, don't waste your time on throw-away-code but start building something useful.
-
@J.Hilk
Hi,
It seems very good. A wide picture! It will be 3D I think.
(Although I didn't mean only the last chapter, 5, all chapters 1 to 5!) :)Is it useful as well, or just a test criterion for me!? I'm ready to get my hands dirty but what about this idea:
Up to now I've created a very good calculator program and a spreadsheet app using Qt. Although I'm not as familiar with QML as Qt but what's your opinion to plan the infrastructure of a good & useful QML app?
If you agree, of course, I can fill the blanks of the puzzle (the whole useful program) using what I've learnt until now, and go on and complete the app alongside with reading and progressing with the next chapters of the book, until the program will be completed and useful for users.@tomy
hi, sory for the late reply, I was away, friday till monday.3d is cool, I myself have jet to really do anything in 3D, so I would not be able to help you much.
If you have a clear idea of an program in mind, that would be useful for you, than there is no need to go for the intersection.
The intersection is just an idea for when you're bored. Go with your idea :-)
-
@tomy
hi, sory for the late reply, I was away, friday till monday.3d is cool, I myself have jet to really do anything in 3D, so I would not be able to help you much.
If you have a clear idea of an program in mind, that would be useful for you, than there is no need to go for the intersection.
The intersection is just an idea for when you're bored. Go with your idea :-)
@J.Hilk
Hi my friend. Thanks for having you.What about a simple game. I've seen it but have forgotten its name for the time being but allow me please to describe it.
There is room in which there is a ball. The gamer has a plate in hand at the bottom of the room. The ball comes down from up, naturally. The gamer moves the plate at the bottom of the room to the position the ball is coming down that way hitting and making it go up again. If the user doesn't move the plate properly and fast, the ball hits the bottom of the room and the game is over. With passing the time and the gamer's not allowing the ball to hit the bottom of the room, the speed of moving of the ball increases and the score of the user also goes upper! The winner between gamers is the one who gets the highest score.
What do you think of this? :) -
@J.Hilk
Hi my friend. Thanks for having you.What about a simple game. I've seen it but have forgotten its name for the time being but allow me please to describe it.
There is room in which there is a ball. The gamer has a plate in hand at the bottom of the room. The ball comes down from up, naturally. The gamer moves the plate at the bottom of the room to the position the ball is coming down that way hitting and making it go up again. If the user doesn't move the plate properly and fast, the ball hits the bottom of the room and the game is over. With passing the time and the gamer's not allowing the ball to hit the bottom of the room, the speed of moving of the ball increases and the score of the user also goes upper! The winner between gamers is the one who gets the highest score.
What do you think of this? :) -
-
@J.Hilk
Pong is much cooler but how to play such a two-player game on a smartphone? We need joysticks. So I go for the one-player version of the game.@tomy ok,
but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)
-
@tomy ok,
but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)
alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)
I guess we have two parts, the first is designing the stuff and the last part is networking (via wlan).
I think it's too advanced for me, but I like it and go for that. -
@tomy ok,
but fyi, Most, if not all, smartphones have a multi touch screen, So it should be possible to play with 2 players.alternatively, this could also be a good option for you to get into networking, to play on 2 phones via bluetooth or wlan. ;-)
I started by a project named PingPong! I've reached that point up to now:
main.qml
:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 Racket { x: 630; y: 100 color: "red" } Racket { x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Rectangle { x: root.width/2 y: 10 width: 10 height: root.height - 20 color: "white" } } }
Ball.qml
:import QtQuick 2.8 Rectangle { width: 20; height: 20 x: 250; y: 250 color: "white" radius: width/2 }
Racket.qml
:import QtQuick 2.8 Rectangle { id: root width: 15; height: 50 x: 400; y: 100 color: "red" MouseArea { anchors.fill: parent drag.target: root drag.axis: Drag.YAxis drag.minimumY: 10 drag.maximumY: 440 } }
I have this up to now:
The rackets work good with the mouse button but will they work as well with touching on smartphones?
Now what I need is animating the ball using Easing.Linear. The ball also should start animating when the program starts and recognizes the rackets and the top and down part of the table to reflect.
what should I read for these please? -
I started by a project named PingPong! I've reached that point up to now:
main.qml
:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 Racket { x: 630; y: 100 color: "red" } Racket { x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Rectangle { x: root.width/2 y: 10 width: 10 height: root.height - 20 color: "white" } } }
Ball.qml
:import QtQuick 2.8 Rectangle { width: 20; height: 20 x: 250; y: 250 color: "white" radius: width/2 }
Racket.qml
:import QtQuick 2.8 Rectangle { id: root width: 15; height: 50 x: 400; y: 100 color: "red" MouseArea { anchors.fill: parent drag.target: root drag.axis: Drag.YAxis drag.minimumY: 10 drag.maximumY: 440 } }
I have this up to now:
The rackets work good with the mouse button but will they work as well with touching on smartphones?
Now what I need is animating the ball using Easing.Linear. The ball also should start animating when the program starts and recognizes the rackets and the top and down part of the table to reflect.
what should I read for these please?@tomy
Hiho,Internaly Qt does not differ between mouse clicks and touch events, so if it works fine with the mouse, than it should work fine on the phone display.
I don't think there is much to read upon for you, you should be able to do that "collision" with what you know.
E.g
You monitor the x-position of your ball. If it hits the x-position of one of the rackets, check if the y-positions of ball and racket overlap.
If yes : Stop old animation of ball and start new one if not, let animation finish and change score counter. -
@tomy
Hiho,Internaly Qt does not differ between mouse clicks and touch events, so if it works fine with the mouse, than it should work fine on the phone display.
I don't think there is much to read upon for you, you should be able to do that "collision" with what you know.
E.g
You monitor the x-position of your ball. If it hits the x-position of one of the rackets, check if the y-positions of ball and racket overlap.
If yes : Stop old animation of ball and start new one if not, let animation finish and change score counter.For this point I changed the
main.qml
to this:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 property real xPos: root.width property real yPos: Math.random() Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Column { spacing: 3 x: root.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } ParallelAnimation { id: anim1 NumberAnimation { target: ball properties: "x" to: root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } function nextPos() { if(ball.x == redRacket.x && ball.y == redRacket.y) { ParallelAnimation { id: anim2 NumberAnimation { target: ball properties: "x" to: -root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } } } MouseArea { anchors.fill: ball onClicked: { anim1.restart(); anim2.restart() } } } }
The net is better and also I tried to make the ball animate on two opposite directions. But I get these errors:
qrc:/main.qml:76 Expected token ,'
qrc:/main.qml:78 Expected token `}'By the way, the Math.random() function seems not to work!
-
For this point I changed the
main.qml
to this:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 property real xPos: root.width property real yPos: Math.random() Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Column { spacing: 3 x: root.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } ParallelAnimation { id: anim1 NumberAnimation { target: ball properties: "x" to: root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } function nextPos() { if(ball.x == redRacket.x && ball.y == redRacket.y) { ParallelAnimation { id: anim2 NumberAnimation { target: ball properties: "x" to: -root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } } } MouseArea { anchors.fill: ball onClicked: { anim1.restart(); anim2.restart() } } } }
The net is better and also I tried to make the ball animate on two opposite directions. But I get these errors:
qrc:/main.qml:76 Expected token ,'
qrc:/main.qml:78 Expected token `}'By the way, the Math.random() function seems not to work!
@tomy
first of let me tell you, as a person with slight ocd-issues, the fact that your indenting is off, is driving me nuts x)Anyway:
you define a function
nextPos()
and insinde the function-body you try to define a ParallelAnimation item and NumberAnimation items. That can't work.only calculate assign values&properties in functions! Not new items.
In C++ you would, kind of, get way with it, but defenitly not in QML :-) -
@tomy
first of let me tell you, as a person with slight ocd-issues, the fact that your indenting is off, is driving me nuts x)Anyway:
you define a function
nextPos()
and insinde the function-body you try to define a ParallelAnimation item and NumberAnimation items. That can't work.only calculate assign values&properties in functions! Not new items.
In C++ you would, kind of, get way with it, but defenitly not in QML :-)@J.Hilk
Sorry, I don't know if there is an option that offer automatic indenting on Qt Creator. Do you mean the code looks ugly? :-)Anyway,
The functionsMath.random()
andnextPos()
andif-condition
are fixed:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 property real xPos: root.width property real yPos: Math.random() * root.height Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Column { spacing: 3 x: root.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } ParallelAnimation { id: anim1 NumberAnimation { target: ball properties: "x" to: root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } ParallelAnimation { id: anim2 NumberAnimation { target: ball properties: "x" to: -root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } function nextPos() { if(ball.x >= redRacket.x && ball.x <= redRacket.x + redRacket.height) { anim1.stop(); anim2.start(); } } MouseArea { anchors.fill: ball onClicked: { anim1.start(); root.nextPos(); } } } }
The x position of the ball is for when it hasn't been animated yet so it won't work in the condition. I need something like:
if (hit(ball,redRacket))
The second is that in:
anim1.stop(); anim2.start();
anim2.start()
doesn't letanim1.start()
work! -
@J.Hilk
Sorry, I don't know if there is an option that offer automatic indenting on Qt Creator. Do you mean the code looks ugly? :-)Anyway,
The functionsMath.random()
andnextPos()
andif-condition
are fixed:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: root width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" property int duration: 1000 property real xPos: root.width property real yPos: Math.random() * root.height Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: root.width/2 - 50 y: root.height/2 } Column { spacing: 3 x: root.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } ParallelAnimation { id: anim1 NumberAnimation { target: ball properties: "x" to: root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } ParallelAnimation { id: anim2 NumberAnimation { target: ball properties: "x" to: -root.xPos duration: root.duration easing.type: Easing.Linear } NumberAnimation { target: ball properties: "y" to: root.yPos duration: root.duration easing.type: Easing.Linear } } function nextPos() { if(ball.x >= redRacket.x && ball.x <= redRacket.x + redRacket.height) { anim1.stop(); anim2.start(); } } MouseArea { anchors.fill: ball onClicked: { anim1.start(); root.nextPos(); } } } }
The x position of the ball is for when it hasn't been animated yet so it won't work in the condition. I need something like:
if (hit(ball,redRacket))
The second is that in:
anim1.stop(); anim2.start();
anim2.start()
doesn't letanim1.start()
work!@tomy Hiho
So, I took a look at your code. I'm not quite sure why it's not working like you want it to.
My guess would be, its quite difficult to click upon the ball when its in the window when its in the Racket.So I simpliefied the situation a bit
I added 2 Properties and a timer to help:
The timer was needed in my testing, otherwise it would change animation anproperty bool toTheRight: true property bool delay: false Timer{ id: delayTimer interval: 500; running: false; repeat: false onTriggered: delay = false } onToTheRightChanged: { delay = true delayTimer.start() }
nextPos() was slighly changed, it currently only checks if the ball is past a line:
function nextPos() { if(!delay){ if(ball.x + ball.width >= redRacket.x || ball.x <= blackRacket.x + blackRacket.width){ toRight = !toRight console.log("Ball hits a racket") if(anim1.running) anim1.stop() else anim1.start() if(anim2.running) anim2.stop() else anim2.start() } } }
The Ball item calls nextPos():
Ball { id: ball x: root.width/2 - 50 y: root.height/2 onXChanged: nextPos() } ... MouseArea { anchors.fill: ball onClicked: { anim1.start(); /*root.nextPos();*/} }
This works fine for me, its results in the ball pinging from one wall to the other.
Next step would be to add the player input conditions.hope this helps.
-
@tomy Hiho
So, I took a look at your code. I'm not quite sure why it's not working like you want it to.
My guess would be, its quite difficult to click upon the ball when its in the window when its in the Racket.So I simpliefied the situation a bit
I added 2 Properties and a timer to help:
The timer was needed in my testing, otherwise it would change animation anproperty bool toTheRight: true property bool delay: false Timer{ id: delayTimer interval: 500; running: false; repeat: false onTriggered: delay = false } onToTheRightChanged: { delay = true delayTimer.start() }
nextPos() was slighly changed, it currently only checks if the ball is past a line:
function nextPos() { if(!delay){ if(ball.x + ball.width >= redRacket.x || ball.x <= blackRacket.x + blackRacket.width){ toRight = !toRight console.log("Ball hits a racket") if(anim1.running) anim1.stop() else anim1.start() if(anim2.running) anim2.stop() else anim2.start() } } }
The Ball item calls nextPos():
Ball { id: ball x: root.width/2 - 50 y: root.height/2 onXChanged: nextPos() } ... MouseArea { anchors.fill: ball onClicked: { anim1.start(); /*root.nextPos();*/} }
This works fine for me, its results in the ball pinging from one wall to the other.
Next step would be to add the player input conditions.hope this helps.
@J.Hilk
Thank you.
Timer was very useful. I wrote this:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: table width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: table.width/2 - 50 y: table.height/2 property double ran: Math.random() + 0.5 property double xincrement: ran property double yincrement: ran } Column { spacing: 3 x: table.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } Timer { interval: 5; repeat: true; running: true onTriggered: { ball.x = ball.x + (ball.xincrement * 2.0); ball.y = ball.y + (ball.yincrement * 2.0); if((ball.x + ball.width >= redRacket.x) && ((ball.y + ball.height >= redRacket.y) && (ball.y + ball.height <= redRacket.y + redRacket.height))) ball.xincrement *= (-1); if((ball.x - ball.width <= blackRacket.x) && ((ball.y + ball.height >= blackRacket.y) && (ball.y + ball.height <= blackRacket.y + blackRacket.height))) ball.xincrement *= (-1); if(ball.y <= 0 || ball.y + ball.height >= table.height) ball.yincrement *= (-1); } } } }
It works fine but the players can't shoot the ball towards a target they want! The rackets are this way only for defending. I need to alter the code so that when the racket has speed upward or downward hitting the ball, the ball goes and gets acceleration on that direction. The real game has that feature.
How can I do that, please?After that I'll go for other missing parts for the game.
-
@J.Hilk
Thank you.
Timer was very useful. I wrote this:import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 title: qsTr("The Ping Pong game") Rectangle { id: table width: 700; height: 500 border.width: 10 border.color: "black" color: "royalblue" Racket { id: redRacket x: 630; y: 100 color: "red" } Racket { id: blackRacket x: 50; y: 100 color: "black" } Ball { id: ball x: table.width/2 - 50 y: table.height/2 property double ran: Math.random() + 0.5 property double xincrement: ran property double yincrement: ran } Column { spacing: 3 x: table.width/2 y: 10 Repeater { model: 21 delegate: Rectangle { width: 5 height: 20 color: "white" } } } Timer { interval: 5; repeat: true; running: true onTriggered: { ball.x = ball.x + (ball.xincrement * 2.0); ball.y = ball.y + (ball.yincrement * 2.0); if((ball.x + ball.width >= redRacket.x) && ((ball.y + ball.height >= redRacket.y) && (ball.y + ball.height <= redRacket.y + redRacket.height))) ball.xincrement *= (-1); if((ball.x - ball.width <= blackRacket.x) && ((ball.y + ball.height >= blackRacket.y) && (ball.y + ball.height <= blackRacket.y + blackRacket.height))) ball.xincrement *= (-1); if(ball.y <= 0 || ball.y + ball.height >= table.height) ball.yincrement *= (-1); } } } }
It works fine but the players can't shoot the ball towards a target they want! The rackets are this way only for defending. I need to alter the code so that when the racket has speed upward or downward hitting the ball, the ball goes and gets acceleration on that direction. The real game has that feature.
How can I do that, please?After that I'll go for other missing parts for the game.
@tomy
well, first you'll need to somehow monitor if the racket moved up or down as its last movement.I don't see how in the code examples you posted how you manage the "Racket-Movement" .
but it doesn't matter much, it can be a property of the Racket Item
#untested Stuff
e.g:Rectangle { id: redRacket x: 630; y: 100 color: "red" property int oldY: 100 property bool upMovement: false onYChanged:{ upMovement = y -oldY < 0 ? true : false oldY = y } width: 50 height: 100 }
and when the Ball hits the racket you decrease the duration, and depending on the up or down movement you change the angle
function onCollisionWithRacket(){ root.duration = root.duration -10 if(redRacket.upMovement){ //Angle to the Top }else{ //Angle to the bottom } }