Разработка приложения, состоящего из прикладного окна

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    255,93 Кб
  • Опубликовано:
    2015-06-22
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка приложения, состоящего из прикладного окна

Министерство общего и профессионального образования

Российской Федерации

Казанский государственный технический университет

имени. А.Н. Туполева

Кафедра АСОИУ








Курсовая работа

по дисциплине «Технология программирования»


Исполнитель:

студент группы

Руководитель:

Оценка _____________________

Подпись_____________________




Казань 2015

Оглавление

1. Введение

1.1 Задание

1.2 Уточнение задания

2. Аннотация

3. Описание разрабатываемой программы с точки зрения пользователя

4. Описание разрабатываемой программы с точки зрения программиста

4.1 Объектное представление программы

4.2 События

4.3. Потоки

5. Поэтапная разработка программной системы

5.1 Разработка класса обычного объекта

5.2 Разработка классов Enemy и Dot

5.3 Разработка классов Wall и Map

5.4 Разработка прикладного окна

5.5 Разработка собственных Exception и Логгера

6. Описание проблем, возникших при разработке программной системы.

7. Заключение

8. Список используемой литературы

Приложения

1. Введение

        

         1.1 Задание


Разработать оконное приложение, в окне которого будет лабиринт.

По лабиринту должны перемещать враг. Игрок, должен убегая от врагов собирать монетки.

Программа должна содержать:

классы

наследование

объекты

потоки

синхронизация потоков

делегаты и события

обработка исключений

Минимум 3 пункта меню, 2 из них должны содержать 3 подпункта.

        

         1.2 Уточнение задания


Программа состоит их прикладного окна. В области клиента прикладного окна расположен лабиринт. В игре несколько уровней. Каждый уровень представлен в виде квадратной матрицы где 0 это монетка, 1 стена, 2 игрок, 3 враг. Враги и игрок представлены в виде квадратов, на которые наложены изображения. Каждый враг и игрок имеют свой поток.

Окно так же содержит меню, в котором есть кнопки запуска игры, выбора уровней, отключения изображений и включения коллизий.

Программы реализовать в среде Microsoft Visual Studio 2013 на языке C#.

         2. Аннотация


В данной курсовой работе рассмотрены следующие инструменты для разработки программного обеспечения на языке C#: Классы, делегаты, работа с потоками, обработка исключений, наследование, работа с окнами и меню. Была рассмотрена пошаговая разработка приложения.

3. Описание разрабатываемой программы с точки зрения пользователя

Программа представлена прикладным окном. В окне перемещаются n врагов.

Окно так содержит меню, в котором есть кнопки запуска игры, выбора уровней, отключения изображений и включения коллизий.

Диаграмма вариантов использования языка UML изображает действия, выполняемые пользователем программы. С точки зрения пользователя приложение предполагает три варианта использования:

·        запустить игру

·        перезапустить уровень

·        загрузить уровень

·        отключить/включить изображения

·        отключить/включить показ столкновений

·        сбросить прохождение

·        открыть окошко «об игре»

·        управлять персонажем с помощью клавиш

Диаграмма вариантов использования представлена на рис. 3.1.

Рис. 3.1. Диаграмма вариантов использования приложения

Прекращение выполнения программы происходит при закрытии прикладного окна или при нажатии меню «выход»

4. Описание разрабатываемой программы с точки зрения программиста

        

         4.1 Объектное представление программы


Программа включает объекты разных типов. Главными объектами программы являются объект прикладного окна класса MainWindow. При старте игры уровень считывается из файла в 2мерный List. Класс Map создает все Entity расположенные на уровне (классы Player, Enemy, Dot). Класс Wall строит лабиринт. После срабатывания события LevelLoad, экземпляры Player, Enemy и Map запускают потоки. Все все созданные игровые объекты хранятся в списке _entities. Map в цикле пробегается по каждого игрового объекта и проверяет его пересечение со всеми остальными, а также посылает в Wall для проверки пересечения со стеной. Wall приводит координаты объекта к индексу в матрице и проверяет ячейку на наличие там стены. В случае столкновения объекта с другим у обоих объектов вызывается соответственная функция:

При столкновения игрока с врагом тратится жизнь.

При столкновении игрока с монетой, увеличиваются очки, монета исчезает.

Если игрок столкнулся с врагом при 0 жизней, игрок умирает, а уровень перезагружается. Когда игрок съедает все монеты, загружается следующий уровень.

При столкновении со стеной объект выезжает из стены (Player останавливается, а Enemy произвольно меняет направление движения). Во время движения, каждый раз, когда по бокам от Enemy есть пустые ячейки, Enemy произвольно может сменить направление с шансом от 30 до 70% (процент смены направления генерируется случайно в пределах заданного значения для каждого экземпляра).

4.2 События

В программе имеются несколько событий.

LevelLoad - Генерирует Map когда полностью создан уровень.

RestartLevel - Генерирует Map когда уровень перезагружается.

OnKeyDown - системное событие нажатия клавиши;

onKeyUp - системное событие отпускания клавиши;

        

         4.3 Потоки

приложение окно игра

Помимо основных потоков wpf, в программе используется дополнительные потоки. Класс Map создает поток для проверки коллизии. Враги и Игрок также имеют свой собственный поток для каждого экземпляра, в которых они перемещаются и реагируют на события.

         5. Поэтапная разработка программной системы


Разработка приложения будет осуществляться поэтапно. Вначале разработаем класс Map и Wall, которые будут отвечать за сцену. Создадим класс Player, и сделаем передвижение игрока по нажатию на кнопки. Затем создадим базовый класс Entity от которого наследуем класс Player потокового объекта и протестируем его. Вынесем в Entity базовые свойства игровых объектов. Создадим механизм проверки столкновений со стеной. Затем создадим и отладим класс Enemy, и протестируем механизм столкновений между врагами и игроком. Сделаем чтобы при столкновении со стеной враг менял направление. Сделаем определение пустых ячеек по бокам от врага, и генерацию процента для случайной смены направления во время движения. Создадим класс Dot и отнаследуем от Entity. Сделаем механизм поедания монет. Далее сделаем жизни, и смерть игрока. Сделаем перезагрузку уровней. Добавим меню.

.1 Разработка класса обычного объекта

На первом этапе создадим абстрактный базовый класс Entity, от которого будут наследоваться игровые объекты:

Перечисление типов игровых объектов:

public enum Type

{= 0,= 1,= 2,= 3,

}

Функции:(Canvas canvas, Map map, int x, int y)- Конструктор классаvoid OnRestart() Действия при перезагрузке уровня

void UpdateThread() функция потока

virtual void Sleep() приостановка потока

void StartUpdate() старт потока

void HideImage(bool isHide) скрыть изображения

void SetZIndex(int index) задает z-индекс для изображения

void InitImage() Инициализирует изображение

void SetImage(String path) Задает изображение

void SetLocation(int x, int y) Перемещает объект в указанные координаты

Rect GetRect() возвращает параллельный осям ограничивающий прямоугольник объекта AABB (axis-aligned bounding box)

virtual void Move(Vector velocity) перемещает объект по заданному вектору скорости

virtual void Update() функция обновления для объектов с потоком

Type GetEntityType() возвращает тип объекта

abstract void Collision(Collision c) срабатывает при коллизии объекта

virtual void Destroy() уничтожает объект

void Stop() останавливает поток

Далее создадим класс Player и пронаслеуем его от Entity

функции:(Canvas canvas, Map map, MainWindow window, int x, int y)

: base(canvas, map, x, y) конструкторonLevelLoad() обработчик события LevelLoad UpdateImage() обновление изображения

void WallCollision() столкновение со стеной

void onKeyDown(object sender, KeyEventArgs e) обработчик нажатия клавишиonKeyUp(object sender, KeyEventArgs e) обработчик отпускания клавиши CheckDirection() проверяет можно ли двигаться дальше в заданном направлении

Результат:

Игрок перемещается по сцене по нажатию на клавиши.

        

         5.2 Разработка классов Enemy и Dot


Добавим класс Enemy. Класс врагов, перемещается в произвольных направлениях.

Enemy(Canvas canvas, Map map,int x, int y):base(canvas,map, x, y) onLevelLoad() Обработчик события загрузки уровня

void СheckSideDirecktion() проверяет боковые стороны для смены движения

void RandomSpeed() генерирует случайную скорость

так же добавим класс Dot - класс монетки. Исчезает при столкновении с игроком.

Dot(Canvas canvas, Map map, int x, int y, int width) конструкторvoid Collision(Collision c) обработка столкновений

         5.3 Разработка классов Wall и Map


Создадим классы которые будут рисовать лабиринт и управлять столкновениями.

Класс Wall менеджер лабиринта

void Draw() Рисует лабиринт по матрице

void DrawBlock(int x, int y) создает квадраты для блоков лабиринта

void DrawImage(int x, int y) создает тайлы для лабиринта

void HideSprites(bool isHide) скрывает изображенияGetIndex(int x) переводит координату в индекс

bool CheckCollision(Rect rect) проверяет пересечение прямоугольника со стеной

bool Intersect(Rect r1, Rect r2) проверяет пересечение 2х прямоугольников

Rect GetRect(int w, int h) возвращает прямоугольник эквивалентный индексу в массиве

List<Vector> CheckSides(Rect rect, Vector direction) возвращает список возможных направлений для смены направления движения.

int GetTail(int x, int y) приравнивает координаты к сетке

Класс Map Менеджер игровых объектов

Map(Canvas canvas, MainWindow parentWindow) конструктор класса

void LoadMap(String path) считывает уровень из файла

void Load(String path) загружает уровень

void AddChild(Entity entity) добавляет игровой объект на карту

void CreatePlayer(int x, int y) создает игрока

void CreateEnemy(int x, int y) создает врага

void CreateDot(int x, int y) создает монетку

bool IsEmpty(Rect r) проверяет прямоугольник на пересечение со стеной

void draw() создает и расставляет объекты на сцене

void InvokeEvent(MapEvent mapEvent) создает заданное событие

void PlayerDie() функция срабатывает при смерти игрока

void CollisionUpdate() проверка коллизий

void AddScore() срабатывает, когда игрок есть монетку

void CheckEntityCollision() проверяет столкновения между объектами

HideSprites(bool isHide) скрывает картинки

void ClearCollisions() скрывает прямоугольники, показывающие места столкновений

SolidColorBrush GetSolidBrush(Color color, float opacity = 0.3f) возвращает кисть с заданными параметрами

List<Vector> CheckNext(Rect rect, Vector direction) обертка для функции CheckSides() в классе Wall

Rect GetFlipping(Rect rect) приравнивает прямоугольник к сетке

Rect GetFlipping(Rect rect) Задает Rectangle размеры из Rect

Rectangle GetDebugRectangle(int index) достает Rectangle из пула объектов, либо создает новый, если свободных нет.

void Destroy() Уничтожает карту

Результат:

Объекты сталкиваются со стенами и между собой.

        

         5.4 Разработка прикладного окна


Разработка функционала окошка.

MainWindow() конструктор

void InitLevels() инициализирует уровни

void OnLevelLoad() обработчик события LevelLoad

void NextLevel() загрузка следующего уровня

void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) обработчик закрытия окна

void StartGameMenu_OnClick(object sender, RoutedEventArgs e) Обработчик меню «новая игра»

void DebugMenu_OnClick(object sender, RoutedEventArgs e) обработчик меню «скрыть спрайты»

void CollisionMenu_OnClick(object sender, RoutedEventArgs e) обработчик меню «показать коллизию»

void ExitMenu_OnClick(object sender, RoutedEventArgs e) обработчик меню «выход»

void AboutMenu_OnClick(object sender, RoutedEventArgs e) обработчик меню «Об игре»

void MenuRestart_OnClick(object sender, RoutedEventArgs e) обработчик меню «Рестарт»

void MenuLevel1_OnClick(object sender, RoutedEventArgs e) обработчик меню «Левел1»

void MenuLevel2_OnClick(object sender, RoutedEventArgs e) обработчик меню «Левел2»

void MenuLevel3_OnClick(object sender, RoutedEventArgs e) обработчик меню «Левел3»

void MenuCancel_OnClick(object sender, RoutedEventArgs e) обработчик меню «Сбросить»

void LoadLevel() Загрузка уровня

void UpdateHP() обновляет хп на экране

Результат:

Появилось оформление окна и меню.

рис 5.4.1 Окно игры

         5.5 Разработка собственных Exception и Логгера


Создадим класс LocalExeption для обработки собственных ошибок.

LocalExeption(string message):base(message) конструктор

Далее cсоздадим класс Logger который будет записывать ошибки в файл Log.txt

Logger() конструктор

static void Write(string str) Записывает сообщение в файл лога

static void Write(Exception e) Записывает содержание ошибки в файл лога

static void Open() открывает файл

static void Close() закрывает файл

После чего добавим конструкцию которая будет отлавливать пользовательские ошибки и записывать их в лог:

try

{

}(LocalExeption e)

{.Write(e);

}

        
6. Описание проблем, возникших при разработке программной системы


Поэтапная разработка программы позволила быстро разработать её и отладить. Проблем не было.

        

         7. Заключение


В ходе разработки приложения были закреплены навыки языка C#, а так же навыки поэтапной разработки программного обеспечения.

         8. Список используемой литературы


1.   Троелсен Э. Язык программирования C# 2010 и платформа .NET 4.0 Вильямс, 2010 -1392с

2.      Медведев В.И. Программирование на С++, C++.NET и С#: - Казань: Мастер Лайн, 2005. - 270 c.: ил. - (Серия «Современная прикладная математика и информатика»).

3.      Applications = Code + Markup: A Guide to the Microsoft® Windows® Presentation Foundation: A Guide to the Microsoft Windows Presentation Foundation (Developer Reference) Hardcover by Charles Petzold - September 13, 2006 -944 с

4.      Microsoft Documentation <https://msdn.microsoft.com/>

        

         Приложение 1. Диаграмма классов разработанной программы


         Приложение 2. Исходный код разработанной программы

.csSystem;System.Collections.Generic;System.Linq;System.Reflection;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Controls.Primitives;System.Windows.Media;System.Windows.Media.Imaging;System.Windows.Shapes;System.Windows.Threading;wpfman

{class Entity

{enum Type

{= 0,= 1,= 2,= 3,

}Entity(Canvas canvas, Map map, int x, int y)

{

_map = map;

_canvas = canvas;.AddChild(this);();(x, y);

_startX = x;

_startY = y;= false;

}virtual void OnRestart()

{(_startX, _startY);

}void UpdateThread()

{(IsWorking)

{

_image.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new(() =>

{(this)

{

{();

}(LocalExeption e)

{.Write(e);

}

}

}));();

}.Write("End thread "+ GetEntityType());

}virtual void Sleep()

{.Sleep(20);

}void StartUpdate()

{= new Thread(UpdateThread);= true;.Start();

}void HideImage(bool isHide)

{

_image.Visibility = (isHide)?Visibility.Hidden : Visibility.Visible;

}void SetZIndex(int index)

{.SetZIndex(_image, index);

}void InitImage()

{

_image = new Image();= new ScaleTransform();.ScaleX = 1;= new RotateTransform();.Angle = 0;

_image.Stretch = Stretch.Fill;myTransformGroup = new TransformGroup();.Children.Add(Scale);.Children.Add(Rotation);

_image.RenderTransform = myTransformGroup;

_image.RenderTransformOrigin = new Point(0.5, 0.5);

_canvas.Children.Add(_image);

}void SetImage(String path)

{bi = new BitmapImage();.BeginInit();.UriSource = new Uri(path, UriKind.Relative);.EndInit();

_image.Source = bi;

}void SetLocation(int x, int y)

{(this)

{.SetLeft(_image, x);.SetTop(_image, y);

}

}Rect GetRect()

{(_image == null) return new Rect();x = Convert.ToInt64(_image.GetValue(Canvas.LeftProperty));y = Convert.ToInt64(_image.GetValue(Canvas.TopProperty));width = Convert.ToInt64(_image.GetValue(Canvas.ActualWidthProperty));height = Convert.ToInt64(_image.GetValue(Canvas.ActualHeightProperty));new Rect(new Point(x, y), new Size(width, height));

}virtual void Move(Vector velocity)

{.SetLeft(_image, Position.X + velocity.X);.SetTop(_image, Position.Y + velocity.Y);

}virtual void Update()

{

}abstract Type GetEntityType();virtual void Destroy()

{(IsRemoved) return;(this)

{.Write("Begin destroy" + GetEntityType());= true;

_map.RestartLevel -= OnRestart;(IsWorking)

{= false;(updateThread != null)

{.Abort();.Join();

}

}

_image.Source.Freeze();

_image.Source = null;

_image.RenderTransform = null;

_canvas.Children.Remove(_image);

_map = null;

_canvas = null;.Write("End destroy" + GetEntityType());

}

}void Stop()

{= false;

}abstract void Collision(Collision c);Point Position

{

{

{x = Convert.ToInt64(_image.GetValue(Canvas.LeftProperty));y = Convert.ToInt64(_image.GetValue(Canvas.TopProperty));new Point(x, y);

}

{.Write("_image = null");new Point(0, 0);

}

}

}ScaleTransform Scale

{{ return _scale; }{ _scale = value; }

}RotateTransform Rotation

{{ return _rotation; }{ _rotation = value; }

}bool IsWorking { get; private set; }Vector Velocity { get; protected set; }bool IsDebug { get; protected set; }bool IsRemoved { get; protected set; }Thread updateThread;Map _map;Image _image;RotateTransform _rotation;ScaleTransform _scale;Canvas _canvas;readonly int _startX;readonly int _startY;readonly static Vector Up = new Vector(0, -1);readonly static Vector Down = new Vector(0, 1);readonly static Vector Left = new Vector(-1, 0);readonly static Vector Right = new Vector(1, 0);readonly static Vector Zero = new Vector(0, 0);

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Input;System.Windows.Media;System.Windows.Media.Imaging;System.Windows.Threading;wpfman

{Player: Entity

{MainWindow _window;Player(Canvas canvas, Map map, MainWindow window, int x, int y)

: base(canvas, map, x, y)

{.Write("create player");("/pacman.png");

_window = window;

_window.KeyDown += onKeyDown;

_window.KeyUp += onKeyUp;

_newVelocity = new Vector();

_map.RestartLevel += OnRestart;(5);.LevelLoad += OnLevelLoad;

}void OnLevelLoad()

{();

}override void Collision(Collision c)

{(this)

{(c.Type)

{Type.Wall:();;Type.Enemy:

_map.PlayerDie();;Type.Dot:

_map.AddScore();;

}

}

}void UpdateImage()

{scale = 1;angle = 0;(Velocity == Up)

{= -90;

}(Velocity == Down)

{= 90;

}(Velocity == Left)

{= -1;

}.Angle = angle;.ScaleX = scale;

}void WallCollision()

{= Zero;

}override void Update()

{.Update();(_newVelocity != Velocity)

{();

}(Velocity * Global.PLAYER_SPEED);(Velocity != Zero) UpdateImage();

}void onKeyDown(object sender, KeyEventArgs e)

{(e.Key)

{Key.Left:

_newVelocity = Left;;Key.Right:

_newVelocity = Right;;Key.Down:

_newVelocity = Down;;Key.Up:

_newVelocity = Up;;

}();

}void onKeyUp(object sender, KeyEventArgs e)

{

_newVelocity = Zero;

}CheckDirection()

{(_newVelocity != Zero)

{r = GetRect();.Offset(_newVelocity);(_map.IsEmpty(r))

{= _newVelocity;

}

}

}override Type GetEntityType()

{Type.Player;

}override void Destroy()

{.Destroy();

_window.KeyDown -= onKeyDown;

_window.KeyUp -= onKeyUp;

_window = null;

}Vector _newVelocity;

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Media;System.Windows.Shapes;wpfman

{Enemy : Entity

{private int Chance;static Random Randomizer = new Random(DateTime.Now.Millisecond);Enemy(Canvas canvas, Map map,int x, int y):base(canvas,map, x, y)

{.Write("create player");("/ghost.png");();();= Randomizer.Next(3,7);.RestartLevel += OnRestart;.LevelLoad += OnLevelLoad;(3);

}void OnLevelLoad()

{();

}override Type GetEntityType()

{Type.Enemy;

}override void Update()

{(IsWorking)

СheckSideDirecktion();(Velocity*Global.ENEMY_SPEED);

}

}override void Sleep()

{.Sleep(40);

}override void Collision(Collision c)

{(this)

{(c.Type)

{Type.Wall:();;Type.Enemy:(Velocity == c.Velocity) return;= -Velocity;(Velocity * Global.PLAYER_SPEED);;

}

}

}СheckSideDirecktion()

{currentRect = GetRect();flippingRect = _map.GetFlipping(currentRect);(currentRect != flippingRect) return;sides =_map.CheckNext(GetRect(),Velocity);(sides.Count == 0) return;k = Randomizer.Next(10);(k > Chance)

{= Randomizer.Next(sides.Count);= sides[k];

}

}void RandomSpeed()

{rnd=new Random();i = rnd.Next(4);(i)

{0:= Up;;1:= Left;;2:= Down;;:= Right;;

}

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading.Tasks;System.Windows;System.Windows.Controls;wpfman

{Dot : Entity

{Dot(Canvas canvas, Map map, int x, int y, int width)

: base(canvas, map, x, y)

{("/dot.png");(1);

}override void Collision(Collision c)

{(this)

{(c.Type)

{Type.Player:();;

}

}

}override Type GetEntityType()

{Type.Dot;

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Media;System.Windows.Media.Imaging;System.Windows.Shapes;wpfman

{Wall

{List<List<int>> _data = new List<List<int>>();readonly Canvas _canvas;bool IsDebug { get; set; }Rectangle DebugRect { get; set; }Rectangle DebugCollision { get; set; }bool IsActive { get; set; }private List<Image> _images = new List<Image>();private List<Rectangle> _debugBlocks = new List<Rectangle>();Wall(List<List<int>> data, Canvas c)

{= true;

_data = data;

_canvas = c;

}void Draw()

{h = 0;(var line in _data)

{w = 0;(var cell in line)

{x = w * Global.TILE;y = h * Global.TILE;(cell == 1)

{(x, y);(x, y);

}

++w;

}

++h;

}

}void DrawBlock(int x, int y)

{rect = new Rectangle();.Width = Global.TILE;.Height = Global.TILE;.Fill = new SolidColorBrush(Color.FromArgb(255,54,54,54));.StrokeThickness = 1;.Stroke = Brushes.Black;

_canvas.Children.Add(rect);.SetLeft(rect, x);.SetTop(rect, y);.SetZIndex(rect, 0);.Visibility = Visibility.Collapsed;

_debugBlocks.Add(rect);

}void DrawImage(int x, int y)

{img = new Image();

_canvas.Children.Add(img);bi = new BitmapImage();.BeginInit();.UriSource = new Uri("wall.png", UriKind.Relative);.EndInit();.Source = bi;.SetLeft(img, x);.SetTop(img, y);

_images.Add(img);

}void HideSprites(bool isHide)

{(var debugBlock in _debugBlocks)

{.Visibility = (isHide) ? Visibility.Visible : Visibility.Collapsed;

}.Yield();(var img in _images)

{.Visibility = (isHide) ? Visibility.Collapsed : Visibility.Visible;

}

}int GetIndex(int x)

{index = x / Global.TILE;(index > _data.Count)

{= 0;new LocalExeption("Выход за пределы карты; GetIndex index =" + index);

}index;

}bool CheckCollision(Rect rect)

{n = _data.Count;(int i = 0; i < n;i++)

{count = _data[i].Count;(int j = 0; j < count; j++)

{(_data[i][j] == 1)

{r = GetRect(j, i);(Intersect(rect, r))

{true;

}

}

}

}false;

}bool Intersect(Rect r1, Rect r2)

{x1 = Math.Max(r1.X, r2.X);y1 = Math.Max(r1.Y, r2.Y);x2 = Math.Min(r1.Right, r2.Right);y2 = Math.Min(r1.Bottom, r2.Bottom);((x1 < x2) && (y1 < y2))

{true;

}false;

}

/*Возвращает прямоугольник по индексу в массиве*/Rect GetRect(int w, int h)

{new Rect(new Point(w * Global.TILE, h * Global.TILE), new Size(Global.TILE, Global.TILE));

}List<Vector> CheckSides(Rect rect, Vector direction)

{x = GetIndex((int)rect.X);y = GetIndex((int)rect.Y);<Vector> sides = new List<Vector>();((direction == Entity.Down) || (direction == Entity.Up))

{(GetTail(x + 1, y) != 1)//право

{.Add(Entity.Right);

}(GetTail(x - 1, y) != 1)//лево

{.Add(Entity.Left);

}

}if ((direction == Entity.Right) || (direction == Entity.Left))

{(GetTail(x, y - 1) != 1)

{.Add(Entity.Up);

}(GetTail(x, y + 1) != 1)

{.Add(Entity.Down);

}

}sides;

}Rect GetFlipping(Rect rect)

{flippingRect = new Rect();.X = GetIndex((int)rect.X) * Global.TILE;.Y = GetIndex((int)rect.Y) * Global.TILE;.Width = Global.TILE;.Height = Global.TILE;flippingRect;

}int GetTail(int x, int y)

{((y < _data.Count) && (x < _data[y].Count))

{_data[y][x];

}

{new LocalExeption("Выход за пределы карты; GetTail() x="+x+" y="+y);

}

}void Destroy()

{.ClearRectList(_debugBlocks, _canvas);(var image in _images)

{.Source.Freeze();

_canvas.Children.Remove(image);

}

_images.Clear();

_data.Clear();

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Shapes;System.Windows.Media;System.Windows.Threading;wpfman.Properties;wpfman

{Map

{Map(Canvas canvas, MainWindow parentWindow)

{+= OnLevelLoad;+= parentWindow.OnLevelLoad;

_canvas = canvas;

_parentWindow = parentWindow;

_wall = new Wall(_data, _canvas);= true;

_debugPull = new List<Rectangle>();

_debugCollision = new List<Rectangle>();

}void LoadMap(String path)

{[] level = System.IO.File.ReadAllLines(path);(var str in level)

{<int> line = new List<int>();(var chr in str)

{.Add(Convert.ToInt32(chr.ToString()));

}

_data.Add(line);

}

}void Load(String path)

{(path);();

_wall.Draw();

}void AddChild(Entity entity)

{

_entities.Add(entity);

}void CreatePlayer(int x, int y)

{Player(_canvas, this,_parentWindow, x, y);

}void CreateEnemy(int x, int y)

{Enemy(_canvas, this, x, y);

}void CreateDot(int x, int y)

{newX = x + ((Global.TILE) / 2)-5;newY = y + ((Global.TILE) / 2)-5;Dot(_canvas, this, newX, newY, 10);

++_maxScore;

}bool IsEmpty(Rect r)

{!_wall.CheckCollision(r);

}void draw()

{h = 0;(var line in _data)

{w = 0;(var cell in line)

{x = w * Global.TILE;y = h * Global.TILE;(cell == (int)Entity.Type.Dot)

{(x, y);

}(cell == (int)Entity.Type.Player)

{(x, y);

}(cell == (int)Entity.Type.Enemy)

{(x, y);

}

++w;

}

++h;

}(LevelLoad);

}void OnLevelLoad()

{

_collisionThread = new Thread(CollisionUpdate);

_collisionThread.Start();

}void InvokeEvent(MapEvent mapEvent)

{e;(this) { e = mapEvent; }(e != null) e();

}void PlayerDie()

{(--Settings.Default.HP >= 0)

{(RestartLevel);

_parentWindow.UpdateHP();

}

{.Default.HP = Global.HP;

_score = Settings.Default.Score;

_parentWindow.LoadLevel();

}

}void CollisionUpdate()

{= true;(IsWorking)

{

_parentWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new(() => {

{();();

}(LocalExeption e)

{.Write(e);

}

}));.Sleep(10);

}

}void AddScore()

{

++_score;

_parentWindow.Score.Text = _score.ToString();(_score == _maxScore)

{= false;.Default.Score = _score;= false;(var entity in _entities)

{.Stop();

}

_parentWindow.NextLevel();

}

}void CheckEntityCollision()

{count = _entities.Count;(int i=0; i < count; ++i)

{entity1 = _entities[i];(entity1.IsRemoved)

{

_entities.RemoveAt(i);= _entities.Count;;

}rect1 = entity1.GetRect();(int j = 0; j < count; ++j)

{entity2 = _entities[j];(entity2.IsRemoved) continue;(entity1 == entity2) continue;rect2 = entity2.GetRect();(rect1.IntersectsWith(rect2))

{c1 = new Collision(entity2.GetEntityType(), entity2.Velocity);c2 = new Collision(entity1.GetEntityType(), entity1.Velocity);.Collision(c1);.Collision(c2);= _entities.Count;

}

}(entity1)

{velocity = entity1.Velocity*-1;isCollide = false;(_wall.CheckCollision(entity1.GetRect()))

{.Move(velocity);= true;

_wall.IsActive = true;(Global.IS_SHOW_COLLISION)

{r = new Rectangle();.Fill = GetSolidBrush(Colors.Red, 0.1f);

_canvas.Children.Add(r);.SetZIndex(r, DEBUG_LAYER);(entity1.GetRect(), r);

_debugCollision.Add(r);

}

}(isCollide) entity1.Collision(new Collision(Entity.Type.Wall));

}

}

}void HideSprites(bool isHide)

{(var entity in _entities)

{.HideImage(isHide);

}

_wall.HideSprites(isHide);(!isHide) Global.ClearRectList(_debugPull,_canvas);

}void ClearCollisions()

{.ClearRectList(_debugCollision,_canvas);

}void Update()

{(Global.IS_DEBUG)

{count = 0;rectList = new List<Rect>();(var entity in _entities)

{type = entity.GetEntityType();(type == Entity.Type.Player)

{debugRect = GetDebugRectangle(count);.Fill = GetSolidBrush(Colors.Goldenrod,0.5f);.StrokeThickness = 1;.Stroke = Brushes.Chocolate;rect = entity.GetRect();(rect,debugRect);

++count;

} else if(type == Entity.Type.Enemy)

{debugRect = GetDebugRectangle(count);.Fill = GetSolidBrush(Colors.CadetBlue,0.5f);.StrokeThickness = 1;.Stroke = Brushes.DarkSlateGray;rect = entity.GetRect();(rect,debugRect);

++count;

}

}

}

}static SolidColorBrush GetSolidBrush(Color color, float opacity = 0.3f)

{br = new SolidColorBrush(color);.Opacity = opacity;br;

}List<Vector> CheckNext(Rect rect, Vector direction)

{_wall.CheckSides(rect, direction);

}Rect GetFlipping(Rect rect)

{_wall.GetFlipping(rect);

}static void RectToRectangle(Rect rect,Rectangle rectangle)

{.Width = rect.Width;.Height = rect.Height;.SetLeft(rectangle,rect.X);.SetTop(rectangle,rect.Y);

}GetDebugRectangle(int index)

{(index < _debugPull.Count)

{_debugPull[index];

}

{r = new Rectangle();.Width = Global.TILE;.Height = Global.TILE;

_canvas.Children.Add(r);.SetZIndex(r, DEBUG_LAYER);

_debugPull.Add(r);r;

}

}void Destroy()

{(!IsDestroyed)

{= false;(_collisionThread != null) _collisionThread.Join();(var entity in _entities)

{.Destroy();

}

_entities.Clear();

_canvas.Children.Clear();.ClearRectList(_debugCollision, _canvas);.ClearRectList(_debugPull, _canvas);

_data.Clear();

_wall.Destroy();

}

}int _maxScore = 0;int _score = 0;bool IsWorking { get; private set ; }bool IsDestroyed { get; set ; }bool IsDebug { get; set; }List<List<int>> _data = new List<List<int>>();readonly Canvas _canvas;const int mapWidth = 16;const int mapHeight = 16;readonly List<Entity> _entities = new List<Entity>();Thread _collisionThread;delegate void MapEvent();event MapEvent LevelLoad;event MapEvent RestartLevel;delegate void CollisionEvent(Collision c);readonly Wall _wall;readonly List<Rectangle> _debugPull;readonly List<Rectangle> _debugCollision;readonly MainWindow _parentWindow;const int DEBUG_LAYER = 5;

}

}.csSystem;System.Collections.Generic;System.ComponentModel.Design;System.IO;System.Linq;System.Text;System.Threading.Tasks;wpfman

{Logger

{static Logger _instance;static bool isExist = false;static string path = @"log.txt";static StreamWriter _sw;Logger()

{

}public void Write(string str)

{(isExist)

{(_instance)

{date = DateTime.Now.ToString() + " " + ": " + str;

_sw.WriteLine(date);

}

}

}static void Open()

{

_instance = new Logger();(File.Exists(path))

{.Delete(path);

}

_sw = File.CreateText(path);= true;

}static void Close()

{(isExist)

{= false;

_sw.Close();

_instance = null;

}

}static void Write(Exception e)

{(e.Message);

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading.Tasks;wpfman

{LocalExeption:Exception

{LocalExeption(string message):base(message)

{

}

}

}.csSystem.Collections.Generic;System.Windows;System.Windows.Controls;System.Windows.Shapes;wpfman

{static class Global

{const int TILE = 30;const int PLAYER_SPEED =3;const int ENEMY_SPEED = 1;const int LEVEL_COUNT = 3;const int HP = 2;const string LEVEL1= @"level1.txt";const string LEVEL2 = @"level2.txt";const string LEVEL3 = @"level3.txt";static bool IS_DEBUG = false;static bool IS_SHOW_COLLISION = false;static int Score = 0;static void ClearRectList(List<Rectangle> list, Canvas canvas)

{(var rect in list)

{.Children.Remove(rect);

}.Clear();

}

}

}.xaml.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Data;System.Windows.Documents;System.Windows.Input;System.Windows.Media;System.Windows.Media.Imaging;System.Windows.Navigation;System.Windows.Shapes;System.Windows.Threading;wpfman.Properties;wpfman

{partial class MainWindow : Window

{Map _map;int _currentLevel = 1;Dictionary<int, string> _levels;MainWindow()

{();.Open();();(_currentLevel != 1) Start.Header = "Продолжить";

}void InitLevels()

{

_levels = new Dictionary<int, string>();

_levels[1] = Global.LEVEL1;

_levels[2] = Global.LEVEL2;

_levels[3] = Global.LEVEL3;

}void OnLevelLoad()

{.Visibility=Visibility.Visible;.Write("Level Load");

}void NextLevel()

{(++_currentLevel <= Global.LEVEL_COUNT) LoadLevel();

{

//MainCanvas.Visibility = Visibility.Collapsed;.Show("Вы набрали " + Settings.Default.Score + " очков!");.Default.ScoresList.Add(DateTime.Now.ToString()+" "+Settings.Default.Score.ToString());.Default.Save();.Visibility = Visibility.Visible;.Text = "";(var rec in Settings.Default.ScoresList)

{.Text += rec + "\n";

}

_currentLevel = 1;.Default.IsCompleted = true;.Header = "Новая игра";

}

}void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

{(_map != null)_map.Destroy();.Close();

}void StartGameMenu_OnClick(object sender, RoutedEventArgs e)

{(Settings.Default.IsCompleted)Settings.Default.LastCompletedLevel = 1;

_currentLevel = Settings.Default.LastCompletedLevel;();_Restart.IsEnabled = !Menu_Restart.IsEnabled;

}void DebugMenu_OnClick(object sender, RoutedEventArgs e)

{(_map != null)

{.IS_DEBUG = !Global.IS_DEBUG;

_map.HideSprites(Global.IS_DEBUG);

}

}void CollisionMenu_OnClick(object sender, RoutedEventArgs e)

{(_map != null)

{.IS_SHOW_COLLISION = !Global.IS_SHOW_COLLISION;menu = sender as MenuItem;(menu != null && !menu.IsChecked) _map.ClearCollisions();

}

}void ExitMenu_OnClick(object sender, RoutedEventArgs e)

{.Default.Save();.Close();

}void AboutMenu_OnClick(object sender, RoutedEventArgs e)

{About()

{= Visibility.Visible

};

}void MenuRestart_OnClick(object sender, RoutedEventArgs e)

{();

}void MenuLevel1_OnClick(object sender, RoutedEventArgs e)

{

_currentLevel = 1;();

}void MenuLevel2_OnClick(object sender, RoutedEventArgs e)

_currentLevel = 2;();

}void MenuLevel3_OnClick(object sender, RoutedEventArgs e)

{

_currentLevel = 3;();

}void LoadLevel()

{.Visibility = Visibility.Collapsed;(_map != null)_map.Destroy();

_map = new Map(MainCanvas, this);

_map.Load(_levels[_currentLevel]);();.Text = Settings.Default.Score.ToString();

}void UpdateHP()

{_Text.Text = Settings.Default.HP.ToString();

}void MenuCancel_OnClick(object sender, RoutedEventArgs e)

{.Default.Reset();

_map.Destroy();

}

}

}.xaml

<Window x:Class="wpfman.MainWindow"="http://schemas.microsoft.com/winfx/2006/xaml/presentation":x="http://schemas.microsoft.com/winfx/2006/xaml"="Zombie Pacman!" Height="538" Width="470" Closing="Window_Closing" ResizeMode="NoResize" Icon="pacman.png">

<Window.Resources>

<Style x:Key="ScrollBarLineButtonStyle" TargetType="{x:Type RepeatButton}">

<Setter Property="Focusable" Value="False"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type RepeatButton}">

<Canvas Height="18">

<Polygon Fill="#333333" Points="3,10 15,10 9,3"></Polygon>

</Canvas>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

<Style x:Key="ScrollBarLineButtonBottomStyle" TargetType="{x:Type RepeatButton}">

<Setter Property="Focusable" Value="False"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type RepeatButton}">

<Canvas Height="18">

<Polygon Fill="#333333" Points="3,5 9,15 15,5"></Polygon>

</Canvas>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

<Style x:Key="ScrollBarPageButtonStyle" TargetType="{x:Type RepeatButton}">

<Setter Property="IsTabStop" Value="False"/>

<Setter Property="Focusable" Value="False"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type RepeatButton}">

<Border BorderBrush="Transparent"></Border>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

<Style x:Key="ScrollBarThumbStyle" TargetType="{x:Type Thumb}">

<Setter Property="IsTabStop" Value="False"/>

<Setter Property="Focusable" Value="False"/>

<Setter Property="Margin" Value="1,0,1,0" />

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type Thumb}">

<Rectangle Fill="Black" Margin="2"></Rectangle>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

<ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">

<Grid>

<Grid.RowDefinitions>

<RowDefinition MaxHeight="18"/>

<RowDefinition Height="*"/>

<RowDefinition MaxHeight="18"/>

</Grid.RowDefinitions>

<RepeatButton Grid.Row="0" Height="18"="{StaticResource ScrollBarLineButtonStyle}"="ScrollBar.LineUpCommand" >

</RepeatButton>

<Track Name="PART_Track" Grid.Row="1"="True">

<Track.DecreaseRepeatButton>

<RepeatButton Command="ScrollBar.PageUpCommand" Style="{StaticResource ScrollBarPageButtonStyle}">

</RepeatButton>

</Track.DecreaseRepeatButton>

<Track.Thumb>

<Thumb Style="{StaticResource ScrollBarThumbStyle}">

</Thumb>

</Track.Thumb>

<Track.IncreaseRepeatButton>

<RepeatButton Command="ScrollBar.PageDownCommand" Style="{StaticResource ScrollBarPageButtonStyle}">

</RepeatButton>

</Track.IncreaseRepeatButton>

</Track>

<RepeatButton Grid.Row="3" Height="18"="{StaticResource ScrollBarLineButtonBottomStyle}"="ScrollBar.LineDownCommand">

</RepeatButton>

</Grid>

</ControlTemplate>

<Style TargetType="{x:Type ScrollBar}">

<Setter Property="Template" Value="{StaticResource VerticalScrollBar}"/>

</Style>

</Window.Resources>

<Window.TaskbarItemInfo>

<TaskbarItemInfo/>

</Window.TaskbarItemInfo>

<StackPanel Background="#FF444444">

<Menu DockPanel.Dock="Top" >

<MenuItem Header="Игра">

<MenuItem x:Name="Start" Header="Новая игра" Click="StartGameMenu_OnClick">

<MenuItem.Icon>

<Image Source="play.png" />

</MenuItem.Icon>

</MenuItem>

<MenuItem x:Name="Menu_Restart" Header="Рестарт" IsEnabled="False" Click="MenuRestart_OnClick"/>

<MenuItem Header="Уровни" >

<MenuItem Header="1 уровень" Click="MenuLevel1_OnClick" />

<MenuItem Header="2 уровень" Click="MenuLevel2_OnClick"/>

<MenuItem Header="3 уровень" Click="MenuLevel3_OnClick"/>

</MenuItem>

<Separator />

<MenuItem Header="Выход" Click="ExitMenu_OnClick"/>

</MenuItem>

<MenuItem Header="Настройки">

<MenuItem Header="Режим отладки" >

<MenuItem x:Name="menu_sprite" Header="Отключить спрайты" Click="DebugMenu_OnClick" IsCheckable="True"/>

<MenuItem Header="Показывать столкновения" Click="CollisionMenu_OnClick" IsCheckable="True"/>

</MenuItem>

<MenuItem Header="Сбросить" IsEnabled="False" Click="MenuCancel_OnClick"/>

</MenuItem>

<MenuItem Header="Справка">

<MenuItem Header="Об игре" Click="AboutMenu_OnClick"/>

</MenuItem>

</Menu>

<Canvas x:Name="TopPanel" Height="24" Visibility="Collapsed">

<Image x:Name ="Heart" Source="heart.png" Stretch="Fill" Canvas.Left="10" Canvas.Top="3"/>

<TextBlock x:Name="HP_Text" Text="2" Canvas.Left="29" Canvas.Top="3" FontFamily="Batang" Height="20" VerticalAlignment="Center" TextAlignment="Center" FontSize="16" FontWeight="Bold" />

<TextBlock x:Name="ScoreText" Canvas.Top="3" Text="Score:" Canvas.Left="125" FontFamily="Batang" Height="20" VerticalAlignment="Center" TextAlignment="Center" FontSize="16" FontWeight="Bold"/>

<TextBlock x:Name="Score" Text="0" Canvas.Top="3" Canvas.Left="181" FontFamily="Batang" Height="20" VerticalAlignment="Center" TextAlignment="Center" FontSize="16" FontWeight="Bold" />

</Canvas>

<Grid>

<Canvas Name="MainCanvas" Width="449" Height="480" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,5,5,5" Visibility="Visible"/>

<ScrollViewer Name="RecordViewer" Margin="52,47,51,63" Background="#66000000" Visibility="Collapsed">

<TextBlock Name="RecordsText" Width="309" FontFamily="Courier New" FontSize="14" Foreground="#FFB9BABD"></TextBlock>

</ScrollViewer>

</Grid>

</StackPanel>

</Window>.xaml.csSystem;System.Collections.Generic;System.Linq;System.Text;System.Threading.Tasks;System.Windows;System.Windows.Controls;System.Windows.Data;System.Windows.Documents;System.Windows.Input;System.Windows.Media;System.Windows.Media.Imaging;System.Windows.Shapes;wpfman

{partial class About : Window

{About()

{();

}

}

}.xaml

<Window x:Class="wpfman.About" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation":x="http://schemas.microsoft.com/winfx/2006/xaml"="Об игре" Height="300" Width="300" >

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="0*"/>

<ColumnDefinition/>

<ColumnDefinition Width="0*"/>

</Grid.ColumnDefinitions>

<TextBlock Grid.ColumnSpan="2" Margin="0,73,0,176" TextAlignment="Center" FontWeight="Bold" FontSize="14" FontFamily="Courier New">

<Run>Автор: Логвина Юлия</Run>

</TextBlock>

<TextBlock Margin="0,98,0,140" Grid.ColumnSpan="2" TextAlignment="Center" FontWeight="Bold" FontSize="14" FontFamily="Courier New">

<Run>Рекомендуемая оценка: 5</Run>

</TextBlock>

</Grid>

</Window>

Похожие работы на - Разработка приложения, состоящего из прикладного окна

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!