2. 随机冒地鼠
4. 计时
完整代码(200行搞定!)
#include <SFML/Graphics.hpp>
#include <vector>
#include <ctime>
class WhackAMole {
sf::RenderWindow window;
struct Mole {
bool isVisible;
float timer;
Mole(float x, float y) {
shape.setPosition(x, y);
isVisible = false;
timer = 0;
}
void update(float dt) {
if(isVisible) {
if(timer >= showTime) {
hide();
} else {
if(timer >= 0.5f && rand() % 100 < 5) {
show();
}
}
void show() {
isVisible = true;
timer = 0;
}
void hide() {
isVisible = false;
}
bool contains(float x, float y) {
}
void whack() {
shape.setFillColor(sf::Color::Red);
};
std::vector<Mole> moles;
int score;
bool gameRunning;
sf::Font font;
sf::Text timeText;
sf::Text titleText;
void setupMoles() {
moles.clear();
float startY = 150;
float spacing = 150;
for(int row = 0; row < 3; row++) {
for(int col = 0; col < 3; col++) {
moles.push_back(Mole(startX + col * spacing, startY + row * spacing));
}
}
void setupText() {
font.loadFromFile("arial.ttf");
titleText.setFont(font);
titleText.setString("疯狂打地鼠");
titleText.setFillColor(sf::Color::Yellow);
titleText.setPosition(200, 30);
scoreText.setFont(font);
scoreText.setCharacterSize(36);
scoreText.setPosition(50, 550);
timeText.setFont(font);
timeText.setFillColor(sf::Color::Cyan);
}
public:
srand(time(0));
window.setframerateLimit(60);
setupMoles();
setupText();
score = 0;
gameRunning = true;
}
void run() {
sf::Clock clock;
while(window.isOpen()) {
float dt = clock.restart().asSeconds();
handleEvents();
update(dt);
render();
}
void handleEvents() {
while(window.pollEvent(event)) {
window.close();
}
if(event.type == sf::Event::MouseButtonPressed && gameRunning) {
if(event.mouseButton.button == sf::Mouse::Left) {
float mouseY = event.mouseButton.y;
for(auto& mole : moles) {
mole.whack();
mole.hide();
}
}
if(event.type == sf::Event::KeyPressed) {
resetGame();
}
}
void update(float dt) {
if(!gameRunning) return;
gameTime -= dt;
if(gameTime <= 0) {
gameRunning = false;
}
for(auto& mole : moles) {
mole.update(dt);
}
std::stringstream ss;
ss << "得分: " << score;
scoreText.setString(ss.str());
std::stringstream ts;
ts << "时间: " << int(gameTime) << "秒";
}
void render() {
window.clear(sf::Color(0, 100, 0));
window.draw(titleText);
for(const auto& mole : moles) {
if(mole.isVisible) {
window.draw(mole.shape);
}
window.draw(scoreText);
window.draw(timeText);
if(!gameRunning) {
gameOverText.setFont(font);
gameOverText.setCharacterSize(48);
gameOverText.setPosition(200, 250);
}
window.display();
}
void resetGame() {
score = 0;
gameRunning = true;
};
int main() {
WhackAMole game;
return 0;
}
四、编译运行指南
Windows(VS Code):
1. 安装SFML:官网下载,解压到C盘
2. 创建tasks.json:
{
{
"label": "编译游戏",
"args": [
"-Lc:/SFML/lib",
"-lsfml-graphics",
"-lsfml-system",
"game.exe"
]
]
}
1. 按F5运行!
重要:字体文件
把Windows的arial.ttf复制到游戏文件夹,或者换别的字体。
五、游戏如何升级?
想挑战自己?试试这些:
1. 难度增加:地鼠出现更快、更狡猾
3. 音效:打中"啪!",错过"唉..."
5. 关卡系统:时间越来越短,地鼠越来越多
六、学到的编程技能
别看只是个小游戏,你实际上学会了:
· 面向对象:Mole类封装地鼠所有行为
· 碰撞检测:鼠标点击是否打中地鼠
· 时间控制:帧率控制、倒计时
七、下一步做什么?
完成打地鼠后,你可以:
1. 贪吃蛇:更经典,学链表数据结构
3. 平台跳跃:学物理引擎和碰撞响应
4. RPG游戏:学状态机和AI行为树
最后的话
游戏开发最棒的地方:边玩边学!
每次debug就像解谜,每次运行成功就像通关。当朋友玩你做的游戏时,那种成就感比什么考试高分都爽!
记住:
每个大作游戏开发者,都是从"Hello World"开始的。
你今天写打地鼠,明天可能就在做3A游戏!
现在就去运行代码,打出第一个地鼠吧!

