Реализация перехода за край поля как в Pacman - C#
Формулировка задачи:
Как можно реализовать так же как в пакмане идешь в одну сторону проходишь и выходишь с противоположной строны.
Есть идея Если герой == допустим значению 2 то его переносит в определенные координаты. Где значение 2 это как бы выход
вот мой код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace SampleWFA
{
public partial class Form1 : Form
{
char[,] Map; //Карта // массив символов который определит положение элементов на карте но не в пиксилях а в своих у.е. 40*40 пикселей одна точка
Bitmap bmp; //Кодировка картинки // не а. создаем переменную типа Bitmap чтоб в ней хранить картинку грубо говоря холст на котором рисовать
Graphics g; //Подключения графики // а это в примитивной аллегории то чем рисовать
Point pointHero; //точка героя // да поле где хранятся координаты героя в координатах map'a
Point pointExit;
Point pointPerehod; //точка ФИНИША// да о том же
Keys LastUserKey; //Типо использования клавиш // последняя нажатая пользователем чтоб перемещался не как угорелый а через определенное время по таймеру
Brush brushHero; //Нарисовка героя // переменная типо Brush хранить будет в себе текстуру картинки героя
Brush brushBackground; //Рисовать фон //...
Brush brushWall; //Рисовать стены
Brush brushStart; //Рисовать старт
Brush brushExit; //Рисовать выход
Brush brushPerehod;
public Form1()
{
InitializeComponent();
Map = new char[50,50];
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height); //Это не понял// а это в переменной bmp создаем картинку размером с picturebox чтоб картинка ьыла сугубо с него размером
//кстати в глупой алегории picturebox - это рамка
g = Graphics.FromImage(bmp); //Это что можно было как я понял использовать формат bmp// нет. это чтоб то с помощью чего ты будешь рисовать (g) знал что рисует в объекте bmp(это лишь имя его)
pointHero = new Point(25, 25); //начальная точка героя//по умолчанию пусть 0,0 потом же все равно поставим как надо))
brushHero = new TextureBrush(Image.FromFile("Герой.png"));
brushBackground = new TextureBrush(Image.FromFile("Фон.png"));
brushWall = new TextureBrush(Image.FromFile("Стена.bmp"));
brushStart = new TextureBrush(Image.FromFile("Старт.png"));
brushExit = new TextureBrush(Image.FromFile("Выход.bmp"));
brushPerehod = new TextureBrush(Image.FromFile("Переход.png"));
}
private void стартToolStripMenuItem_Click(object sender, EventArgs e)
{
bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);// а теперь конкретный размер ну и пофиг что опять то же самое
g = Graphics.FromImage(bmp);// о том же
g.Clear(Color.Black);// сделать холст черным ну просто как очистить на всякий случай
pictureBox1.Image = bmp;// установим холст в рамку т.е. bmp в picturebox
LoadMission();// вызываем загрузку карты из файла реализации разные могут быть
LastUserKey = Keys.A;// да все равно какая неиспользуемая за стоять ничего не делать //ВОТ Это я вообще не понял что такое
//дык последняя кнопка нажатая игруном может быть любой в идиале. а мы используем в игре суть стрелки нам пока другие не надо а клавиша А суть лубая лишь бы ничего не делать
//вот что и знаяит любая не задействованная
// pointHero = pointStart;// когда загрузили карту можем установить колординаты начальные героя пусть на место старта
timer1.Start();// запускаем таймер по каждому тику которого будет изменяться что-то на форме-экране
Up.Stop(); Down.Stop(); Left.Stop(); Right.Stop();
}
private void стопToolStripMenuItem_Click(object sender, EventArgs e) //СТОП
{
timer1.Stop(); Up.Stop(); Down.Stop(); Left.Stop(); Right.Stop();
}
private void выходToolStripMenuItem_Click(object sender, EventArgs e) //ВЫХОД
{
Application.Exit();
}
private void Form1_KeyDown(object sender, KeyEventArgs e) //НЕ знаю// событие для формы кнопка нажата какая-то
//кликни в дизайнере формы на саму форму открой панель свойства и щелкни сверху на молнии там увидишь все события на которые форма реагирует
//практически все они будут пусты за исключением KeyUp KeyDown
{
LastUserKey = e.KeyCode;// от параметра события е сохраним нажатую кнопку чтоб при тике таймера знать куда бежать
if (e.KeyCode == Keys.Up)
{
Up.Start();
Down.Stop();
Left.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Down)
{
Down.Start();
Up.Stop();
Left.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Left)
{
Left.Start();
Up.Stop();
Down.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Right)
{
Right.Start();
Up.Stop();
Down.Stop();
Left.Stop();
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
LastUserKey = Keys.A;// да все равно какая неиспользуемая за стоять ничего не делать// ага как отпустили кнопку т.е. UP ее в переменную установим пофиг какое знаяение лишь бы ничего не делать
if (e.KeyCode == Keys.Up)
{
Up.Start();
Down.Stop();
Left.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Down)
{
Down.Start();
Up.Stop();
Left.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Left)
{
Left.Start();
Up.Stop();
Down.Stop();
Right.Stop();
}
if (e.KeyCode == Keys.Right)
{
Right.Start();
Up.Stop();
Down.Stop();
Left.Stop();
}
}
private void timer1_Tick(object sender, EventArgs e) //Таймер если герой равняется таймеру то вылаит сообщение ????// а вот это главный обработчик
//если в дизайнере выберешь Timer и откроешь его свойства то там будет Intrval в которм в милисекундах задан период через который происходит тик как в часах
//там стоит по-моему 200
{
if (timer1.Interval > 70) timer1.Interval = 70;
PaintMap();
if (pointHero == pointPerehod)
{
pointHero = new Point(25, 2);
}
if (pointHero == pointExit)
{
timer1.Stop();//таймер остановить чтоб не тикал и ничего более не менялось
MessageBox.Show("Вы победили!");//вывести мессагу ура победа))
return;//ну и закончить обработчик т.к. смысла продолжать передвигать что-то уже нет
}
//в противном случае
HeroStep();//вызвать метод пересчитывающий следующее положение героя
}
private void HeroStep()
{
switch (LastUserKey)
{
case Keys.Down:
if (pointHero.Y < 50 && Map[pointHero.X,pointHero.Y + 1]!='1')
{
pointHero.Y++;
}
break;
case Keys.Left:
if (pointHero.X > 0 && Map[pointHero.X - 1, pointHero.Y] != '1')
{
pointHero.X--;
}
break;
case Keys.Right:
if (pointHero.X < 50 && Map[pointHero.X + 1, pointHero.Y] != '1')
{
pointHero.X++;
}
break;//синтаксис так положено а в общем break прерывает или пару switch-case или цикл
case Keys.Up:
if (pointHero.Y > 0 && Map[pointHero.X, pointHero.Y - 1] != '1')
{
pointHero.Y--;
}
break;
default:
break;
}
}
private void PaintMap()
{
Brush br = null; //типо присваевается значение нул только хз для чего // а все для того же чтоб компилятор не мудрил моль создана переменная а не инициализирована
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 50; j++)//перебираем все по строкам столбцам в позиции
{
switch (Map[i,j])//опять переключатель по значению
{
case '0': //Рисуется фон// да как в readme тебе писал
br = brushBackground;// в вышеупомянутый br суем уже конкретную текстуру
break;
case '1': //РИСУЕТСЯ стена
br = brushWall;
break;
case '2': //Рисуется переход
br = brushPerehod;
break;
case '3': //РИсуется ФИНИШ
br = brushExit;
break;
default:
br = new SolidBrush(Color.Black); //не знаю// а это опять если не то и не друго пусть хоть что-то будет
break;
}
g.FillRectangle(br, i * 10, j * 10, 10, 10); //не знаю// в нашем bmp с использованием контента g рисуем закрашеный прямоугольник кистью br и координатами i j масштабируемыми на размер элемента 40*40 ну и размер его 40*40
}
}
g.FillRectangle(brushHero, pointHero.X * 10, pointHero.Y * 10, 10, 10); // не знаю// тоже самое но рисуем уже героя в его координатах помни что координаты героя в элементах пизиции а в пиксели переводится масштабированием бишь умножением на размер картинки
pictureBox1.Refresh(); //типо обновить пикчер бокс ток хз зачем// чтоб новая картинка появилась не дожидаясь системных инвалидов т.е. принудительно
}
private void LoadMission() //загрузка уровня
{
using (StreamReader sr = new StreamReader("Map.txt")) //это как я понял из этого тхт файла и обрисовывается вся карта.//ага
{
string str=""; //все что тут написано я не понял :)написано я не понял//создали вспомагательные переменные str куда строку с файла кинем
int i=0, j=0; // и i j для циклов, строка нужна чтоб не заморачиваться на символы перевод строки и конец строки
while (sr.Peek() != -1)//а куда while делся// его для того чтоб читать пока не кончится файл// ну зная размер файла можно и без него в принципе но до кучи пусть так
{
str = sr.ReadLine();//читаем с потока sr строку
for (i = 0; i < 50; i++)//разбираем строку по-элементно создаем цикл по переменной i
{
// if (str[i] == '2') pointHero = new Point(i, j);
if (str[i] == '3') pointExit = new Point(i, j);
Map[i, j] = str[i];
}
j++;
}
}
}
private void Up_Tick(object sender, EventArgs e)
{
if (Up.Interval > 70) Up.Interval = 70;
Point cor = pointHero;
if (pointHero.Y > 0 && Map[pointHero.X, pointHero.Y - 1] != '1')
if (cor.Y == '1') Up.Stop();
else
{
cor.Y--;
pointHero = cor;
}
}
private void Down_Tick(object sender, EventArgs e)
{
if (Down.Interval > 70) Down.Interval = 70;
Point cor = pointHero;
if (pointHero.Y < 50 && Map[pointHero.X, pointHero.Y + 1] != '1')
if (cor.Y == '1') Down.Stop();
else
{
cor.Y++;
pointHero = cor;
}
}
private void Left_Tick(object sender, EventArgs e)
{
if (Left.Interval > 70) Left.Interval = 70;
Point cor = pointHero;
if (pointHero.X > 0 && Map[pointHero.X - 1, pointHero.Y] != '1')
if (cor.Y == '1') Left.Stop();
else
{
cor.X--;
pointHero = cor;
}
}
private void Right_Tick(object sender, EventArgs e)
{
if (Right.Interval > 70) Right.Interval = 70;
Point cor = pointHero;
if (pointHero.X < 50 && Map[pointHero.X + 1, pointHero.Y] != '1')
if (cor.X == '1') Right.Stop();
else
{
cor.X++;
pointHero = cor;
}
}
}
}Решение задачи: «Реализация перехода за край поля как в Pacman»
textual
Листинг программы
private void Right_Tick(object sender, EventArgs e)
{
Point cor = pointHero;
if (pointHero.X < 50 && Map[pointHero.X + 1, pointHero.Y] == '2')
{
pointHero = new Point(49, 25);
}
if (pointHero.X < 50 && Map[pointHero.X + 1, pointHero.Y] != '1')
if (cor.X == '1') Right.Stop();
else
{
cor.X++;
pointHero = cor;
}
}