чтобы опробовать инструмент решил написать понг чисто на QML, в принципе результирующий код вышел немного громоздким из-за асинхронного javascript кода и qml анимаций
мышкой управляются обе платформы, скорость игры постепенно увеличивается, необходимо набрать наибольшее количество очков
// imports
import Qt 4.7
// root object
Rectangle
{
id:screen; width:1024; height:768; color:"#DDDDDD"
// game text, show status of the game
Text
{
id:gameText;
anchors.top:screen.top; anchors.horizontalCenter:screen.horizontalCenter
text:"QML pong by jimon"
}
// score text
Text
{
id:gameScoreText;
anchors.top:screen.top; x:5;
font.family: "Courier New"; font.pointSize: 16; color: "#000000"
function zeroPad(num, count)
{
while(num.length < count) num = "0" + num;
return num;
}
function setScore(score)
{
text = "SCORE : " + zeroPad(score.toString(), 7)
}
Component.onCompleted:setScore(0);
}
// ball
Rectangle
{
id:ball; width:64; height:64; color:"#000000"
x:(screen.width - ball.width) / 2; y:(screen.height - ball.height) / 2
property variant wayX: 0 // ball way X
property variant wayY: 0 // ball way Y
property double speed: 0
property double speedDefault: 0.25 // in pixels per millisec
// moving, use number animation on x and y, calculate duration by hands
// moving by javascript and etc is a really BAD idea
NumberAnimation on x {id:ballAnimX}
NumberAnimation on y {id:ballAnimY}
function moveTo(newV, oldV, anim)
{
anim.stop();
anim.duration = Math.abs(oldV - newV) / speed;
anim.from = oldV;
anim.to = newV;
anim.start();
}
function moveToX(newX)
{
moveTo(newX, ball.x, ballAnimX)
}
function moveToY(newY)
{
moveTo(newY, ball.y, ballAnimY)
}
function stopAnimations()
{
ballAnimX.stop();
ballAnimY.stop();
}
function setWayX(newWayX)
{
if(newWayX != wayX)
{
ball.moveToX(newWayX == 1 ? screen.width - ball.width : 0);
wayX = newWayX;
}
}
function setWayY(newWayY)
{
if(newWayY != wayY)
{
ball.moveToY(newWayY == 1 ? screen.height - ball.height : 0);
wayY = newWayY;
}
}
}
// left platform
Rectangle
{
id:left; width:32; height:128; color:"#5555FF"; anchors.left:screen.left
y:(screen.height - left.height) / 2
}
// right platform
Rectangle
{
id:right; width:32; height:128; color:"#5555FF"; anchors.right:screen.right
y:(screen.height - right.height) / 2
}
// game logic timer
Timer
{
interval:20; running:true; repeat:true
onTriggered:gameTick();
}
// work with mouse
MouseArea
{
id:mouse;
anchors.fill:screen; hoverEnabled:true
onPositionChanged:gameUpdateMouse();
onClicked:gameRestart();
}
property variant gameCanRestart:1;
property variant gameScore:0;
function gameTick()
{
if(!gameCanRestart) // if game running
{
gameScore = gameScore + 10;
gameScoreText.setScore(gameScore);
ball.speed = ball.speed * 1.001;
}
if(gamePlatformCheck(left)) // horizontal moving
ball.setWayX(1);
if(gamePlatformCheck(right))
ball.setWayX(-1);
else if(ball.x <= 0 || ball.x >= screen.width - ball.width)
screen.gameLose();
if(ball.y >= screen.height - ball.height) // vertical moving
ball.setWayY(-1);
else if(ball.y <= 0)
ball.setWayY(1);
}
function gamePlatformCheck(platform)
{
return (Math.abs(platform.x - ball.x + (platform.width - ball.width) / 2) < (platform.width + ball.width) / 2) &&
(Math.abs(platform.y - ball.y + (platform.height - ball.height) / 2) < (platform.height + ball.height) / 2);
}
function gameUpdateMouse()
{
left.y = mouse.mouseY - left.height / 2;
right.y = mouse.mouseY - right.height / 2;
}
function gameLose()
{
gameText.text = "Game Over !";
ball.stopAnimations();
ball.x = (screen.width - ball.width) / 2;
ball.y = (screen.height - ball.height) / 2;
gameCanRestart = 1;
}
function gameRestart()
{
if(gameCanRestart)
{
gameScore = 0;
gameScoreText.setScore(gameScore);
ball.speed = ball.speedDefault;
ball.wayX = 0;
ball.wayY = 0;
ball.setWayX(-1);
ball.setWayY(-1);
gameText.text = "Game Started !";
gameCanRestart = 0;
}
}
}
основная громоздкость в необходимости хранить направление движения, потому что функция moveTo выполняется асинхронно с анимациями и может банально не дать анимации стартовать
подход выполнения логики в javascriptе мне совсем не понравился, он слишком сырой сейчас, попробую еще реализовать логику на C++