2.
zemini ortadan üç dört parçaya bölüp her bir grass malzemesi için, farklı sürtünme değerleri atayabiliriz, bu da zıplama esnasında ulaşılan maksimum yükseklik değerini ivme artışı ve azalışıyla beraber değiştirecektir.
hatta bu zemin parçalarının her birinde farklı yerçekimi ivmelerine maruz kalıp, aniden havalanabilir, zeminden bir milim dahi zıplayamadan yere çakılı vaziyette kalabiliriz.
1.
basit zannedilen fizik mekaniği, kinematik 101 konusu 2 boyutlu eğik atış hareketinden (projectile motion ) ilham alınarak tasarlanmış:
#include <SFML/Graphics.hpp>
#include <cmath>
#include <vector>
#include <sstream>
const float GRAVITY = 981.0f;
const float JUMP_SPEED = 400.0f;
const float MOVE_SPEED = 300.0f;
const float BOOST_MULTIPLIER = 1.5f;
const float DOUBLE_JUMP_MULTIPLIER = 1.5f; // ikinci zıplama için hız çarpanı
const float FLOOR_Y = 540.0f;
const float WINDOW_WIDTH = 1920.0f;
const float WINDOW_HEIGHT = 1080.0f;
int main()
{
sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "2D-EGIK ATIS HAREKETI");
// Font yükleme
sf::Font font;
if (!font.loadFromFile("/home/kratertepesi/Masaüstü/Programlar/arial.ttf"))
{
return -1; // Font yüklenemezse programı sonlandır
}
// Başlık metni oluşturma
sf::Text titleText("2D-EGIK ATIS HAREKETI", font, 50); // Font boyutu 50
titleText.setFillColor(sf::Color::White);
titleText.setPosition(WINDOW_WIDTH / 2 - titleText.getGlobalBounds().width / 2, 10); // Ortalanmış başlık
sf::RectangleShape blueSquare(sf::Vector2f(50.0f, 50.0f));
blueSquare.setFillColor(sf::Color::Blue);
blueSquare.setPosition(960, FLOOR_Y);
sf::RectangleShape ground(sf::Vector2f(WINDOW_WIDTH, WINDOW_HEIGHT - (FLOOR_Y + blueSquare.getSize().y)));
ground.setFillColor(sf::Color::Green);
ground.setPosition(0, FLOOR_Y + blueSquare.getSize().y);
sf::RectangleShape sky(sf::Vector2f(WINDOW_WIDTH, FLOOR_Y));
sky.setFillColor(sf::Color(135, 206, 235));
sf::RectangleShape background(sf::Vector2f(WINDOW_WIDTH, blueSquare.getSize().y));
background.setFillColor(sf::Color(135, 206, 235));
background.setPosition(0, FLOOR_Y);
bool jumping = false;
bool onGround = true;
bool doubleJumpReady = false; // ikinci zıplama hazır mı
float xVelocity = 0.0f;
float yVelocity = 0.0f;
float jumpStartY = FLOOR_Y; // Zıplama başlangıç noktası
sf::Clock clock;
std::vector<sf::Vertex> path; // Paraboli çizmek için yol noktaları
sf::Text angleText, forceText;
angleText.setFont(font);
angleText.setCharacterSize(24);
angleText.setFillColor(sf::Color::White);
forceText.setFont(font);
forceText.setCharacterSize(24);
forceText.setFillColor(sf::Color::White);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
float dt = clock.restart().asSeconds();
// Hareket hızını ve zıplama hızını belirler
float currentMoveSpeed = MOVE_SPEED;
float currentJumpSpeed = JUMP_SPEED;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
currentMoveSpeed *= BOOST_MULTIPLIER;
currentJumpSpeed *= BOOST_MULTIPLIER;
}
// Hareket kontrolleri
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
xVelocity = -currentMoveSpeed;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
xVelocity = currentMoveSpeed;
}
else
{
xVelocity = 0.0f;
}
// Zıplama işlemi
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && onGround)
{
jumping = true;
onGround = false;
yVelocity = -currentJumpSpeed;
jumpStartY = blueSquare.getPosition().y; // Zıplama başlangıç yüksekliği ayarlanır
doubleJumpReady = true; // ikinci zıplama yapılabilir
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && doubleJumpReady)
{
yVelocity = -currentJumpSpeed * DOUBLE_JUMP_MULTIPLIER;
doubleJumpReady = false; // ikinci zıplama bir kez yapılır
}
// Yer çekimi etkisi
if (!onGround)
{
yVelocity += GRAVITY * dt;
}
blueSquare.move(xVelocity * dt, yVelocity * dt);
// Parabol çizimi için pozisyon ekle
path.push_back(sf::Vertex(blueSquare.getPosition(), sf::Color::Red));
// Açıyı ve kuvveti hesapla
float angle = atan2(-yVelocity, xVelocity) * 180 / 3.14159; // Derece cinsinden açı
float force = sqrt(xVelocity * xVelocity + yVelocity * yVelocity); // Kuvvet büyüklüğü
std::stringstream angleStream, forceStream;
angleStream << "Angle: " << angle << " degrees";
forceStream << "Force: " << force << " N";
angleText.setString(angleStream.str());
forceText.setString(forceStream.str());
angleText.setPosition(10, 10);
forceText.setPosition(10, 40);
if (blueSquare.getPosition().y >= FLOOR_Y)
{
blueSquare.setPosition(blueSquare.getPosition().x, FLOOR_Y);
yVelocity = 0.0f;
onGround = true;
doubleJumpReady = false; // Yere indiğinde ikinci zıplama sıfırlanır
path.clear(); // Parabol çizgisini sıfırla
}
if (blueSquare.getPosition().x < 0)
{
blueSquare.setPosition(0, blueSquare.getPosition().y);
}
else if (blueSquare.getPosition().x + blueSquare.getSize().x > window.getSize().x)
{
blueSquare.setPosition(window.getSize().x - blueSquare.getSize().x, blueSquare.getPosition().y);
}
window.clear();
window.draw(sky);
window.draw(background);
window.draw(ground);
// Parabol çizimi
if (!path.empty())
{
window.draw(&path[0], path.size(), sf::LinesStrip);
}
window.draw(blueSquare);
window.draw(titleText); // Başlık metnini çiz
window.draw(angleText);
window.draw(forceText);
window.display();
}
return 0;
}