Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 7: Программирование на Visual C# искусственного интеллекта. Издание 2
Шрифт:
Добавляем в проект (из отмеченной выше статьи или из Интернета) файл изображения батона хлеба bread.jpg по стандартной схеме, а именно: в меню Project выбираем Add Existing Item, в этой панели в окне “Files of type” выбираем “All Files”, в центральном окне находим и выделяем имя файла и щёлкаем кнопку Add (или дважды щёлкаем по имени файла). В панели Solution Explorer мы увидим этот файл.
Теперь этот же файл bread.jpg встраиваем в проект в виде ресурса по разработанной выше схеме, а именно: в панели Solution Explorer выделяем появившееся там имя файла, а в панели Properties (для данного файла) в свойстве Build Action (Действие при построении)
Объявляем и инициализируем объект breadImage (класса Image) для загрузки в него изображения хлеба и две текущие координаты bx и by верхнего левого угла прямоугольника, описанного вокруг хлеба, в системе координат с началом в верхнем левом углу экрана. А приведённый выше код в теле метода Form1_Paint заменяем на тот, который дан на следующем листинге.
Листинг 4.9. Метод для рисования изображения.
//We declare the object of class System.Drawing.Image
//for the subject:
Image breadImage; // = null by default.
//Current abscissa of a subject:
int bx = 0;
//Current ordinate of a subject:
int by = 0;
private void Form1_Paint(object sender, PaintEventArgs e)
{
//We load into the object of class System.Drawing.Image
//the image file of the set format, added to the project,
//by means of the ResourceStream:
cheeseImage =
new Bitmap(myAssembly.GetManifestResourceStream(
myName_of_project + "." + "cheese.JPG"));
breadImage =
new Bitmap(myAssembly.GetManifestResourceStream(
myName_of_project + "." + "bread.JPG"));
//We draw the images on the Form1:
e.Graphics.DrawImage(cheeseImage, cx, cy);
e.Graphics.DrawImage(breadImage, bx, by);
//We turn on the timer:
timer1.Enabled = true;
}
В режиме выполнения (Build, Build Selection; Debug, Start Without Debugging) мы видим, что на форме Form1 к перемещающемуся изображению сыра cheese.jpg добавилось изображение хлеба bread.jpg (в верхнем левом углу экрана), рис. 4.7.
Рис. 4.7. Подвижный сыр и неподвижный хлеб. Рис. 4.8. Сыр закрывает хлеб.
Однако изображения и сыра, и хлеба мерцают, что необходимо исправить методом двойной буферизации (в следующем параграфе).
4.6. Методика устранения мерцания изображения при помощи двойной буферизации
Идея устранения мерцания изображения методом двойной буферизации заключается в том, что сначала изображение проектируют не на экране, как до применения двойной буферизации, а в специальном буфере в памяти компьютера, а когда изображение полностью спроектировано в буфере памяти, оно копируется на экран . Так как процесс копирования готового изображения из буфера на экран происходит быстрее, чем процесс прорисовки изображения сразу на экране без использования промежуточного
Чтобы устранить мерцание изображения при помощи двойной буферизации, приведённый выше код в теле метода Form1_Paint заменяем на тот, который дан на следующем листинге (с подробными комментариями).
Листинг 4.10. Метод для рисования изображения.
//Buffer in the view of object of class Bitmap:
Bitmap backBuffer = null;
private void Form1_Paint(object sender, PaintEventArgs e)
{
//We load into object of class System.Drawing.Image
//the image file of the set format, added to the project,
//by means of ResourceStream:
cheeseImage =
new Bitmap(myAssembly.GetManifestResourceStream(
myName_of_project + "." + "cheese.JPG"));
breadImage =
new Bitmap(myAssembly.GetManifestResourceStream(
myName_of_project + "." + "bread.JPG"));
//If it is necessary, we create the new buffer:
if (backBuffer == null)
{
backBuffer = new Bitmap(this.ClientSize.Width,
this.ClientSize.Height);
}
//We create the object of class Graphics from the buffer:
using (Graphics g = Graphics.FromImage(backBuffer))
{
//We clear the form:
g.Clear(Color.White);
//We draw the image in the backBuffer buffer:
g.DrawImage(breadImage, bx, by);
g.DrawImage(cheeseImage, cx, cy);
}
//We draw the image on the Form1:
e.Graphics.DrawImage(backBuffer, 0, 0);
//We turn on the timer:
timer1.Enabled = true;
} //End of the method Form1_Paint.
Если мы сейчас запустим программу на выполнение, то увидим, что мерцание уменьшилось, но не исчезло совсем. Это объясняется тем, что при выполнении метода Form1_Paint операционная система Windows сначала заполняет экран цветом фона (background color), в нашем примере белым фоном (white), и только после этого поверх фона прорисовывает встроенные в программу изображения. Поэтому необходимо сделать так, чтобы операционная система Windows не изменяла фон. Для этого воспользуемся неоднократно применяемым и в наших предыдущих книгах, и в данной книге шаблоном метода OnPaintBackground, в тело которого мы ничего не будем записывать, как показано на следующем листинге.
Листинг 4.11. Метод OnPaintBackground.
protected override void OnPaintBackground(
System.Windows.Forms.PaintEventArgs e)
{
//We prohibit to redraw a background.
}
Этот метод OnPaintBackground следует записать непосредственно за методом Form1_Paint, естественно, в теле класса Form1.
Теперь в режиме выполнения (Build, Build Selection; Debug, Start Without Debugging) подвижный сыр и неподвижный хлеб уже не мерцают, и мы решили данную задачу.
Однако при перемещении сыр может перекрыть батон хлеба (рис. 4.8), хотя по правилам игры пользователь должен управлять перемещением хлеба, не давая сыру упасть вниз, а маленький кусочек сыра при столкновении должен отскочить от большого батона хлеба в противоположном направлении. Поэтому методично и последовательно перейдём к решению этих задач.
4.7. Методика управления направлением перемещения объекта при помощи элементов управления и мыши