How to make a game like Pong with Felgo - AI
Testing a game without enemy is hardly possible. Now you are going implement a simple AI in the Paddle.qml to test the game. First of all you gonna need a flag to distinguish if the player is AI or human - which can be set
via the reset method. Furthermore, a difficulty flag is added which can have values of 2 (easy), 4 (medium), 6(hard). Once started, the MultiTouchArea should only be touchable for human players, therefore, change the enable
flag dependent on the isAI
flag. The move function will be called regularly which drives the AI calculations. Based on the difficulty flag, 3 different approaches have been used as demonstration.
After the position calculation, there are some bounding checks that the paddles stay in the game field.
... // Save the score of the player property int score: 0 // Flag to identify if the paddle is human or AI property bool isAI : false // Difficulty for SimpleAI, can be used property int difficulty : 2 // last pad position property real lastPadPosY: 0 // movement speed of the paddle property real paddleSpeed : 0 // update the speed of the paddle which can be used by the ball during collision events onYChanged: { paddleSpeed = lastPadPosY-y lastPadPosY=y } ... MultiTouchArea { ... // the touch are should only be usable when a human is the player enabled: !isAI } ... // Resetting the score and set if AI or not function reset(isPlayerAI) { isAI = isPlayerAI score = 0 } // move the paddle used for AI function move(ballEntity) { if(!isAI) return // remove jittering if(lastPadPosY === ballEntity.y) return else if(Math.abs(lastPadPosY - ballEntity.y) < 8) return lastPadPosY = ballEntity.y // calculate paddle position based on difficulty if(difficulty <= 2) { easy(ballEntity) } else if(difficulty >2 && difficulty < 8) { medium(ballEntity) } else { hard(ballEntity) } // check the boundaries of the word, so that the paddle does not intersect var bumper = level.blockHeight+sprite.height/2 if(y > scene.height - bumper) { y = scene.height - bumper } if(y < bumper) { y = bumper } } // position change based on the linear velocity function easy(ballEntity) { if(ballEntity.linearVelocity().y > 0) { y += difficulty*4 } else if(ballEntity.linearVelocity().y < 0) { y -= difficulty*4 } } // position change based on position function medium(ballEntity) { if(ballEntity.y > y) y += difficulty*3 else if( ballEntity.y < y) y -= difficulty*3 } // position change based on ball position function hard(ballEntity) { y = ballEntity.y } ...
The difficulty of the AI can be changed via the buttons in the MainMenu.qml. You can create a game session for left/right handed player or a multi player session or a game session AI vs. AI.
Column { anchors.centerIn: parent MenuButton { text: "Multi Player" onClicked: { scene.state = "game" // Reset player and if it is an AI player (true) or not (false) player1.reset(false) player2.reset(false) } } MenuButton { text: "SP - Left Handed" onClicked: { scene.state = "game" player1.reset(true) player2.reset(false) } } MenuButton { text: "SP - Right Handed" onClicked: { scene.state = "game" player1.reset(false) player2.reset(true) } } MenuButton { text: "AI Fight" onClicked: { scene.state = "game" player1.reset(true) player2.reset(true) } } MenuButton { property int difficulty : 2 text: "Difficulty: " + ((difficulty==2) ? "easy" : (difficulty==4) ? "normal" : "epic") onClicked: { difficulty+=2; if(difficulty>6) { difficulty = 2 } player1.difficulty = difficulty player2.difficulty = difficulty } } }
The calculation of the AI needs to be triggered by calling the move() function of the paddles which is done with timers.
... // timer to calculate AI movement, does need to be called each frame // therefore we use a timer. Timer { interval: 32; running: true; repeat: true onTriggered: { player1.move(ball) player2.move(ball) } } ...
Now the paddles move around automatically, based on the difficulty level.
Now it's time to add some special effects to the game.