Опубликован: 02.12.2011 | Уровень: специалист | Доступ: платный
Лекция 14:

Создание программы "Лабиринт"

< Лекция 13 || Лекция 14: 123

Информация обо всех стенах лабиринта будет храниться в массиве plan, каждый элемент которого описывает расположение и цвет одной из стен лабиринта.

В программе также будут использоваться несколько глобальных переменных и констант ( пример 13.9 и пример 13.10).

Bitmap bmpBrick;
Bitmap bmpEarth;
double AngleX = 0;
double AngleY = 0;
double AngleZ = 0;
// шаг перемещения наблюдателя в лабиринте
const double Step = 0.2; 
// высота стен лабиринта
const double hdl = 5;
const double AngleDl = 5;
// координаты положения наблюдателя
PointFloat Pos;
Листинг 13.9. Объявление переменных и констант программы Лабиринт на C#
var 
  // переменные для хранения данных о тектурах
  texBrick, texEarth: TGLTexture;
  // направление движения наблюдателя (угол его поворота),
  // изменяется с помощью клавиш со стрелками влево и вправо
  AngleY: integer;
  // координаты положения наблюдателя
  Pos: TPointFloat;
  // угол поворота сферы
  RY: integer;
Const
  AngleDl=5;    //угол разворота при нажатии на клавишу
  Step = 0.2;   // шаг перемещения наблюдателя в лабиринте
  hdl=5;        // высота стен лабиринта
Листинг 13.10. Объявление переменных и констант программы Лабиринт на Object Pascal

Переменная Pos будет использоваться для хранения текущих координат положения наблюдателя в лабиринте, константа Step будет определять изменение положения наблюдателя в направлении перемещения ("длина шага" наблюдателя в лабиринте).

Изображение лабиринта будет формироваться на основе данных массивов points и coners ( пример 13.11 и пример 13.12).

private void glControl1_Paint(object sender, PaintEventArgs e)
{
  // очистка буферов цвета и глубины
  GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  // поворот изображения
  GL.LoadIdentity();
  GL.Rotate(AngleY, 0.0, 1.0, 0.0);
  GL.Translate(Pos.X, 0, Pos.Y);
  // стены лабиринта
  for (int i = 0; i < plan.Length; ++i)
  {
    // длина стены
    double wdl = Math.Sqrt(Math.Pow(coners[plan[i].L].X - coners[plan[i].R].X, 2)
      + Math.Pow(coners[plan[i].L].Y - coners[plan[i].R].Y, 2)) / 4;
    GL.Color4(plan[i].C);
    GL.Begin(BeginMode.Quads);
    GL.TexCoord2(0, 0);         GL.Vertex3(coners[plan[i].L].X, -hdl, 
      coners[plan[i].L].Y);
    GL.TexCoord2(0, hdl / 2);   GL.Vertex3(coners[plan[i].L].X,  hdl, 
      coners[plan[i].L].Y);
    GL.TexCoord2(wdl, hdl / 2); GL.Vertex3(coners[plan[i].R].X,  hdl, 
      coners[plan[i].R].Y);
    GL.TexCoord2(wdl, 0);       GL.Vertex3(coners[plan[i].R].X, -hdl, 
      coners[plan[i].R].Y);
    GL.End();
  }
  
  GL.Flush();
  GL.Finish();
  glControl1.SwapBuffers();
}
Листинг 13.11. Обработчик события Paint компонента GLControl программы Лабиринт на C#
procedure TForm1.FormPaint(Sender: TObject);
var i: integer;
begin
  // очистка буфера цвета
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);        glLoadIdentity;
  // перемещение наблюдателя
  glRotatef(AngleY, 0.0, 1.0, 0.0);
  glTranslatef(Pos.X, 0, Pos.Y);
  // стены лабиринта
  for i:=0 to High(plan) do begin
    glBegin(GL_QUADS);
      glColor(GetRValue(plan[i].c),GetGValue(plan[i].c),
     GetBValue(plan[i].c));
      glVertex3f(coner[plan[i].l].x, -hdl, coner[plan[i].l].y);
      glVertex3f(coner[plan[i].l].x, hdl, coner[plan[i].l].y);
      glVertex3f(coner[plan[i].r].x, hdl, coner[plan[i].r].y);
      glVertex3f(coner[plan[i].r].x, -hdl, coner[plan[i].r].y);
    glEnd;
  end;
 
  glFlush;
  glFinish;
  SwapBuffers(DC);
end;
Листинг 13.12. Обработчик события OnPaint формы программы Лабиринт на Object Pascal

Для возможности перемещения наблюдателя в лабиринте в программе будут использоваться клавиши со стрелками. Клавиши со стрелками влево и вправо будут использоваться для поворота наблюдателя в соответствующем направлении, клавиши со стрелками вперед и назад – для перемещения наблюдателя вперед и назад ( пример 13.13 и пример 13.14).

private void glControl1_KeyDown(object sender, KeyEventArgs e)
{
  switch(e.KeyCode)
  {
    case Keys.Left: AngleY += -AngleDl; break;
    case Keys.Right: AngleY -= -AngleDl; break;
    case Keys.Up:
      Pos.X = Pos.X - Step * Math.Sin(AngleY * Math.PI / 180);
      Pos.Y = Pos.Y + Step * Math.Cos(AngleY * Math.PI / 180);
    break;
    case Keys.Down:
      Pos.X = Pos.X + Step * Math.Sin(AngleY * Math.PI / 180);
      Pos.Y = Pos.Y - Step * Math.Cos(AngleY * Math.PI / 180);
    break;
  }
  if (AngleY>=360) AngleY -= 360;
  glControl1.Invalidate(); 
}
Листинг 13.13. Обработчик события KeyDown компонента GLControl программы Лабиринт
procedure TfrmGL.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
case Key of
  VK_LEFT:   inc(AngleY, -AngleDl);
  VK_RIGHT:  dec(AngleY, -AngleDl);
  VK_UP: begin
           PosX:=PosX - Step*Sin(AngleY*pi/180);
           PosZ:=PosZ + Step*Cos(AngleY*pi/180);
         end;
  VK_DOWN: begin
           PosX:=PosX + Step*Sin(AngleY*pi/180);
           PosZ:=PosZ - Step*Cos(AngleY*pi/180);
          end;
 end;
 if AngleY>=360 then dec (AngleY, 360);
 InvalidateRect(Handle, nil, False);
end;
Листинг 13.14. Обработчик события FormKeyDown формы программы Лабиринт на Object Pascal

В результате будет получено приложение, которое рисует замкнутое помещение с одной дополнительной стеной, все стены имеют различный цвет. Программа позволяет наблюдателю перемещаться в этом помещении ( рис. 13.1). В полученном приложении не контролируются границы стен.

Изображение лабиринта (вариант 1)

Рис. 13.1. Изображение лабиринта (вариант 1)
< Лекция 13 || Лекция 14: 123
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?

 

Константин Леденев
Константин Леденев
Россия
Олег Равков
Олег Равков
Россия