浏览代码

first commit

当前提交
2fce7c12bd
共有 5 个文件被更改,包括 285 次插入0 次删除
  1. 3
    0
      Makefile
  2. 二进制
      pong
  3. 282
    0
      pong.cpp
  4. 二进制
      resources/ball.wav
  5. 二进制
      resources/sansation.ttf

+ 3
- 0
Makefile 查看文件

@@ -0,0 +1,3 @@
1
+all: pong.cpp resources
2
+	g++ pong.cpp -o pong  -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio
3
+

二进制
pong 查看文件


+ 282
- 0
pong.cpp 查看文件

@@ -0,0 +1,282 @@
1
+
2
+////////////////////////////////////////////////////////////
3
+// Headers
4
+////////////////////////////////////////////////////////////
5
+#include <SFML/Graphics.hpp>
6
+#include <SFML/Audio.hpp>
7
+#include <cmath>
8
+#include <ctime>
9
+#include <cstdlib>
10
+
11
+#ifdef SFML_SYSTEM_IOS
12
+#include <SFML/Main.hpp>
13
+#endif
14
+
15
+std::string resourcesDir()
16
+{
17
+#ifdef SFML_SYSTEM_IOS
18
+    return "";
19
+#else
20
+    return "resources/";
21
+#endif
22
+}
23
+
24
+////////////////////////////////////////////////////////////
25
+/// Entry point of application
26
+///
27
+/// \return Application exit code
28
+///
29
+////////////////////////////////////////////////////////////
30
+int main()
31
+{
32
+    std::srand(static_cast<unsigned int>(std::time(NULL)));
33
+
34
+    // Define some constants
35
+    const float pi = 3.14159f;
36
+    const int gameWidth = 800;
37
+    const int gameHeight = 600;
38
+    sf::Vector2f paddleSize(25, 100);
39
+    float ballRadius = 10.f;
40
+
41
+    // Create the window of the application
42
+    sf::RenderWindow window(sf::VideoMode(gameWidth, gameHeight, 32), "SFML Pong",
43
+                            sf::Style::Titlebar | sf::Style::Close);
44
+    window.setVerticalSyncEnabled(true);
45
+
46
+    // Load the sounds used in the game
47
+    sf::SoundBuffer ballSoundBuffer;
48
+    if (!ballSoundBuffer.loadFromFile(resourcesDir() + "ball.wav"))
49
+        return EXIT_FAILURE;
50
+    sf::Sound ballSound(ballSoundBuffer);
51
+
52
+    // Create the left paddle
53
+    sf::RectangleShape leftPaddle;
54
+    leftPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
55
+    leftPaddle.setOutlineThickness(3);
56
+    leftPaddle.setOutlineColor(sf::Color::Black);
57
+    leftPaddle.setFillColor(sf::Color(100, 100, 200));
58
+    leftPaddle.setOrigin(paddleSize / 2.f);
59
+
60
+    // Create the right paddle
61
+    sf::RectangleShape rightPaddle;
62
+    rightPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
63
+    rightPaddle.setOutlineThickness(3);
64
+    rightPaddle.setOutlineColor(sf::Color::Black);
65
+    rightPaddle.setFillColor(sf::Color(200, 100, 100));
66
+    rightPaddle.setOrigin(paddleSize / 2.f);
67
+
68
+    // Create the ball
69
+    sf::CircleShape ball;
70
+    ball.setRadius(ballRadius - 3);
71
+    ball.setOutlineThickness(3);
72
+    ball.setOutlineColor(sf::Color::Black);
73
+    ball.setFillColor(sf::Color::White);
74
+    ball.setOrigin(ballRadius / 2, ballRadius / 2);
75
+
76
+    // Load the text font
77
+    sf::Font font;
78
+    if (!font.loadFromFile(resourcesDir() + "sansation.ttf"))
79
+        return EXIT_FAILURE;
80
+
81
+    // Initialize the pause message
82
+    sf::Text pauseMessage;
83
+    pauseMessage.setFont(font);
84
+    pauseMessage.setCharacterSize(40);
85
+    pauseMessage.setPosition(170.f, 150.f);
86
+    //pauseMessage.setFillColor(sf::Color::White);
87
+    
88
+    #ifdef SFML_SYSTEM_IOS
89
+    pauseMessage.setString("Welcome to SFML pong!\nTouch the screen to start the game");
90
+    #else
91
+    pauseMessage.setString("Welcome to SFML pong!\nPress space to start the game");
92
+    #endif
93
+
94
+    // Define the paddles properties
95
+    sf::Clock AITimer;
96
+    const sf::Time AITime   = sf::seconds(0.1f);
97
+    const float paddleSpeed = 400.f;
98
+    float rightPaddleSpeed  = 0.f;
99
+    const float ballSpeed   = 400.f;
100
+    float ballAngle         = 0.f; // to be changed later
101
+
102
+    sf::Clock clock;
103
+    bool isPlaying = false;
104
+    while (window.isOpen())
105
+    {
106
+        // Handle events
107
+        sf::Event event;
108
+        while (window.pollEvent(event))
109
+        {
110
+            // Window closed or escape key pressed: exit
111
+            if ((event.type == sf::Event::Closed) ||
112
+               ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
113
+            {
114
+                window.close();
115
+                break;
116
+            }
117
+
118
+            // Space key pressed: play
119
+            if (((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space)) ||
120
+                (event.type == sf::Event::TouchBegan))
121
+            {
122
+                if (!isPlaying)
123
+                {
124
+                    // (re)start the game
125
+                    isPlaying = true;
126
+                    clock.restart();
127
+
128
+                    // Reset the position of the paddles and ball
129
+                    leftPaddle.setPosition(10 + paddleSize.x / 2, gameHeight / 2);
130
+                    rightPaddle.setPosition(gameWidth - 10 - paddleSize.x / 2, gameHeight / 2);
131
+                    ball.setPosition(gameWidth / 2, gameHeight / 2);
132
+
133
+                    // Reset the ball angle
134
+                    do
135
+                    {
136
+                        // Make sure the ball initial angle is not too much vertical
137
+                        ballAngle = (std::rand() % 360) * 2 * pi / 360;
138
+                    }
139
+                    while (std::abs(std::cos(ballAngle)) < 0.7f);
140
+                }
141
+            }
142
+            
143
+            // Window size changed, adjust view appropriately
144
+            if (event.type == sf::Event::Resized)
145
+            {
146
+                sf::View view;
147
+                view.setSize(gameWidth, gameHeight);
148
+                view.setCenter(gameWidth/2.f, gameHeight/2.f);
149
+                window.setView(view);
150
+            }
151
+        }
152
+
153
+        if (isPlaying)
154
+        {
155
+            float deltaTime = clock.restart().asSeconds();
156
+
157
+            // Move the player's paddle
158
+            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) &&
159
+               (leftPaddle.getPosition().y - paddleSize.y / 2 > 5.f))
160
+            {
161
+                leftPaddle.move(0.f, -paddleSpeed * deltaTime);
162
+            }
163
+            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
164
+               (leftPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f))
165
+            {
166
+                leftPaddle.move(0.f, paddleSpeed * deltaTime);
167
+            }
168
+            
169
+            if (sf::Touch::isDown(0))
170
+            {
171
+                sf::Vector2i pos = sf::Touch::getPosition(0);
172
+                sf::Vector2f mappedPos = window.mapPixelToCoords(pos);
173
+                leftPaddle.setPosition(leftPaddle.getPosition().x, mappedPos.y);
174
+            }
175
+
176
+            // Move the computer's paddle
177
+            if (((rightPaddleSpeed < 0.f) && (rightPaddle.getPosition().y - paddleSize.y / 2 > 5.f)) ||
178
+                ((rightPaddleSpeed > 0.f) && (rightPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f)))
179
+            {
180
+                rightPaddle.move(0.f, rightPaddleSpeed * deltaTime);
181
+            }
182
+
183
+            // Update the computer's paddle direction according to the ball position
184
+            if (AITimer.getElapsedTime() > AITime)
185
+            {
186
+                AITimer.restart();
187
+                if (ball.getPosition().y + ballRadius > rightPaddle.getPosition().y + paddleSize.y / 2)
188
+                    rightPaddleSpeed = paddleSpeed;
189
+                else if (ball.getPosition().y - ballRadius < rightPaddle.getPosition().y - paddleSize.y / 2)
190
+                    rightPaddleSpeed = -paddleSpeed;
191
+                else
192
+                    rightPaddleSpeed = 0.f;
193
+            }
194
+
195
+            // Move the ball
196
+            float factor = ballSpeed * deltaTime;
197
+            ball.move(std::cos(ballAngle) * factor, std::sin(ballAngle) * factor);
198
+
199
+            #ifdef SFML_SYSTEM_IOS
200
+            const std::string inputString = "Touch the screen to restart";
201
+            #else
202
+            const std::string inputString = "Press space to restart or\nescape to exit";
203
+            #endif
204
+            
205
+            // Check collisions between the ball and the screen
206
+            if (ball.getPosition().x - ballRadius < 0.f)
207
+            {
208
+                isPlaying = false;
209
+                pauseMessage.setString("You Lost!\n" + inputString);
210
+            }
211
+            if (ball.getPosition().x + ballRadius > gameWidth)
212
+            {
213
+                isPlaying = false;
214
+                pauseMessage.setString("You Won!\n" + inputString);
215
+            }
216
+            if (ball.getPosition().y - ballRadius < 0.f)
217
+            {
218
+                ballSound.play();
219
+                ballAngle = -ballAngle;
220
+                ball.setPosition(ball.getPosition().x, ballRadius + 0.1f);
221
+            }
222
+            if (ball.getPosition().y + ballRadius > gameHeight)
223
+            {
224
+                ballSound.play();
225
+                ballAngle = -ballAngle;
226
+                ball.setPosition(ball.getPosition().x, gameHeight - ballRadius - 0.1f);
227
+            }
228
+
229
+            // Check the collisions between the ball and the paddles
230
+            // Left Paddle
231
+            if (ball.getPosition().x - ballRadius < leftPaddle.getPosition().x + paddleSize.x / 2 &&
232
+                ball.getPosition().x - ballRadius > leftPaddle.getPosition().x &&
233
+                ball.getPosition().y + ballRadius >= leftPaddle.getPosition().y - paddleSize.y / 2 &&
234
+                ball.getPosition().y - ballRadius <= leftPaddle.getPosition().y + paddleSize.y / 2)
235
+            {
236
+                if (ball.getPosition().y > leftPaddle.getPosition().y)
237
+                    ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
238
+                else
239
+                    ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
240
+
241
+                ballSound.play();
242
+                ball.setPosition(leftPaddle.getPosition().x + ballRadius + paddleSize.x / 2 + 0.1f, ball.getPosition().y);
243
+            }
244
+
245
+            // Right Paddle
246
+            if (ball.getPosition().x + ballRadius > rightPaddle.getPosition().x - paddleSize.x / 2 &&
247
+                ball.getPosition().x + ballRadius < rightPaddle.getPosition().x &&
248
+                ball.getPosition().y + ballRadius >= rightPaddle.getPosition().y - paddleSize.y / 2 &&
249
+                ball.getPosition().y - ballRadius <= rightPaddle.getPosition().y + paddleSize.y / 2)
250
+            {
251
+                if (ball.getPosition().y > rightPaddle.getPosition().y)
252
+                    ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
253
+                else
254
+                    ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
255
+
256
+                ballSound.play();
257
+                ball.setPosition(rightPaddle.getPosition().x - ballRadius - paddleSize.x / 2 - 0.1f, ball.getPosition().y);
258
+            }
259
+        }
260
+
261
+        // Clear the window
262
+        window.clear(sf::Color(50, 200, 50));
263
+
264
+        if (isPlaying)
265
+        {
266
+            // Draw the paddles and the ball
267
+            window.draw(leftPaddle);
268
+            window.draw(rightPaddle);
269
+            window.draw(ball);
270
+        }
271
+        else
272
+        {
273
+            // Draw the pause message
274
+            window.draw(pauseMessage);
275
+        }
276
+
277
+        // Display things on screen
278
+        window.display();
279
+    }
280
+
281
+    return EXIT_SUCCESS;
282
+}

二进制
resources/ball.wav 查看文件


二进制
resources/sansation.ttf 查看文件