简体   繁体   English

蛇游戏——尾巴运动

[英]Snake game — tail movement

I'm making a snake game and having trouble with the tail movement.我正在做一个蛇游戏,尾巴运动有问题。 I understand the logic for this part, which is that each segment of the tail follows the previous segment, starting from the end of the tail.我理解这部分的逻辑,即尾部的每一段都跟随上一段,从尾部的末端开始。 I am looking at someone else's code, and it looks like this我在看别人的代码,看起来像这样


 #include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailx[100], taily[100];
int nTail;
enum eDirecton { Stop, Left, Right, Up, Down } dir;

void Setup()
{
 gameOver = false;
 dir = Stop;
 x = width / 2;
 y = height / 2;
 fruitX = rand() % width;
 fruitY = rand() % height;
 score = 0;
}
void Draw()
{
 system("cls"); 
 for (int i = 0; i < width + 2; i++)
     cout << "#";
 cout << endl;

 for (int i = 0; i < height; i++)
 {
     for (int j = 0; j < width; j++)
     {
         if (j == 0)
             cout << "#";
         if (i == y && j == x)
             cout << "O";
         else if (i == fruitY && j == fruitX)
             cout << "F";
         else
         {
             bool print = false;
             for (int k = 0; k < nTail; k++)
             {
                 if (tailx[k] == j && taily[k] == i)
                 {
                     cout << "o";
                     print = true;
                 }
             }
             if (!print)
                 cout << " ";
         }


         if (j == width - 1)
             cout << "#";
     }
     cout << endl;
 }

 for (int i = 0; i < width + 2; i++)
     cout << "#";
 cout << endl;
 cout << "Score:" << score << endl;
}
void Input()
{
 if (_kbhit())
 {
     switch (_getch())
     {
     case 'a':
         dir = Left;
         break;
     case 'd':
         dir = Right;
         break;
     case 'w':
         dir = Up;
         break;
     case 's':
         dir = Down;
         break;
     case 'x':
         gameOver = true;
         break;
     }
 }
}
void Logic()
{
 for (int i = nTail - 1; i > 0; i--)
 {
     tailx[i] = tailx[i - 1];
     taily[i] = taily[i - 1];
 }
 tailx[0] = x;
 taily[0] = y;

 switch (dir)
 {
 case Left:
     x--;
     break;
 case Right:
     x++;
     break;
 case Up:
     y--;
     break;
 case Down:
     y++;
     break;
 default:
     break;
 }

 if (x >= width) x = 0; else if (x < 0) x = width - 1;
 if (y >= height) y = 0; else if (y < 0) y = height - 1;

 for (int i = 0; i < nTail; i++)
     if (tailx[i] == x && taily[i] == y)
         gameOver = true;

 if (x == fruitX && y == fruitY)
 {
     score += 10;
     fruitX = rand() % width;
     fruitY = rand() % height;
     nTail++;
 }
}
int main()
{
 Setup();
 while (!gameOver)
 {
     Draw();
     Input();
     Logic();
     Sleep(50); 
 }
 return 0;
}

I understand the logic but I don't understand why it works.我理解逻辑,但我不明白它为什么有效。 When we create an array, the value of each element is just a garbage value without initializing each element.当我们创建一个数组时,每个元素的值只是一个垃圾值,没有初始化每个元素。 So in the code above, when doing所以在上面的代码中,当做

tailx[i] = tailx[i-1];
taily[i] = taily[i-1];

what value is assigned to each element?为每个元素分配什么值? When displaying the snake, it has a for loop to go through every coordinate of the screen and inside it has another for loop to compare tailx[i] and taily[i] with each coordinate to find out the right position to print each segment of the tail.显示蛇时,它有一个通过屏幕的每个坐标到 go 的 for 循环,并且在它内部还有另一个 for 循环来比较 tailx[i] 和 taily[i] 与每个坐标以找出正确的 position 以打印每个段尾巴。 Since tailx and tialy are not storing the coordinates of the segments of the tail, how come this code works?由于 tailx 和 tialy 不存储尾部段的坐标,这段代码是如何工作的?

Thank you so much!!太感谢了!!

Presumably, you're missing a line at the end that looks something like:大概,你在最后错过了一条看起来像这样的行:

if(nTail < 100) { nTail++; }

Assuming that's the case, nTail is initialized to 0 and that this is all in a loop, the code probably looks something like (I'm using a size of 5 instead of 100 to make visualizing easier)假设是这种情况, nTail被初始化为 0 并且这一切都在一个循环中,代码可能看起来像这样(我使用 5 而不是 100 的大小来使可视化更容易)

int tailx[5];
int taily[5];
int nTail = 0; //length

while(true) {
    for(int i = nTail -1; i > 0; i--)
    {
         tailx[i] = tailx[i-1];
         taily[i] = taily[i-1];
    }

    // Let's assume there's some logic here the fetches a new
    //   x and y. For the sake of debugging, let's assume the
    //   values will be {(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)}

    tailx[0] = x; // x is the x-coordinate of the head
    taily[0] = y; //y is the y-coordinate of the head
    if(nTail < 5) { nTail++; }
}

Let's step through this!让我们一步一步来!

Before we enter the loop, your tail arrays are going to look like: (I'm using NA here to mean "Garbage")在我们进入循环之前,您的尾部 arrays 看起来像:(我在这里使用NA表示“垃圾”)

nTail = 0

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | NA| NA| NA| NA| NA|
+-------------------------+
|  Y  | NA| NA| NA| NA| NA|
+-------------------------+

We enter the loop, initialize i to nTail - 1 which is -1 .我们进入循环,将i初始化为nTail - 1 ,即-1 This doesn't pass the check of i > 0 , so we don't even enter the loop.这没有通过i > 0的检查,所以我们甚至没有进入循环。

We'll now grab new x and y vals and assign them into the tails, along with incrementing nTail .我们现在将获取新的xy值并将它们分配到尾部,同时增加nTail So going into the next loop our variables will look like:所以进入下一个循环,我们的变量将如下所示:

nTail = 1

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 1 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 1 | NA| NA| NA| NA|
+-------------------------+

We'll head on in, initialize i to nTail - 1 => 0 .我们将继续,将i初始化为nTail - 1 => 0 This DOESN'T pass the check of i > 0 , so again we don't enter the loop (which sounds wrong to me...maybe you're initializing nTail to 1 instead of 0?).这没有通过i > 0的检查,所以我们再次没有进入循环(这对我来说听起来不对......也许你正在将nTail初始化为 1 而不是 0?)。

We head on down, grab new x/y vals and increment nTail and restart the loop with:我们继续前进,获取新的 x/y 值并增加nTail并使用以下命令重新启动循环:

nTail = 2

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 2 | NA| NA| NA| NA|
+-------------------------+
|  Y  | 2 | NA| NA| NA| NA|
+-------------------------+

Initializing i to nTail - 1 => 1 means since i > 0 we'll finally enter the inner loop.i初始化为nTail - 1 => 1意味着由于i > 0我们将最终进入内部循环。

With i = 1 , we update our tail arrays:i = 1时,我们更新我们的尾部 arrays:

tailx[1] = tailx[0];
taily[1] = taily[0];

Then head down, grab new values and increment nTail .然后低头,获取新值并增加nTail Our variables now look like:我们的变量现在看起来像:

nTail = 3

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 3 | 2 | NA| NA| NA|
+-------------------------+
|  Y  | 3 | 2 | NA| NA| NA|
+-------------------------+

After the next loop, things will look like:在下一个循环之后,事情将如下所示:

nTail = 4

+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
|  X  | 4 | 3 | 2 | NA| NA|
+-------------------------+
|  Y  | 4 | 3 | 2 | NA| NA|
+-------------------------+

I'll leave it to you to keep tracing if you so desire.如果您愿意,我会留给您继续追踪。

You're right;你是对的; this code cannot work, and it has undefined behaviour.此代码无法工作,并且具有未定义的行为。

nTail isn't even initialised to anything. nTail甚至没有初始化为任何东西。

Are you sure it's a full program, and not just snippets glued together?你确定这是一个完整的程序,而不仅仅是粘在一起的片段吗? Or a sort of "pseudocode" to show the logic without being actual valid C++?还是一种“伪代码”来显示逻辑而不是实际有效的 C++? You'd need values for nTail and all the array elements.您需要nTail和所有数组元素的值。

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

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