Hi,
ich bin gerade dabei mein erstes kleines Programm mit der SFML zu erstellen (TicTacToe). Nachdem ich die Grafiken fertig gestellt habe, muss ich den Maus-Input managen: Man soll, ganz einfach auf eines der 9 TicTacToe-Felder klicken und dann wird je nachdem ein 'X' oder 'O' gezeichnet. Da ich nicht wusste wie das geht, hab ich mehrere Stunden nach einer Möglichkeit gesucht, mit Erfolg:
#Click on a sprite - SFML Forum# Dort sieht man direkt, sogar vom SFML-Entwickler selbst einen für jeden Idioten, verständlichen und logischen Code wie man das löst. Wenn man runterscrollt sieht man zwar eine weitere Möglichkeit, doch die gilt nur für das veraltete SFML 1.6, ich habe dagegen SFML 2.0/2.1. Im folgendem Projekt müsste ich das doch eigentlich richtig zur Schau gestellt haben:
Sprite.hpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#ifndef SPRITE_HPP
#define SPRITE_HPP
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
extern sf::Texture TicTacToe_Texture;
int LoadTexture();
//Slot class
class CSlot : public sf::Drawable, public sf::Transformable
{
friend class CCollision;
private:
sf::Sprite m_Slot;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform *= getTransform();
states.texture = &TicTacToe_Texture;
target.draw(m_Slot, states);
}
public:
CSlot ();
};
//X and O class
class CXO : public sf::Drawable, public sf::Transformable
{
friend class CCollision;
private:
sf::Sprite X;
sf::Sprite O;
public:
CXO();
};
#endif
|
Sprite.cpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include "Sprites.hpp"
using namespace std;
sf::Texture TicTacToe_Texture;
int LoadTexture()
{
if(!TicTacToe_Texture.loadFromFile("TicTacToe_Texture.png"))
{
return -1;
}
}
CSlot::CSlot ()
{
LoadTexture();
m_Slot.setTexture(TicTacToe_Texture);
m_Slot.setTextureRect(sf::IntRect(0, 0, 199, 199));
m_Slot.setPosition(0, 0);
}
CXO::CXO()
{
LoadTexture();
//Player 1 Sprite
X.setTexture(TicTacToe_Texture);
X.setTextureRect(sf::IntRect(200, 0, 199, 199));
//Player 2 Sprite
O.setTexture(TicTacToe_Texture);
O.setTextureRect(sf::IntRect(400, 0, 199, 199));
}
|
IO.hpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#ifndef IO_HPP
#define IO_HPP
#include "Sprites.hpp"
extern sf::RenderWindow MainWindow;
//Collision class
class CCollision
{
private:
short Player;
sf::Vector2f Mouse;
sf::FloatRect Slot1Box;
sf::FloatRect Slot2Box;
sf::FloatRect Slot3Box;
sf::FloatRect Slot4Box;
sf::FloatRect Slot5Box;
sf::FloatRect Slot6Box;
sf::FloatRect Slot7Box;
sf::FloatRect Slot8Box;
sf::FloatRect Slot9Box;
bool Slot1Taken;
bool Slot2Taken;
bool Slot3Taken;
bool Slot4Taken;
bool Slot5Taken;
bool Slot6Taken;
bool Slot7Taken;
bool Slot8Taken;
bool Slot9Taken;
public:
CCollision();
void CheckCollision();
};
#endif
|
IO.cpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include "IO.hpp"
sf::RenderWindow MainWindow (sf::VideoMode(597, 597), "TicTacToe", sf::Style::Default);
//Create Entities
CSlot Slot1;
CSlot Slot2;
CSlot Slot3;
CSlot Slot4;
CSlot Slot5;
CSlot Slot6;
CSlot Slot7;
CSlot Slot8;
CSlot Slot9;
CCollision::CCollision()
{
//Player: 15 for 'O', 24 for 'X'
Player = 24;
Mouse = MainWindow.mapPixelToCoords(sf::Mouse::getPosition(MainWindow));
Slot1Box = Slot1.m_Slot.getGlobalBounds();
Slot2Box = Slot2.m_Slot.getGlobalBounds();
Slot3Box = Slot3.m_Slot.getGlobalBounds();
Slot4Box = Slot4.m_Slot.getGlobalBounds();
Slot5Box = Slot5.m_Slot.getGlobalBounds();
Slot6Box = Slot6.m_Slot.getGlobalBounds();
Slot7Box = Slot7.m_Slot.getGlobalBounds();
Slot8Box = Slot8.m_Slot.getGlobalBounds();
Slot9Box = Slot9.m_Slot.getGlobalBounds();
Slot1Taken = false;
Slot2Taken = false;
Slot3Taken = false;
Slot4Taken = false;
Slot5Taken = false;
Slot6Taken = false;
Slot7Taken = false;
Slot8Taken = false;
Slot9Taken = false;
}
void CCollision::CheckCollision()
{
// hit test
if(Slot1Box.contains(Mouse))
{
printf("You pressed Slot1!");
}
}
|
main.cpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#include "IO.hpp"
using namespace std;
//First project: TicTacToe Project
//Create Window
int main()
{
//Create Entities
CCollision Collision;
CSlot Slot1;
CSlot Slot2;
CSlot Slot3;
CSlot Slot4;
CSlot Slot5;
CSlot Slot6;
CSlot Slot7;
CSlot Slot8;
CSlot Slot9;
//Manage Entities
Slot1.setPosition(0, 0);
Slot2.setPosition(199, 0);
Slot3.setPosition(398, 0);
Slot4.setPosition(0, 199);
Slot5.setPosition(199, 199);
Slot6.setPosition(398, 199);
Slot7.setPosition(0, 398);
Slot8.setPosition(199, 398);
Slot9.setPosition(398, 398);
while (MainWindow.isOpen())
{
sf::Event event;
while (MainWindow.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
printf("You clicked the 'Close' Button.\n");
MainWindow.close();
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
Collision.CheckCollision();
}
}
MainWindow.clear(sf::Color(128,128,128));
MainWindow.draw(Slot1);
MainWindow.draw(Slot2);
MainWindow.draw(Slot3);
MainWindow.draw(Slot4);
MainWindow.draw(Slot5);
MainWindow.draw(Slot6);
MainWindow.draw(Slot7);
MainWindow.draw(Slot8);
MainWindow.draw(Slot9);
MainWindow.display();
}
return 0;
}
|
Noch nicht alles ganz fertig, aber mich interessiert im Moment nur der Maus-Input der nicht funktioniert. Könnte man zwar selbst fixen der Fehler aber es ist nun mal so: Der selbe Code hat verschiedene Ergebnisse: 1. Wenn man klickt, wird in der Konsole angezeigt:
You pressed Slot1. Das soll ein Platzhalter darstellen. Das Problem ist, dass es nicht wie gedacht nur dann reagiert, wenn man wirklich NUR auf Slot1 klickt, sondern ganz egal wo im Fenster man klickt. 2. Es reagiert überhaupt nicht.
Meinen Fehler kann ich nicht erkennen, obwohl es höchstwahrscheinlich meiner ist. Was stimmt jetzt mit dem Maus-Input nicht?
MfG Pwalb