Как создать змейку на c в visual studio
- To create a snake game in visual studio
- To create and manage an array of snake parts in the game
- To spawn and respawn food across the screen
- To detect hit test with the border and snakes own body
- Start and restart the game
- Keep score in the game
- Manage the project and follow good programming practice by using comments and indentation
- Using different OOP (object-oriented programming) classes to allocate the snake body and game controls
- Using the system PAINT event to draw and animate SNAKE parts across the screen
- Using Keyboard events and optimising the events to respond to up, down, left and right keys
New Updated Tutorial –
Written Tutorial –
Start a new project in Visual Studio. We will call this project SnakeGame. This project will be saved under the Documents folder / Visual Studio 2017 / Snake Game folder.
Click OK for the project to be created in Visual Studio.
Right click on the SnakeGame inside the Solutions Explorer, hover over Add, click on Class. We will need add a few classes for our game. Let’s set it up and then we can start adding the components for the game on Windows Form.
In the name box type Circle (Capital C) and Click add. Make sure the CLASS object is highlighted in the list not anything else.
The circle class has been added to the program. Visual Studio will also open the class file for us in the code editor. Let’s add the remaining classes for the game.
Add the following 2 classes now –
Now we have all our classes added to the project.
This is a simple practice of Object Oriented Programming. We have created 3 classes for this project that can be imported or removed from the game dynamically, this process allows us to compartmentalize the programming therefore we will not be required to code everything in one file.
Now lets go in to the Design view for the form and change some property settings
Now we have our main game screen set, time to start adding the components to the game screen. In this game we will need the following
1 Picture box – which will be used as the main game area.
3 Labels – for various information to be shown on about the game.
1 Timer Object – This timer will be used as the main game engine
Now change the following in the picture boxes properties. (When you select the picture box in the form it will allow you to change several options in the properties window. The Properties window is located right under the Solutions Explorer, if for some reason you cannot find it then right click on the picture box and select properties it will show up.)
Name | pbCanvas |
Back Color | Grey |
Location | 13, 13 |
Size | 541, 560 |
This is what the picture box looks like after the changes we made to its properties.
Lets go back to the ToolBox and get some labels for the game.
Now add 3 labels to the form
In the properties for label 1 change the following
Note to change the font in the properties window click on the three dotted … button in the properties window
In the properties for label 2 change the following
Font | Bold, Size 14 |
Text | 00 |
In the properties window for label 3 change the following
Font | Bold, Size 14 |
Back Color | Black |
Fore Color | Yellow |
Location | 215, 226 |
Text | End Text |
This is what the form looks like, now you can see that we have out Score text and a 00 text also we have the End Text in middle of the picture box.
Now let’s add a Timer to the form
In the Timer’s properties window make the following changes
Name | gameTimer |
You only need to change the of the Timer, the rest of the settings we need we can import them through the code later on. Nice Right!
We need several different types of Events to make this game work. We need a Key down, Key Up for the form and we also need a paint event for the picture box we added earlier.
Lets click on the form and make sure you haven’t clicked on anything else just the form and click on that little lightning bolt icon in the properties window to take you to the events window.
From the list lets find the Key Down and Key Up event
For key down type keyisdown and press and for key up type keyisup and press enter. They will take you to the code view but come back to the design view for one more event we need to add before going for the codes.
Click on the grey picture box on the form and in the events window find the Paint event and type updateGraphics
See the screen shot above.
Now with all the GUI components in place, lets start coding the game.
As you have followed thus far we have 3 different classes inserted in the game
Circle – This will be used to calculate the snakes head and body
Settings – This class will be used to check the height, width, speed and other default set ups for the game
Input – This class will be linked to the user input for example up, down, left or right
Lets start with Circle First
Привет Хабр! Меня зовут Евгений «Nage», и я начал заниматься программированием около года назад, в свободное от работы время. Просмотрев множество различных туториалов по программированию задаешься вопросом «а что же делать дальше?», ведь в основном все рассказывают про самые основы и дальше как правило не заходят. Вот после продолжительного времени за просмотром разных роликов про одно и тоже я решил что стоит двигаться дальше, и браться за первый проект. И так, сейчас мы разберем как можно написать игру «Змейка» в консоли со своими начальными знаниями.
Глава 1. Итак, с чего начнем?
Создадим файл для быстрой компиляции нашего кода, сохранил файл с расширением .bat со следующим содержимым:
"@echo off" отключает отображение команд в консоли. С помощью команды goto получаем бесконечный цикл. Задаем переменную name, а с модификатором /p в переменную записывается значение введенное пользователем в консоль. «echo.» просто оставляет пустую строчку в консоли. Далее вызываем компилятор и передаем ему файл нашего кода, который он скомпилирует.
Таким способом мы можем скомпилировать только один файл, поэтому мы будем писать все классы в одном документе (я не разобрался еще как компилировать несколько файлов в один .exe через консоль, да и это не тема нашей статьи, может кто нибудь расскажет в комментариях).
Для тех кто сразу хочет увидеть весь код.
Глава 2. Первые шаги
Подготовим поле нашей игры, начиная с точки входа в нашу программу. Задаем переменные X и Y, размер и буфер окна консоли, и скроем отображение курсора.
Для вывода на экран нашей «графики» создадим свой тип данных — точка. Он будет содержать координаты и символ, который будет выводится на экран. Также сделаем методы для вывода на экран точки и ее «стирания».
Это интересно!
Оператор => называется лямбда-оператор, он используется в качестве определения анонимных лямбда выражений, и в качестве тела, состоящего из одного выражения, синтаксический сахар, заменяющий оператор return. Приведенный выше метод переопределения оператора (про его назначение чуть ниже) можно переписать так:
Создадим класс стен, границы игрового поля. Напишем 2 метода на создание вертикальных и горизонтальных линий, и в конструкторе вызываем отрисовку всех 4х сторон заданным символом. Список всех точек в стенке нам пригодится позже.
Как вы могли заметить для инициализации типа данных Point используется форма Point p = (x, y, ch); как и у встроенных типов, это становится возможным при переопределении оператора implicit, в котором описывается как задаются переменные.
Вернемся к классу Game и объявим поле walls, а в методе Main инициализируем ее.
Все! Можно скомпилировать код и посмотреть, что наше поле построилось, и самая легкая часть позади.
Глава 3. А что сегодня на завтрак?
Добавим генерацию еды на нашем поле, для этого создадим класс FoodFactory, который и будет заниматься созданием еды внутри границ.
Добавляем инициализацию фабрики и создадим еду на поле
Глава 4. Время главного героя
Перейдем к созданию самой змеи, и для начала определим перечисление направления движения змейки.
Теперь можем создать класс змейки, где опишем как она будет ползать, поворачивать. Определим список точек змеи, наше перечисление, шаг на сколько будет перемещаться за ход, и ссылки на хвостовую и головную точки, и конструктор, в котором рисуем змею в заданных координатах и заданной длинны при старте игры.
В методе поворота, что бы избежать возможности повернуть сразу на 180 градусов, просто указываем, что в каждом направлении мы можем повернуть только в 2 стороны. А проблему поворота на 180 градусов двумя нажатиями — поставив «переключатель», отключаем возможность поворачивать после первого нажатия, и включаем после очередного хода.
Осталось вывести ее на экран.
Готово! теперь у нас есть все что нужно, поле огороженное стенами, рандомно появляющаяся еда, и змейка. Пришла пора заставить все это взаимодействовать друг с другом.
Глава 5. Л-логика
Заставим нашу змейку двигаться, напишем бесконечный цикл для считывания клавиш нажатых на клавиатуре, и передаем клавишу в метод поворота змеи
Теперь, перед тем как написать метод движения змейки, надо реализовать взаимодействие головы с едой, стенками и хвостом змеи. Для этого надо написать метод, позволяющий сравнивать две точки на совпадение координат. Переопределим оператор равенства и не равенства, их обязательно нужно переопределять в паре.
Теперь можно написать метод, который будет проверять совпадает ли интересующая нас точка с какой нибудь из массива стен.
И похожий метод проверяющий не совпадает ли точка с хвостом.
И методом проверки съела ли еду наша змейка, и сразу делаем ее длиннее.
теперь можно написать метод движения, со всеми нужными проверками.
Вот и все! Наша змейка в консоли закончена и можно поиграть.
Заключение
Мы посмотрели как можно реализовать первую простенькую игру с небольшим использованием ООП, научились перегружать операторы, посмотрели на кортежи и лямбда оператор, надеюсь это было полезно!
Это была пилотная статья, и если вам понравилось, я напишу про реализацию змейки на Unity.
Всем удачи!
Пара слов о слушателе: менеджер IT-проекта, знаком с процедурным программированием, web-разработкой, SQL. Более тесное знакомство с ООП понадобилось для глубокого внедрения в бизнес-процессы. Итак, слово нашему выпускнику.
«Есть такая программистская шутка: язык программирования легко выучить — в отличие от иностранных языков, в нём совсем немного слов. Действительно, выучить названия команд, функций, библиотек, типы данных и даже синтаксис не так сложно, тем более, что многие из них схожи в разных языках. Однако недаром высказывание названо шуткой — для того, чтобы работать с конкретным языком программирования, нужно знать принципы, основы парадигмы, стандарты языка. Объектно-ориентированное программирование, как и любая парадигма программирования, имеет набор принципов и правил, которые справедливы для всех языков и пригодятся в любом случае.
В начале программы я погрузился сразу в два современных инструмента, которые используют разработчики.
-
Visual Studio — интегрированную среду разработки для ряда языков программирования. Именно в Visual Studio можно познакомиться с редактором исходного кода, дизайнером классов, отладчиком и консолью.
Изначально преподаватель делает акцент на том, что будет разрабатываться продукт. Выбор на змейку пал неслучайно — всем известна логика игры, её особенности и требования. А в разработке важно уже на раннем этапе иметь целостное представление о будущем проекте. Такое видение помогает разбить его на значимые этапы и избежать многих упущений.
Первые два урока просты и понятны любому человеку, даже совершенно не знакомому с программированием. Традиционно работа начинается со счастливого ‘Hello, world!’
Я ещё раз повторил для себя, что такое функция, как она работает, как создаются переменные. Для написания кода используется процедурный подход — функции последовательно применяются, принимая на входе заданные параметры. Сразу становятся очевидными два недостатка создания всего кода внутри главной функции main: разрастание кода и объявление переменных прямо внутри этой функции.
Действительно, после первых двух занятий возникает чувство восторга от понимания довольно сложных вещей. Проверил на себе, поэтому подписываюсь под комментариями слушателей.
На третьей лекции я познакомился с понятием класса, типа данных. Класс — одно из основных понятий ООП, поэтому его изучению уделяется пристальное внимание. Переменные начинают создаваться как экземпляры класса, то есть объекты (отсюда и название ООП).
Если слушатель начинающий, то он учится понимать язык кода и выражение Point p1 = new Point(); начинает восприниматься как «создаётся объект точка p1 как экземпляр класса Point, принимающий на входе координаты».
На этом же занятии слушатель учится думать, как компьютер. Это происходит с помощью использования точки останова и прохода по коду через отладчик: шаг за шагом можно видеть создание объектов класса, инициализацию переменных, работу функции (вызов метода Draw).
На четвёртом занятии создаётся конструктор класса Point — явно написанный конструктор со специальным синтаксисом, который ничего не возвращает.
Я заметил, как сокращается объём кода основной программы после создания конструктора. Конструктор принимает на вход координаты точки и символ её обозначения, но деталей реализации пользователь не видит — они скрыты внутри конструктора. Так я столкнулся с первым из трёх принципов ООП — инкапсуляцией. Инкапсуляция — это свойство системы, позволяющее объединять данные и методы, работающие с ними, в классе и скрыть все детали реализации от пользователя.
Работая с циклом в отладчике, слушатель ещё более наглядно понимает структуру и последовательность работы программы.
Для целей реализации игры мы создали горизонтальные и вертикальные линии препятствий для змейки, которые представляют собой не что иное как список точек. Я старался успевать следовать за преподавателем, разбирая его код, создавая свой и тренируясь уже в своей программе.
Преподаватель отмечает, что и точка, и линии, а в дальнейшем и сама подвижная змейка по сути являются фигурами, поэтому должно существовать какое-то решение для оптимизации кода, которое позволит не копировать код, а переиспользовать его. Так я познакомился со вторым принципом ООП — наследованием. Наследование — это свойство системы, позволяющее описывать новый класс на основе уже существующего с частично или полностью замещающейся функциональностью. Таким образом, каждая линия, змейка и точка становятся частным случаем (наследуются) от класса Фигура: class HorizontalLine: Figure.
Наследный класс обязательно содержит признаки родительского класса, но может иметь и свои собственные. Пример наследования дополнительно разбирается на хрестоматийном и понятном примере класса Работник, унаследованном от класса Человек, имеющим от родительского класса рост и возраст и свой признак — зарплату. Кстати, для целей самостоятельной тренировки понимания наследования в ООП лучше всего работать именно с проектированием карточки студента или сотрудника — это я понял сразу, сперва самостоятельно закрепляя свои знания, а потом уже работая с проектом.
И вот змейка должна научиться двигаться в поле и управляться стрелками с клавиатуры. Задача кажется сложной, но я помнил, что речь идёт всё ещё о консоли и поэтому реализация передвижения змейки должна быть максимально простой. Я уже знал, что змейка должна двигать в четырёх направлениях, что-то есть, расти или уменьшаться. И вот тут наступает пора абстрагирования — ситуации, при которой код пишется на основе выбранных значимых характеристик объекта, а незначительные — исключаются. Выбираем значимые признаки: змейка — это фигура из точек на карте, у неё есть стартовая позиция, координаты и она движется в одном из четырёх направлений. Класс Snake серьёзно изменяется и растёт.
Вообще, если продолжить говорить об абстрагировании, в ООП широко используется понятие абстрактного класса. Создаётся шаблонный класс, который реализует только известную и нужную разработчику на данный момент функциональность. Классы, производные от абстрактного, всю функциональность в дальнейшем смогут дополнить.
Но вернёмся к проекту. Появляется класс Direction (направление), в котором используется ещё один тип данных enum — перечисление, состоящее из набора именованных констант. В нашем случае это константы-направления: right, left, up, down. У класса Point появляется метод Move.
Таким образом, передвижение змейки реализовано как сдвиг позиции с перетиранием хвоста пробелом. Змейка управляется клавишами и управление реализовано следующим образом.
Вновь я столкнулся с инкапсуляцией — управление змейкой уходит в класс Snake.
На следующем этапе змейка начинает есть и добыча создаётся в бесконечном цикле с помощью функции FoodCreator, проверяется совпадение координат головы змейки и точки, представляющей собой еду.
Создавая препятствия для кушающей в бесконечном цикле змейки и работая над классом Wall, я узнал о третьей парадигме ООП — полиморфизме, способности функции обрабатывать данные разных типов. В ООП полиморфизм заключается в том, что объект использует методы производного класса, которого нет на момент создания базового. Во время выполнения объекты производного класса могут рассматриваться как объекты базового класса в таких местах, как параметры метода, коллекции или массивы. Когда это происходит, объявленный тип перестает соответствовать самому типу во время выполнения. Сразу оговорюсь, что полиморфизм понимается не сразу, мне понадобилось послушать лекцию ещё раз и обратиться к замечательному учебнику Шилдта, который давно лежал под рукой и ждал своего часа.
На последнем занятии змейка стала вполне самостоятельной, а я учился обрабатывать столкновения с препятствиями и собственным хвостом змейки. Код в лекции уже не создаётся, а берётся из репозитория и разбирается. Я не пошёл на поводу у соблазна скопировать чужой код, а некоторое время после прослушивания курса создавал свой, раз за разом обращаясь к лекциям. Вам я советую поступать точно так же — потому что для работы и понимания нужны знания. Надеюсь, я дал достаточно тизеров, чтобы вам захотелось зайти на GitHub и разобраться в реализации простой игры, основной код которой составляет всего 52 строки, а это значит, что все принципы ООП были успешно применены.
Подводя итоги, преподаватель ещё раз возвращается к главным парадигмам ООП и обращает внимание на модификаторы доступа public и private и рассказывает о ключевом слове virtual, благодаря которому метод может быть переопределён в наследном классе. Private — это закрытые данные и код внутри объекта, public — открытые. Закрытые данные и код доступны только из другой части этого же объекта, то есть извне к ним обратиться нельзя. Открытые данные и код доступны из любой части программы и нередко служат интерфейсом к закрытым частям объекта.
Если говорить о курсе в целом, то он мне помог — изменились и качество моей работы, и уровень общения с разработчиками. Советую попробовать всем, кому хоть немного интересно программирование, как минимум, это развивает мозг и учит думать системно. Я точно вернусь послушать другие курсы и пообщаться с профессионалами. Ну, а отважным новичкам желаю удачи!»
Вы заметили, насколько популярным стал видеоформат в контенте, рекламе, управлении? Общеизвестно, что видео задействует сразу и зрение, и слух, а значит, воспринимается лучше. К тому же, видеокурс можно остановить, перемотать, прослушать ещё несколько раз, задать вопросы в комментариях. Плюс ко всему, в GeekBrains преподают практики, для которых программирование — ежедневная работа и поэтому они всегда в курсе самых последних тенденций своей отрасли. Конечно, просмотр курса со стаканом чая перед монитором принесёт мало пользы, поэтому в заключение хотим дать несколько советов слушателям.
-
Слушайте курс с карандашом или ручкой — записывайте моменты, которые стоит переслушать или дополнительно посмотреть в Интернете или книге.
Учиться легче, когда вы имеете дело с играми. Создав несложную игру на любом языке программирования, вы получите отличный опыт, который пригодится вам в будущем, если вы собираетесь стать программистом.
Для создания вам необходимы базовые знания языка. Однако, даже если вы имеете мало опыта программирования на C++, я постараюсь подробно описать основные моменты разработки.
Для работы с C++ вам нужно скачать Visual Studio - это среда , разработанная компанией Microsoft.
После скачивания вы создаете пустой проект и начинаете писать программный код , в котором вы заложите отрисовку , логику, управление нашей Змейки.
Сразу скажу, что на создание даже такой простой игры как Змейка у малоопытного программиста может уйти немало времени , но по завершении создания вы сможете неплохо продвинуться в этой сфере и , возможно , полюбить программирование . Сам процесс создания я буду излагать в нескольких статьях на моем канале.
ЧАСТЬ 1:
Окей, для начала подключим к нашей программе основную библиотеку для ввода и вывода ( Вывод осуществляется, как правило, с помощью перегруженного оператора сдвига влево (<<), а ввод – с помощью оператора сдвига вправо (>>)) Это основная библиотека, только благодаря в дальнейшем мы сможем отрисовать карту для игры, саму змейку и фрукты, появляющиеся на карте.
Дальше мы создаем основные функции. Отдельные функции будут отвечать за логику, отрисовку и управление игры. Название каждой функции будет говорить за ее назначение в программе.
Так, функция Setup (англ.установить) будет содержать в себе переменные, благодаря которым мы зададим змейке начальное положение и настроим случайное появление фрукта на карте.
Функция Draw (англ.рисовать) будет отвечать за отрисовку карты, змейки и фрукта в консоли с ее постоянным обновлением(анимацией).
Функция Input (англ.ввод) будет отвечать за управление нашей змейкой, которое заключается в назначении клавиш, отвечающих за перемещение.
Функция Logic (англ.логика) будет содержать переменные, описывающие логику игры (конец игры, если змейка врежется в стенку, увеличение длины тела при поедании фрукта и т.п.)
Ну и основная функция main будет включать в себя все функции для отображения игры на консоли до тех пор пока игра не завершена.
Как вы уже заметили мы ввели логическую переменную GameOver (конец игры), пока она принимает значения False(ложь) игра будет продолжаться, поэтому все функции будут выполняться.
Теперь нам надо заполнить каждую функцию, чтобы они имели смысл. Но перед тем, как заполнять одну из функций введем глобальные переменные:
const int width (ширина ) и (height) можно поставить любые значения, эти константы зададут размер игрового поля для змейки. При тесте игры мы сможем в любой момент изменить эти параметры не меняя логику и целостность игры.
Параметры x,y будут отвечать за положение змейки на горизонтали и вертикали ( т.к. змейка в двухмерном пространстве(на плоскости)) , аналогично параметры fruitX и fruitY будут отвечать за положение фрукта.
Дальше идет перечисление enum (англ. enumeration) / с помощью перечислений мы присвоим параметрам Stop, LEFT,RIGHT,UP,DOWN целые значения ( первому параметру Stop присвоится 0, второму LEFT - 1, и т.д. DOWN - 4)
Переходим в функцию Setup.
Изначально игра не окончена, поэтому GameOver = false; , иначе при запуске консоли программа завершит процесс выполнения. eDirection или dir (направление при запуске игры будет 0, то есть змейка будет стоять на месте, 0 в перечислениях принимал параметр Stop. x,y отвечают за положение змейки, при делении высоты и ширины пополам мы получим, что змейка будет находиться в центре игрового поля при запуске. Положение фрукта же случайно , поэтому приплетаем функцию rand() с остатком от деления на высоту вертикальной составляющей и с остатком от деления на ширину горизонтальной составляющей, так фрукт будет появляться в случайном месте на карте. Score( счетчик очков ) изначально равен нулю. Тут все ясно.
Сразу перейдем к функции Draw для отрисовки карты и объектов на консоли. Пожалуй, это самая сложная и интересная функция. Для того, чтобы картинка стала обновляться и создалась анимация движения нам необходимо прописать команду system("cls") ; Дальше заполняем первую верхнюю строчку(верхний край) нашего игрового поля. Это можно реализовать с помощью цикла for. Верхний край заполнится дефисами и будет символизировать стенку шириной width. По окончании цикла переходим на вторую строку консоли с помощью coutДальше нам необходимо отрисовать остальную часть поля, использую уже вложенный цикл ( for вложен в for ) вложенный цикл отрисует змейку( решетка ), фрукт ( F ), и левую и правую стенку ( | ). Суть в том, что в каждой строке левая стенка находится на первой позиции(нулевой элемент строки), а правая на позиции ширина - 1(элемент равный ширине строки).
На позиции x,y находится змейка , рисуем любой элемент, я использовал решетку, на позиции fruitX,fruitY рисуем фрукт , я использовал букву F . Строки №40-45 отрисуют нижнюю границу поля, аналогично верхней, только ниже на расстоянии height (высоты).
На этом этапе, если вы все правильно усвоили и безошибочно написали вы увидите следующую картинку в консоли:
Привет всем. Написал змейку, принимаю критику по коду и оптимизации:
Змейка
Помогите пожалуйста, как сделать так чтобы змейка съедала фрукт, какбы написанно, но что-то идет не.
Консольная змейка
Я уже устал и отчаялся. Никак не могу понять как нарисовать горизонтальную линию. У меня есть.
Змейка в консоли
using System; using System.Collections.Generic; using System.Linq; using System.Text; using.
Консольная змейка
Сижу дома на летних каникулах, развлекаюсь.. З,Ы, особо забавный 3-й режим игры с клоном)) он.
В общем неплохо, но мерцание изображения выглядит не очень. Советую делать отрисовку на PictureBox'е и использовать двойную буферизацию. А так, то играбельно.
Двойная буферизация — в информатике метод подготовки данных, обеспечивающий возможность отдачи готового результата, без прерывания процесса подготовки следующего результата.
А если своими словами, то это когда ты рисуешь всю графику на одном изображении(второй буфер), а когда отрисовка окончена, то копируешь содержимое первого изображения во второе(основной буфер). На практике это можно сделать так:
Скажите что именно не понятно, может помогу.
ЗЫ. Про двойную буферизацию хорошо написано в книге "Занимательное программирование" Мозговой М.
А если всю графику рисовать непосредственно на viewBox.Image, или(что еще хуже) на форме, то при отрисовке будут появляться артефакты в виде мерцания изображения. Теперь ясно для чего копировать старое изображение? Иначе же оно никак не выводиться на экране, и мы будем смотреть на белый фон.
Alex Sabaka,
этот метод тоже делегируется какому то событию? если да то какому?:
Добавлено через 1 минуту
viewBox - это компонент PictureBox?
Добавлено через 1 минуту
и за чем ты перегружаешь его (метод)?
1. Этот метод вызывается при первом показе формы, это все можно было сделать и в конструкторы формы, но у меня уже было так, а менять лень.
2. Да, viewBox - это PictureBox
3. Перезагружаю в коде потому что лень брать мышку и лезть в свойства формы.
Второй буфер это "Bitmap view;", а первый - "viewBox.Image". "Graphics graph" - это для работы с графикой, то есть для отображения примитивов на view.
Не вывод, а копирование содержимого второго буфера в основной(первый), и отображается на экране первый буфер, а не второй.
Решение
Alex Sabaka, Я понял так(конкретно твой пример), при запуске формы создается второй буфер, при срабатывании таймера второй буфер очищается, затем на нем же рисуется прямоугольник, затем буфер копируется в певый и выволится на экран. Так я понял? В чем выигрыш, то? замена картинки viewBox.Image будет происходить без мерцания?
Добавлено через 15 минут
Alex Sabaka, Ну действительно не мерцает))), спасибо, вот обновленный код:
Добавлено через 4 минуты
Получается, вся фишка в том что на экран выводтся уже готовые картинки, а у меня было так, что какждый сегмент змейки выводился поочердно и из - за этого были мерцания
1) в свойствах формы надо поставить DoubleBuffered = true;
2) (snake[0].X < 0 || snake[0].X >240 || snake[0].Y < 0 || snake[0].Y >240) у меня работает неправильно, хоть и форсированно задал размер клиентской области. в общем надо параметризовать ширину и высоту кратными ширине и высоте "сегментов" змеи и при загрузке уже выставлять размер формы, или же, как это сделано в других змейках - предложить выбрать размер (мал, сред, бол) и отрисовать границы поля на форме отдельно
3) поля классов предпочтительнее (обязательно в 99% случаев) делать закрытыми (private)
4) ну и самое главное - один раз создавать Graphics - противозаконно. лучше все делать через метод OnPaint, а по таймеру делать Invalidate
Читайте также: