Blind.Geek81 Ответов: 1

Я написал змеиную игру точно так, как описано в видео на YouTube, но я все еще не могу заставить свою змею двигаться.


Клянусь, я следовал учебнику этого парня до последней буквы; У меня нет ошибок в коде. Когда окно открывается, игроку дается указание нажать пробел, чтобы начать игру, использовать клавиши со стрелками для перемещения змеи и получить самый высокий балл. Метка ввода исчезает, и в окне появляется кусочек еды, но ни одна из клавиш со стрелками не сдвинет змею.
Есть 2 класса: змея и еда, а также форма окон. В форме есть 3 обработчика событий: Draw, KeyDown и Load.
Есть кое-что, что вам нужно знать обо мне, прежде чем вы прочтете код. Мое самое большое препятствие в программировании - это мое зрение; у меня 20/400 в правом глазу, а свет и движение рук-в левом. Чтобы что-то делать на компьютере, мне нужно увеличение не менее 300-450%. Пожалуйста, не удивляйтесь, если обнаруженная вами ошибка окажется простой; представьте себе, что вы смотрите видео на YouTube с увеличением 300+; оно очень размыто! Я в основном говорю о том, что слышу,и о том, что вижу. Мне удалось расшифровать большую часть текста, но вероятность того, что я пропустил что-то маленькое, но важное, очень высока.
Вот код для формы:
	public partial class FRM_Snake : Form
	{
		Random foodPiece = new Random();
		Graphics g;
		Snake snake = new Snake();
		Food food;
		bool moveLeft = false;
		bool moveUp = false;
		bool moveRight = false;
		bool moveDown = false;
		int Score = 0;
		public FRM_Snake()
		{
			InitializeComponent();
			food = new Food(foodPiece);
		}
		private void FRM_Snake_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyData == Keys.Space)
			{
				timer1.Enabled = true;
				LBL_Begin.Text = "";
				moveUp = false;
				moveDown = true;
				moveLeft = false;
				moveRight = false;
			}
			if (e.KeyData == Keys.Down && moveUp == false)
			{
				moveDown = true;
				moveUp = false;
				moveLeft = false;
				moveRight = false;
				snake.MoveDown();
			}
			if (e.KeyData == Keys.Up && moveDown == false)
			{
				moveDown = false;
				moveUp = true;
				moveLeft = false;
				moveRight = false;
				snake.MoveUp();
			}
			if (e.KeyData == Keys.Left && moveRight == false)
			{
				moveDown = false;
				moveUp = false;
				moveLeft = true;
				moveRight = false;
				snake.MoveLeft();
			}
			if (e.KeyData == Keys.Right && moveLeft == false)
			{
				moveDown = false;
				moveUp = false;
				moveLeft = false;
				moveRight = true;
				snake.MoveRight();
			}
		}
		private void FRM_Snake_Paint(object sender, PaintEventArgs e)
		{
			g = e.Graphics;
			food.drawFood(g);
			snake.DrawSnake(g);
		}
		private void FRM_Snake_Load(object sender, EventArgs e)
		{
			if (moveDown)
			{
				snake.MoveDown();
			}
			if (moveUp)
			{
				snake.MoveUp();
			}
			if (moveLeft)
			{
				snake.MoveLeft();
			}
			if (moveRight)
			{
				snake.MoveRight();
			}	this.Invalidate();
		}
		private void timer1_Tick(object sender, EventArgs e)
		{
			this.TSL_Score.Text = Convert.ToString(Score);
			if (moveDown)
				snake.MoveDown();
			if (moveUp)
				snake.MoveUp();
			if (moveLeft)
				snake.MoveLeft();
			if (moveRight)
				snake.MoveRight();
			//Collision Detection
			for (int i = 0; i < snake.MySnake.Length; i++)
			{
				if (snake.MySnake[i].IntersectsWith(food.foodPiece))
				{
					Score += 20;
					snake.growSnake();
					food.FoodLocation(foodPiece);
				}
			}
		}
		public void Collisoin()
		{
			for (int i = 1; i < snake.MySnake.Length; i++)
			{
				if (snake.MySnake[0].IntersectsWith(snake.MySnake[i]))
				{
					MessageBox.Show("Ouch! Quit biting yourself!\n Your total score is " + Score);
					Restart();
				}
			}
			//Use if you want game to be over when snake hits the edge of the screen
			if (snake.MySnake[0].X < 0 || snake.MySnake[0].X > 480)
			{
				MessageBox.Show("Haha! You're not a worm;\nyou can't chew through walls! Your total score is " + Score);
				Restart();
			}
			if (snake.MySnake[0].Y < 0 || snake.MySnake[0].Y > 480)
			{
				MessageBox.Show("Haha! You're not a worm;\nyou can't chew through walls! Your total score is " + Score);
				Restart();
			}
		}
		public void Restart()
		{
			Score = 0;
			this.TSL_Score.Text = "0";
			timer1.Enabled = false;
			this.LBL_Begin.Text = "Don't space out!\nPress Spacebar to begin";
			snake = new Snake();
		}
	}
</pre>
Here is the Snake class; I don't think the Food class has anything to do with my snake's lack of movement :)
<pre>	class Snake
	{
		private Rectangle[] mySnake;
		private SolidBrush myBrush;
		private int x;
		private int y;
		private int width;
		private int height;
		public Rectangle[] MySnake
		{
			get
			{
				return mySnake;
			}
		}
		//Constructor
		public Snake()
		{
			//Basic drawing components of the snake
			mySnake = new Rectangle[3];
			myBrush = new SolidBrush(Color.White);
			//The position of the snake on the game
			x = 16;
			y = 16;
			//Width and height of the snake
			width = 16;
			height = 16;
			//Give the snake a base so it can grow
			for (int i = 0; i &lt; mySnake.Length; i++)
			{
				mySnake[i] = new Rectangle(x, y, width, height);
				x -= 16;
			}
		}
		public void DrawSnake(Graphics g)
		{
			foreach (Rectangle rec in mySnake)
			{
				g.FillRectangle(myBrush, rec);
			}
		}
		public void DrawSnake()
		{
			for (int i = mySnake.Length - 1; i &gt; 0; i--)
			{
				mySnake[i] = mySnake[i - 1];
			}
		}
		public void MoveDown()
		{
			DrawSnake();
			mySnake[0].Y += 16;
		}
		public void MoveUp()
		{
			DrawSnake();
			mySnake[0].Y -= 16;
		}
		public void MoveLeft()
		{
			DrawSnake();
			mySnake[0].X -= 16;
		}
		public void MoveRight()
		{
			DrawSnake();
			mySnake[0].X += 16;
		}
		public void growSnake()
		{
			List&lt;Rectangle&gt; Rec = mySnake.ToList();
			Rec.Add(new Rectangle(mySnake[mySnake.Length - 1].X, mySnake[mySnake.Length - 1].Y, width, height));
			mySnake = Rec.ToArray();
		}
	}

http://www.youtube.com/user/TutorialHouseNz#p/a[^]
Это не помогает, когда Пример проекта, на который вы коситесь, не может быть найден, потому что у автора больше нет веб-сайта :)

Sergey Alexandrovich Kryukov

Какой учебник вы имеете в виду?
--СА

1 Ответов

Рейтинг:
11

jsharrison

Привет, я главная ошибка, которую я могу найти в вашем коде, заключается в том, что в процедуре тика таймера вы не аннулируете форму, а это означает, что форма никогда не будет перерисована при перемещении змеи.

Чтобы исправить это, просто добавьте строку " это.Invalidate()' после того, как вы переместили змею.

Вот как должна выглядеть ваша функция timer_Tick (без кода обнаружения столкновений).

private void timer1_Tick(object sender, EventArgs e)
{
    this.TSL_Score.Text = Convert.ToString(Score);
    if (moveDown)
        snake.MoveDown();
    if (moveUp)
        snake.MoveUp();
    if (moveLeft)
        snake.MoveLeft();
    if (moveRight)
        snake.MoveRight();

    this.Invalidate();
}


Кроме того, функция 'FRM_Snake_Load' не нужна, так как она вызывается только один раз при загрузке формы, и именно здесь вы аннулировали форму, чтобы перерисовать змею, но это неэффективно.

Надеюсь, это поможет.