Шаг 78.
Библиотека OWL.
Игра "Поймай меня"

    На этом шаге мы рассмотрим небольшую игру.

    Студентка 4 курса (2009-10 уч.год) Бусыгина Ксения реализовала небольшую игру "Поймай меня".

    Пользователь перемещает курсор мыши близко к кнопке, а та "убегает". Смысл " убегания" объекта, с точки зрения программы, состоит в реализации удаления объекта с формы и создания этого объекта в другом месте формы, определяемом случайным образом.

    Рассмотрим реализацию этого приложения средствами библиотеки OWL.

#include <owl\framewin.h>
#include <owl\applicat.h>
#include <stdlib.h>
#include <time.h>
#include <owl\edit.h>
#include <owl\button.h>
#include "proj.rc"

// Класс приложения.
class TCatchApp : public TApplication
{
  public:
	TCatchApp() : TApplication() {}
	void InitMainWindow();
};

// Класс главного окна.
class TCatchWindow : public TFrameWindow
{
  protected:
	 int maxx,maxy,x,y, xpos,ypos,
	 game_over;	// Флаг управления игрой.
	 TButton *b;
	 TEdit  *edit;
  public:
	TCatchWindow(TWindow *parent, const char far *title);
  protected:
	void SetupWindow();
	void PushBut2();
	void EvMouseMove(UINT,TPoint &point);
	DECLARE_RESPONSE_TABLE(TCatchWindow);
};

DEFINE_RESPONSE_TABLE1(TCatchWindow,TFrameWindow)
	EV_COMMAND(CM_PUSHB2,PushBut2),
	EV_WM_MOUSEMOVE,
END_RESPONSE_TABLE;
TCatchWindow::TCatchWindow(TWindow *parent, const char far *title) :
	 TFrameWindow (parent, title)
{
  Attr.X = 100;
  Attr.Y = 100;
  Attr.W = 600;
  Attr.H = 600;
  randomize();
  maxx = 450;
  maxy = 450;
  xpos = random(maxx);
  ypos = random(maxy);
  game_over = TRUE;
  b=new TButton(this,CM_PUSHB1,"Я ТУТ!",xpos,ypos,50,20);
  new TButton(this,CM_PUSHB2,"Начать новую игру",410,530,170,30);
}
void TCatchWindow::SetupWindow ()
{
  TFrameWindow::SetupWindow();
}
void  TCatchWindow::PushBut2()
{
 if (game_over)
  {
	 game_over  =  FALSE;
	 SetWindowText("Поймай  кнопку!");
  }
  else MessageBox("Ошибка! Игра уже была начата!!!", "Ошибка", MB_OK);
}
void TCatchWindow::EvMouseMove(UINT,TPoint &point)
{
x=point.x;
y=point.y;
if (!game_over)
  {
	SetActiveWindow();
	if ((x>xpos-30 && x<xpos+50 && y>ypos-10) || 
             (y>ypos-20 && y<ypos+50 && x>xpos-10) || 
             (x>xpos-30 && x<xpos+50 && y<ypos-60) || 
             (y>ypos-20 && y<ypos+50 && x<xpos-65))
	{
        delete b;
	 xpos = random(maxx);
	 ypos = random(maxy);
        b=new TButton(this,CM_PUSHB1,"Я ТУТ !",xpos,ypos,50,20);
        SetupWindow();
	}
	}
}
void TCatchApp::InitMainWindow()
{
  TFrameWindow *wndw = new TCatchWindow(0,
				"Игра поймай меня");
  SetMainWindow(wndw);
}

int OwlMain (int, char*[])
{
  return TCatchApp().Run();
}

    Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#define CM_PUSHB1     101
#define CM_PUSHB2     102
Текст этого приложения можно взять здесь.

    Внешний вид приложения изображен на рисунке 1.


Рис.1. Внешний вид приложения

    Когда вы запустите данную программу, то вы увидите окно, изображенное на рисунке 1.

    После нажатия на кнопку "Начать новую игру", кнопка "Я ТУТ!" начинает "убегать" от указателя мыши, если он приближается к ней.

    Рассмотрим основные принципы работы программы:

    Кнопка "Я ТУТ!" имеет идентификатор CM_PUSHB1, кнопка "Начать новую игру" имеет идентификатор CM_PUSHB2, которые они получают после инициализации окна:

TCatchWindow::TCatchWindow(TWindow *parent, const char far *title) :
	 TFrameWindow (parent, title)
{
  Attr.X = 100;
  Attr.Y = 100;
  Attr.W = 600;
  Attr.H = 600;
  randomize();
	maxx =450;
	maxy = 450;
  xpos = random(maxx);
  ypos = random(maxy);
  game_over = TRUE;
    b=new TButton(this,CM_PUSHB1,"Я ТУТ!",xpos,ypos,50,20);
  new TButton(this,CM_PUSHB2,"Начать новую игру",410,530,170,30);
}

    После нажатия на кнопку "Начать новую игру", происходит событие EV_COMMAND (CM_PUSHB2,PushBut2), которому сопоставлено выполнение функции PushBut2:

void  TCatchWindow::PushBut2()
{
 if (game_over)
  {
	 game_over  =  FALSE;
	 SetWindowText("Поймай  кнопку!");
  }
  else MessageBox("Ошибка!игра уже была начата!!!", "Ошибка", MB_OK);
}
устанавливающей соответствующее значение логической переменной game_over. Если значение game_over ложно, то кнопка "Я ТУТ!" будет реагировать на положение курсора мыши, т.е эта кнопка будет "убегать" от указателя мыши, а иначе кнопка "Я ТУТ!" будет игнорировать перемещение указателя мыши по форме.
void TCatchWindow::EvMouseMove(UINT,TPoint &point)
{
x=point.x;
y=point.y;
if (!game_over)
  {
	SetActiveWindow();
	if ((x>xpos-30 && x<xpos+50 && y>ypos-10) || 
            (y>ypos-20 && y<ypos+50 && x>xpos-10) || 
            (x>xpos-30 && x<xpos+50 && y<ypos-60) || 
            (y>ypos-20 && y<ypos+50 && x<xpos-65))
	{
	 delete b;
	 xpos = random(maxx);
	 ypos = random(maxy);
	 b=new TButton(this,CM_PUSHB1,"Я ТУТ !",xpos,ypos,50,20);
	 SetupWindow();
	}
	}
}

    В данной функции реализовано, собственно, перемещение объекта, в зависимости на каком расстоянии от кнопки "Я ТУТ !", расположен курсор мыши. Если game_over ложно, то объект b класса TButton удаляется из окна. Затем происходит случайный выбор новых координат кнопки, после чего происходит его повторное создание но уже в новом месте.

  b=new TButton(this,CM_PUSHB1,"Я ТУТ !",xpos,ypos,50,20);

    Координаты указателя содержатся в переменных типа int xpos, ypos, а числа 50 и 20 длина и ширина кнопки.

    После этого необходимо провести инициализацию управляющих элементов окна, путем выполнения функции SetupWindow().


   Примечание. Перед компиляцией программы нужно установить в окне TargetExpert значение параметра Platform в Windows 3.x (16).

    На следующем шаге мы рассмотрим программу выбора курсора.




Предыдущий шаг Содержание Следующий шаг