[英]Dragging a sprite in sfml
我现在正在做一项任务,为此,我需要将棋子拖到棋盘上,问题是我不知道如何使这项工作不止一个棋子。 我可以计算鼠标 position 并且我只能移动一件,但代码仅适用于该单件。 我的问题是我如何点击一个片段,让它成为活动片段,直到我释放鼠标按钮。 如果我只检查它是否与一件相交,这将不起作用,因为那时它不是动态的。 我的代码因为我尝试不同的东西而一团糟,但这里有一些相关的部分。
这是精灵的设置:
// load the texture and setup the sprite for the logo
void Game::setupSprite()
{
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
if (!m_boardTexture.loadFromFile("ASSETS\\IMAGES\\board.png"))
{
// simple error message if previous call fails
std::cout << "problem loading board" << std::endl;
}
m_boardSprite.setTexture(m_boardTexture);
m_boardSprite.setPosition(0.0f, 0.0f);
//pieces
if (!m_wkingTex.loadFromFile("ASSETS\\IMAGES\\PIECES\\wking.png"))
{
// simple error message if previous call fails
std::cout << "problem loading piece" << std::endl;
}
m_wking.setTexture(m_wkingTex);
m_wking.setPosition(0.0f, 0.0f);
sf::IntRect wkingRect(pieceRect);
}
如果鼠标按钮按下
void Game::processMouseButtonDown(sf::Event t_event)
{
if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
std::cout << "Mouse button pressed\n";
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
if (isSpriteClicked() && !m_holdingPiece) {
m_holdingPiece = true;
}
}
}
鼠标按钮向上:
void Game::processMouseButtonUp(sf::Event t_event)
{
m_holdingPiece = false;
sf::IntRect pieceRect(m_wking.getPosition().x, m_wking.getPosition().y, 128, 128);
m_wking.setTextureRect(pieceRect);
}
如果精灵被点击
bool Game::isSpriteClicked()
{
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
sf::FloatRect bounds(mouse.x, mouse.y, 1.0f, 1.0f);
if (bounds.intersects(wkingRect.I dont know what Im doing)) {
std::cout << "King has Been clicked!\n";
return true;
}
else {
return false;
}
}
最后移动精灵:
void Game::move()
{
if (m_holdingPiece) {
sf::Vector2f mouse = m_window.mapPixelToCoords(sf::Mouse::getPosition(m_window));
m_wking.setPosition(mouse);
}
}
对不起,如果这看起来像很多代码,但我觉得这一切都与问题有关。
问题:
您已经对所有变量进行了硬编码,因此即使您创建一个列表并对其进行迭代以运行Game::move()
它也会移动所有部分而不是仅移动一个,因为变量m_holdingPiece
对于所有部分都是相同的。
解决方案:
您应该使用更多的 OOP 方法为棋子创建 class 而Game
class 可能应该只控制游戏何时开始,何时结束并检查移动是否合法。 解释所有这些都太宽泛了 Stack Overflow 并且它是你必须做的工作的一部分,所以我将举一个例子来说明一个基本的chessPiece
class 将如何使棋子变得可拖动。
例子:
这是一个如何使一组片段可拖动的示例。
#include <SFML/Graphics.hpp>
#include <string>
class chessPiece: public sf::Drawable, public sf::Transformable
{
private:
sf::RenderWindow& window;
sf::Texture texture;
sf::Sprite sprite;
bool moving;
public:
chessPiece(sf::RenderWindow& windowRef, const std::string& fileName): window(windowRef)
{
if(!texture.loadFromFile(fileName))
exit(0);
this->sprite.setTexture(this->texture);
this->moving = false;
this->sprite.setScale(128/this->sprite.getGlobalBounds().width,128/this->sprite.getGlobalBounds().height);
}
chessPiece(chessPiece&& rval): window(rval.window)
{
this->texture = std::move(rval.texture);
this->sprite.setTexture(this->texture);
this->sprite.setScale(rval.sprite.getScale());
this->moving = std::move(rval.moving);
}
chessPiece(const chessPiece& lval): window(lval.window)
{
this->texture = lval.texture;
this->sprite.setTexture(this->texture);
this->sprite.setScale(lval.sprite.getScale());
this->moving = lval.moving;
}
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= this->getTransform();
target.draw(this->sprite,states);
}
void move(bool& movingAPiece)
{
sf::Vector2f mousePosition = window.mapPixelToCoords(sf::Mouse::getPosition(window));
if(this->moving)
{
this->setPosition(mousePosition.x - this->sprite.getGlobalBounds().width/2,mousePosition.y - this->sprite.getGlobalBounds().height/2);
if(!sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
{
this->moving = false;
movingAPiece = false;
}
}
else
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && mousePosition.x > this->getPosition().x &&
mousePosition.y > this->getPosition().y && mousePosition.x < this->getPosition().x + this->sprite.getGlobalBounds().width &&
mousePosition.y < this->getPosition().y + this->sprite.getGlobalBounds().height && !movingAPiece)
{
this->moving = true;
movingAPiece = true;
}
}
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(1000,500),"Window");
std::vector<chessPiece> pieces = {chessPiece(window,"white-king.png"),chessPiece(window,"white-pawn.png")};
pieces[0].setPosition(400,400);
bool movingAPiece = false;
while(true)
{
sf::Event event;
if(window.pollEvent(event))
if(event.type == sf::Event::Closed)
window.close();
for(unsigned int i = 0; i < pieces.size(); i++)
pieces[i].move(movingAPiece);
window.clear();
for(unsigned int i = 0; i < pieces.size(); i++)
window.draw(pieces[i]);
window.display();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.