简体   繁体   English

如何使用 SFML 在蛇游戏中定义游戏?

[英]How can I define a game over in snake game using SFML?

so recently I have been wanting to make a snake game in C++ using SFML in Microsoft Visual studio 2015 and I made one and I am actually pretty satisfied with my work but there is a problem, that I forgot to make a game over for it and it seems like I couldn't make it work and it really had me on edge.所以最近我一直想在 Microsoft Visual Studio 2015 中使用 SFML 用 C++ 制作一个蛇游戏,我制作了一个,实际上我对我的工作非常满意,但是有一个问题,我忘记为它制作一个游戏,似乎我无法让它发挥作用,这真的让我很紧张。 So I thought I could use stack overflow's help.所以我想我可以使用堆栈溢出的帮助。 I would really appreciate it if you guys would let me know how to make it work and please keep it simple obvious.如果你们让我知道如何使它工作并且请保持简单明了,我将非常感激。 Here is my code:这是我的代码:

// GraphicalLoopSnakeGame.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <ctime>
#include <SFML/Graphics.hpp>

using namespace sf;

int N = 30, M = 20;
int size = 16;
int w = size * N;
int h = size * M;

int dir, num = 4;

struct Snake {
    int x, y;
} s[100];

struct Fruit {
    int x, y;
} f;

void Tick() {
    for(int i = num; i > 0; --i) {
        s[i].x = s[i - 1].x;
        s[i].y = s[i - 1].y;
    }

    if(dir == 0) s[0].y += 1;
    if(dir == 1) s[0].x -= 1;
    if(dir == 2) s[0].x += 1;
    if(dir == 3) s[0].y -= 1;

    if((s[0].x == f.x) && (s[0].y == f.y)) {
        num++;
        f.x = rand() % N;
        f.y = rand() % M;
    }

    if(s[0].x > N) s[0].x = 0;
    if(s[0].x < 0) s[0].x = N;
    if(s[0].y > M) s[0].y = 0;
    if(s[0].y < 0) s[0].y = M;

    for(int i = 1; i < num; i++)
        if(s[0].x == s[i].x && s[0].y == s[i].y) num = i;
}

int main() {
    srand(time(0));
    RenderWindow window(VideoMode(w, h), "Snake Game!");

    Texture t1, t2, t3;

    t1.loadFromFile("images/white.png");
    t2.loadFromFile("images/red.png");
    t3.loadFromFile("images/green.png");

    Sprite sprite1(t1);
    Sprite sprite2(t2);
    Sprite sprite3(t3);

    Clock clock;
    float timer = 0, delay = 0.13;

    f.x = 10;
    f.y = 10;

    while(window.isOpen()) {
        float time = clock.getElapsedTime().asSeconds();
        clock.restart();
        timer += time;

        Event e;
        while(window.pollEvent(e)) {
            if(e.type == Event::Closed) window.close();
        }

        if(Keyboard::isKeyPressed(Keyboard::Left)) dir = 1;
        if(Keyboard::isKeyPressed(Keyboard::Right)) dir = 2;
        if(Keyboard::isKeyPressed(Keyboard::Up)) dir = 3;
        if(Keyboard::isKeyPressed(Keyboard::Down)) dir = 0;
        if(Keyboard::isKeyPressed(Keyboard::W)) dir = 3;
        if(Keyboard::isKeyPressed(Keyboard::D)) dir = 2;
        if(Keyboard::isKeyPressed(Keyboard::A)) dir = 1;
        if(Keyboard::isKeyPressed(Keyboard::S)) dir = 0;

        if(timer > delay) {
            timer = 0;
            Tick();
        }

        ////// draw  ///////
        window.clear();

        for(int i = 0; i < N; i++)
            for(int j = 0; j < M; j++) {
                sprite1.setPosition(i * size, j * size);
                window.draw(sprite1);
            }

        for(int i = 0; i < num; i++) {
            sprite2.setPosition(s[i].x * size, s[i].y * size);
            window.draw(sprite2);
        }

        sprite3.setPosition(f.x * size, f.y * size);
        window.draw(sprite3);

        window.display();
    }

    return 0;
}

In your Tick() function you can check whether the head bumps into anything after everything has moved in the given direction.在您的Tick()函数中,您可以检查在所有东西都沿给定方向移动后头部是否碰到任何东西。 If it does, let main() know about it somehow: for example, return a bool which expresses if the game is over.如果是,让main()以某种方式知道它:例如,返回一个bool ,表示游戏是否结束。 Let's say this bool is called over .假设这个bool被调用over

So, add if (over) { window.close(); }所以,添加if (over) { window.close(); } if (over) { window.close(); } inside your while (window.isOpen()) loop (right after calling Tick() ) to let main() reach return 0; if (over) { window.close(); }您的内部while (window.isOpen())循环(调用之后Tick()main()范围return 0; and finish the program.并完成程序。

EDIT: Think about using std::deque for moving your snake using less code and time: you'd be able to just pop_back() the snake tile farthest from the head and push_front() the new tile where the head currently is (after a tick), simulating crawling one step forwards.编辑:考虑使用std::deque使用更少的代码和时间移动你的蛇:你可以只pop_back()离头部最远的蛇瓦片和push_front()当前头部所在的新瓦片(之后一个滴答声),模拟向前爬行一步。

Anyway, after having moved your snake you can check each of its body tiles whether it has the same coordinates as its head.无论如何,在移动你的蛇之后,你可以检查它的每个身体图块是否与它的头部具有相同的坐标。 If it does, it means your snake crashed into its tail so the game is over.如果是这样,这意味着你的蛇撞到了它的尾巴,所以游戏结束了。

// in Tick():
// ...other logic...
tiles.pop_back();
tiles.push_front(new_head_position);
for (/* each tile of your snake except its head */) {
  if (tile.x == head.x && tile.y == head.y) {
    return false; // game over
  }
}
return true; // everything is fine

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM