Chào mọi người.
Hiện tại em đang học SFML và muốn thêm bớt 1 chút yếu tố vật lí (ở đây là gia tốc) cho nhân vật.
Tuy nhiên thì em bị gặp một số lỗi về hướng di chuyển của nhân vật. Cụ thể lỗi thì em cũng chưa biết cách diễn đạt nên dùng tạm Paint vẽ 1 hình cho mọi người dễ hình dung.
Chú thích:
- Đường màu đỏ là đường đi của nhân vật
- Mũi tên đen chỉ hướng di chuyển của nhân vật
- A -> W là thứ tự phím bấm
Khi em A -> W thì nhân vật đang đi sang trái sẽ đi dần lên như hình. Thế nhưng khi nhân vật đang đi sang(D -> W) phải thì lại bị trôi tiếp đến khi vận tốc bằng 0 mới đổi hướng.
Ban đầu em đã nghĩ là di thứ tự sắp xếp các câu lệnh điều kiển nhân vật nhưng sau khi đổi lại vẫn không được. Một cái nữa là không phải do bộ gõ vì em thử đổi tiếng Anh với tiếng Việt rồi nhưng đều vậy.
Ai biết em sai ở đâu thì gợi ý cho em với ạ. Em cảm ơn mọi người rất nhiều.
Dưới đây là code của em ạ.
P/s : Ai có thuật toán tốt hơn cho cái gia tốc thì gợi ý cho em nữa nhé.
#include <SFML/Graphics.hpp>
#include <iostream>
#include<vector>
using namespace sf;
int main()
{
// Create the main window
RenderWindow window(VideoMode(800,600) , "Wall");
window.setFramerateLimit(60);
//Grid
float girdSize = 50.f;
//Creat player
RectangleShape player(Vector2f(girdSize , girdSize));
player.setFillColor(Color::Green);
//Creat acceleration, drag, maxVelocity, ..
float acceleration = 2.5f;
float drag = 0.5f;
float maxVelocity = 6.f;
Vector2f currentVelocity( 0 , 0);
float deltaTime = 0;
float multi = 15;
Clock clock;
//Main loop
while(window.isOpen()){
Event event;
while(window.pollEvent(event)){
if(event.type == Event::Closed){
window.close();
}
}
//Update
//Restart deltaTime
deltaTime = clock.restart().asSeconds();
//Acceleration
if(Keyboard::isKeyPressed(Keyboard::A)){
if(currentVelocity.x > -maxVelocity){
currentVelocity.x -= acceleration * deltaTime * multi;
}
}
if(Keyboard::isKeyPressed(Keyboard::D)){
if(currentVelocity.x < maxVelocity){
currentVelocity.x += acceleration * deltaTime * multi;
}
}
if(Keyboard::isKeyPressed(Keyboard::S)){
if(currentVelocity.y < maxVelocity){
currentVelocity.y += acceleration * deltaTime * multi;
}
}
if(Keyboard::isKeyPressed(Keyboard::W)){
if(currentVelocity.y > -maxVelocity){
currentVelocity.y -= acceleration * deltaTime * multi;
}
}
//Drag
if(currentVelocity.x > 0){
currentVelocity.x -= drag * deltaTime * multi;
if(currentVelocity.x < 0){
currentVelocity.x = 0 ;
}
}
if(currentVelocity.x < 0){
currentVelocity.x += drag * deltaTime * multi;
if(currentVelocity.x > 0){
currentVelocity.x = 0 ;
}
}
if(currentVelocity.y > 0){
currentVelocity.y -= drag * deltaTime * multi;
if(currentVelocity.y < 0){
currentVelocity.y = 0 ;
}
}
if(currentVelocity.y < 0){
currentVelocity.y += drag * deltaTime * multi;
if(currentVelocity.x > 0){
currentVelocity.y = 0 ;
}
}
player.move(currentVelocity);
//Render
window.clear();
window.draw(player);
window.display();
}
return EXIT_SUCCESS;
}
Code có lẽ sai ở phần gia tốc và kéo thả nhưng em post full code vì sợ có thể sai ở chỗ khác.
Giải thích thuật toán phần gia tốc và kéo thả
Phần gia tốc em sử dụng 1 biến gia tốc acceleration
để minh họa cho gia tốc. Khi press A
thì sẽ so sánh vận tốc hiện thời currentVelocity
với vận tốc tối đa maxVelocity
. Nếu nhỏ hơn thì tăng vận tốc theo gia tốc.
Khi nhả A thì sẽ so sánh currentVelocity
với 0. Nếu còn lớn hơn 0 thì trừ đi drag
.Nếu currentVeclocity
mà nhỏ hơn thì sẽ đưa currentVelocity
về 0.
Bản chất thì acceleration
và drag
đều là gia tốc nhưng 1 cái là gia tốc bắt đầu và gia tốc khi phanh.