Пишем игру 21 (очко). Пример использования 1С и ActiveX

31.08.17

Разработка - Разработка внешних компонент

Пишем игру "очко". Программный код состоит из двух частей: 1.Разработка компоненты работы с графикой на Delphi 2.Логическая реализация игрового процесса на 1С

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Пишем игру 21 (очко). Пример использования 1С и ActiveX (Программный код 1С и Delphi):
.zip 1,49Mb
3
3 Скачать (1 SM) Купить за 1 850 руб.

Часть 1. Пишем компоненту работы с графикой на Delphi.

Для работы с графикой решено использовать внешнюю компоненту, т.к возможности 1С в этом ограничены.

Открываем старый и добрый Дельфи 7, и создаем новый проект.

Переходим на вкладку ActiveX и выбираем ActiveX Form

Вводим имя ActiveX

Для хранения изображений колоды карт будем использовать компонент TImage. Кидаем его на форму.

и загружаем в TImage колоду карт найденную в интернете:

Отображать карты будем на канве формы, предварительно вырезав нужную из TImage. Поэтому, чтобы TImage не светилось - прячем его. Для этого свойство Visible у TImage ставим в False.

Теперь опишем методы работы с изображением. Их будет два:

1. Отображение на канве формы нужной игральной карты.

2. Очистка самой канвы.

Открываем Type Library

И добавляем 2 метода: AddCard и ClearCanvas

у метода AddCard вводим параметры: x,y - это координаты отображения карты. row, column - это номер игральной карты из загруженного нами изображения. Например 0 ряд 2 карта.

Опишем реализацию методов в модуле:

//вырезаем и отображаем на канве нужную нам игральную карту
procedure Tw0rm21.AddCard(x, y, row, colimn: Integer);
const
  h=215; //высота карты
  w=148; //длина карты
begin
  Canvas.CopyRect(Rect(x, y, x+w, y+h), Image1.Canvas, Rect(colimn*w ,row*h, (colimn*w)+w, (row*h)+h));
end;

//Очищаем канву
procedure Tw0rm21.ClearCanvas;
begin
  InvalidateRect(0, nil, true);
end;

На этом реализация компоненты закончена. Вы можете ее в дальнейшем доработать как вам нужно.

Осталось только зарегистировать компоненту.

2. Реализуем игровую логику на 1С

Создаем внешнюю обработку. На форму обработки размещаем наш компонент:

Располагаем контролы (кнопки, надписи) на форме:

И описываем реализацию логики игры:

Перем КолодаКарт, ОбщийСчетИгрок, ОбщийСчетПК;
Перем ИгрокX, ИгрокY,  КомпX, КомпY, ШагКарты;
Перем карта1ПК,	карта2ПК;
Перем СтоимостьКарт;


Процедура КнопкаВыполнитьНажатие(Кнопка)
	Колонка = ПолучитьСлучайноеЧисло(0, 12);
	Ряд = ПолучитьСлучайноеЧисло(0, 3);
	ЭлементыФормы.ЭлементУправления1.AddCard(1,1, Ряд, Колонка);
КонецПроцедуры


Функция ПолучитьСлучайноеЧисло(Мин,Макс) 

	//вместо Randomize 
	Для н = 1 По 100 Цикл 
		Уник = Новый УникальныйИдентификатор; 
	КонецЦикла; 

	//генерируем GUID 
	Уник = СокрЛП(Новый УникальныйИдентификатор); 

	//оставляем только цифры 
	Уник = СтрЗаменить(Уник,"-",""); 
	Уник = СтрЗаменить(Уник,"a",""); 
	Уник = СтрЗаменить(Уник,"b",""); 
	Уник = СтрЗаменить(Уник,"c",""); 
	Уник = СтрЗаменить(Уник,"d",""); 
	Уник = СтрЗаменить(Уник,"e",""); 
	Уник = СтрЗаменить(Уник,"f",""); 

//знаменатель должен иметь такое же количество нулей + 1 
	Знаменатель = 10; 
	Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл 
		Знаменатель = Знаменатель * 10; 
	КонецЦикла; 

	Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1 

	//преобразуем его в случайное число из заданного интервала, округляем до целого 
	ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

	Возврат ЧислоИзИнтервала; 

КонецФункции

Процедура РаздатьКартыНажатие(Элемент)
	СтоимостьКарт = "11;2;3;4;5;6;7;8;9;10;2;3;4";
	СтоимостьКарт = СтрЗаменить(СтоимостьКарт, ";", Символы.ПС);
	ЭлементыФормы.ЭлементУправления1.ClearCanvas();
	ИнициализоватьКолоду();
	СчетИгрок = 0;
	СчетПК	= 0;
	ИгрокX = 2; ИгрокY = 3;
	КомпX = 2;  КомпY = 500;
	Шагкарты = 180;
	карта1ПК = Неопределено;
	карта2ПК = Неопределено;	
	
	карта1Игрок =ПолучитьКарту();
	карта2Игрок =ПолучитьКарту();
	СчетИгрок = СчетИгрок + карта1Игрок.Стоимость;
	СчетИгрок = СчетИгрок + карта2Игрок.Стоимость;
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта1Игрок.Ряд, карта1Игрок.Колонка);
	ИгрокX = ИгрокX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта2Игрок.Ряд, карта2Игрок.Колонка);
	
	карта1ПК =ПолучитьКарту();
	карта2ПК =ПолучитьКарту();
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, 4, 2);
	КомпX = КомпX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, 4, 2);
	
	КомпX = 2;
	
	ОбновитьФорму(Ложь, Истина, Истина);
	
	Если СчетИгрок = 21 Тогда 
		Предупреждение("У ВАС ОЧКО! Вы победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;	

	Если СчетИгрок = 22 Тогда 
		Предупреждение("У ВАС ЗОЛОТОЙ! Вы победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;

	
КонецПроцедуры

Процедура ИнициализоватьКолоду()
	Колонка = 13;
	Строк  = 4;
	КолодаКарт = Новый Массив(Строк, Колонка);
	Для а = 0 по Строк-1 Цикл 
		Для б = 0 по Колонка-1 Цикл 
			КолодаКарт[а][б] = 0;
		КонецЦикла;	
	КонецЦикла;	
КонецПроцедуры	

Функция ПолучитьКарту()
	Карта = Новый Структура;
	КартаНайдена = Ложь;
	
	
	Пока КартаНайдена = Ложь Цикл 
		
		Колонка = ПолучитьСлучайноеЧисло(0, 12);
		Ряд = ПолучитьСлучайноеЧисло(0, 3);	

		Если КолодаКарт[Ряд][Колонка] = 0 Тогда 
			Карта.Вставить("Ряд", Ряд);
			Карта.Вставить("Колонка", Колонка);
			Стоимость = СтрПолучитьСтроку(СтоимостьКарт, Колонка+1);
			Карта.Вставить("Стоимость", Число(Стоимость));
			//Сообщить(Стоимость);
			КолодаКарт[Ряд][Колонка] = 1;
			КартаНайдена = Истина;
		КонецЕсли;	
			
	КонецЦикла;	
	
	Возврат(Карта);
КонецФункции	

Процедура ВзятьКартуНажатие(Элемент)
	ИгрокX = ИгрокX + Шагкарты;
	карта = ПолучитьКарту();
	ЭлементыФормы.ЭлементУправления1.AddCard(ИгрокX, ИгрокY, карта.Ряд, карта.Колонка);
	СчетИгрок = СчетИгрок + карта.Стоимость;
	Если СчетИгрок > 21 Тогда 
		Предупреждение("У ВАС ПЕРЕБОР! Вы проиграли!");
		ОбщийПК = ОбщийПК + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
	КонецЕсли;	
КонецПроцедуры

Процедура ХватитНажатие(Элемент)
	ОбновитьФорму(Ложь, Ложь, Ложь);	
	Пауза(2);
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, карта1ПК.Ряд, карта1ПК.Колонка);
	СчетПК = СчетПК + карта1ПК.Стоимость;
	Пауза(2);
	КомпX = КомпX + Шагкарты;
	ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, карта2ПК.Ряд, карта2ПК.Колонка);
	СчетПК = СчетПК + карта2ПК.Стоимость;
	
	Если СчетПК = 22 Тогда 
		Предупреждение("У Меня ЗОЛОТОЙ! Я Победил!");
		ОбщийИгрок = ОбщийИгрок + 1;
		ОбновитьФорму(Истина, Ложь, Ложь);
		Возврат;
	КонецЕсли;

	
	Пока СчетПК < 17 Цикл  
		Пауза(2);
		КомпX = КомпX + Шагкарты;
		картаПК =ПолучитьКарту();
		ЭлементыФормы.ЭлементУправления1.AddCard(КомпX, КомпY, картаПК.Ряд, картаПК.Колонка);
		СчетПК = СчетПК + картаПК.Стоимость;
	КонецЦикла;
	
	ОбновитьФорму(Истина, Ложь, Ложь);
	
	Если СчетПК > 21 Тогда 
		Предупреждение("У меня перебор! ВЫ ВЫЙГРАЛИ!");
		ОбщийИгрок = ОбщийИгрок + 1;
		Возврат;
	КонецЕсли;	
	
	Если СчетПК = 21 Тогда 
		Предупреждение("У меня ОЧКО! Я победил!");
		ОбщийПК = ОбщийПК + 1;
		Возврат;
	КонецЕсли;
	
	Если СчетПК = СчетИгрок Тогда 
		Предупреждение("Ничья!");
		Возврат;
	КонецЕсли;	
	
	Если СчетПК > СчетИгрок Тогда 
		Предупреждение("Я победил!"); 
		ОбщийПК = ОбщийПК + 1;
		Возврат;
	КонецЕсли;	
	
	Если СчетПК < СчетИгрок Тогда 
		Предупреждение("Вы Победили!");
		ОбщийИгрок = ОбщийИгрок + 1;
		Возврат;
	КонецЕсли;	


	
КонецПроцедуры

Процедура Пауза(Секунд)
	
  КонДата = ТекущаяДата() + Секунд;
  Пока ТекущаяДата() < КонДата Цикл
      // ждемссс....
  КонецЦикла;	
  
КонецПроцедуры	

Процедура ПриОткрытии()
	ОбщийИгрок = 0;
	ОбщийПК = 0;
	ОбновитьФорму(Истина, Ложь, Ложь);
КонецПроцедуры

Процедура ОбновитьФорму(РаздатьКарты, ВзятьКарту, Хватит)
	ЭлементыФормы.РаздатьКарты.Доступность = РаздатьКарты;
	ЭлементыФормы.ВзятьКарту.Доступность   = ВзятьКарту;
	ЭлементыФормы.Хватит.Доступность       = Хватит;
КонецПроцедуры

Вызов наших методов из компоненты написанной на Delphi выглядит так: ЭлементыФормы.ЭлементУправления1.AddCard(1,1, Ряд, Колонка); и ЭлементыФормы.ЭлементУправления1.ClearCanvas();

запускаем и проверяем

На этом у меня все! Вы можете сами доработать правила игрового процесса, так как считаете нужным.

Архив с примером выкладываю ниже.

Перед тем как запустить обработку из архива необходимо зарегистрировать компоненту w0rm21Proj1.ocx. 

Готов ответить на вопросы.

Спасибо за внимание!

 

ActiveX Delphi программирование Игры

См. также

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Программист Пользователь Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Медиадисплей покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Экран можно использовать в качестве графического меню-борда в кафе и видеовывески. В качестве устройства отображения можно использовать Android-планшеты, смарт-телевизоры с Android, мониторы или проекторы под управлением Windows или Linux-компьютера. Linux-версия успешно запускается на одноплатных компьютерах Raspberri Pi и Orange Pi. Настраивается ЛЮБОЙ ДИЗАЙН экрана при помощи встроенного графического редактора! Решение можно масштабировать от одного экрана до тысяч экранов с централизованным управлением.

18000 руб.

30.05.2017    53929    9    69    

46

Разработка внешних компонент Телефония, SIP Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    47146    124    66    

67

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Платные (руб)

Внешняя компонента для конвертации PDF файлов в картинки без использования дополнительных программ. Работает на сервере и в тонком клиенте.

2400 руб.

25.06.2024    1069    3    4    

3

Разработка внешних компонент Программист Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    3542    3    0    

5

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента в виде библиотеки (.dll файл), позволяющая посылать команды и получать ответы по протоколу WebSocket из 1С. Компонента работает только на стороне "клиента".

4440 руб.

22.06.2020    18344    18    33    

22

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Позволяет автоматизировать работу с картинками. С помощью компоненты можно измерять размер изображений, поворачивать их, наносить водяные знаки, конвертировать из одного формата в другой. Будет очень полезна для интернет-магазинов и всех, кому постоянно требуется работать с различными графическими форматами. Выполнена по технологии NativeAPI. Работает с форматами: jpg (jpeg), png, bmp, gif, tif

3600 руб.

02.09.2010    77456    72    257    

191

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

3000 руб.

12.05.2020    28548    138    100    

91

Разработка внешних компонент Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

В статье описывается приложение-конструктор внешних компонент (native API). Конструктор упрощает процесс разработки за счет удобного добавления всех нужных функций и процедур в графическом режиме, с указанием их параметров и типов параметров. На выходе приложение генерирует готовый код на С++ и Rust и позволяет сразу приступить к реализации, без настройки API компоненты вручную.

04.12.2024    4497    kovalevdmv    26    

75
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. rpgshnik 3810 23.05.17 10:29 Сейчас в теме
Это круто!
Прикрепленные файлы:
DrAku1a; Tolpinski; Romakon92; CyberCerber; TDAlleaMebeli; Smirnov1980; +6 Ответить
2. BackinSoda 23.05.17 10:39 Сейчас в теме
Что это за правило такое - "Золотой" ?
CyberCerber; Smirnov1980; +2 Ответить
3. user621724_Dimav1979 411 23.05.17 10:52 Сейчас в теме
(2) в данном случае это когда два туза сразу выпало...
Smirnov1980; +1 Ответить
7. CyberCerber 874 23.05.17 13:01 Сейчас в теме
(3) Не заметил в коде, а где-то проверяется, что это именно два туза, а не, например 10 + 10 + 2?
8. user621724_Dimav1979 411 23.05.17 17:48 Сейчас в теме
(7) Проверка на Золотой сразу после раздачи первых двух карт, если счет будет 22 - то это и есть 2 туза
4. smirnov.es 21 23.05.17 11:17 Сейчас в теме
Респект таким парням. Ждем реализации на мобильной платформе
CyberCerber; Smirnov1980; madonov; rpgshnik; +4 Ответить
5. Smirnov1980 7 23.05.17 12:07 Сейчас в теме
Это cool !

ps В базовую поставку 1С уже давно требуется пасьянс "косынка" )))).
AlexGroovy; rpgshnik; +2 Ответить
6. CyberCerber 874 23.05.17 13:00 Сейчас в теме
Круто! Лет 10 назад делал тоже 21 на Делфи 7... Интересно, можно будет его теперь в 1С встроить :-)
9. quick 584 23.05.17 22:22 Сейчас в теме
А слабо на делфях в 7-ку сделать форму, да что бы калбэки уходили в 1С? ;)
Если делфи еще интересно, могу посоветовать глянуть https://github.com/WorldException/v7SimpleAddIn
там уже XE2, но сам принцип использовать RTTI для внешних компонент может быть интересен.
rpgshnik; +1 Ответить
10. user621724_Dimav1979 411 24.05.17 04:41 Сейчас в теме
(9) Если кому интересно, могу статью опубликовать отлавливание событий из формы ActiveX в 1С...можно на примере игры морской бой или на примере ведения карты склада ячеистого газобетона
smirnov.es; user657734_YGREEN; Rain88; Trancer64; monsterZE; inf012; +6 Ответить
12. rpgshnik 3810 24.05.17 17:45 Сейчас в теме
(10) Нужно бооооольше уроков
Прикрепленные файлы:
11. user621724_Dimav1979 411 24.05.17 08:11 Сейчас в теме
Выкладываю обработку с компонентой
Прикрепленные файлы:
21_example.zip
wowik; monsterZE; +2 Ответить
13. PerlAmutor 155 24.05.17 21:35 Сейчас в теме
Немного полезной критики =) Delphi? Гхм, пора бы ей уже на покой. Компонента не переносима на другие платформы, про веб-клиент, можно забыть. В безопасном режиме работать не будет. Тут возникает главный вопрос, зачем было связывать это вообще с 1С? Хотите того же самого - используйте HTML5 и JavaScript. К сожалению тоже будет не переносимо, т.к. Internet Explorer нет в Linux. Легких путей, к сожалению, разработчики 1С нам не предлагают. Управляемые Формы, опять же к сожалению, оказались менее управляемые чем Обычные. Надеюсь они когда нибудь встроят в свою платформу браузер Chromium и позволят управлять всем исходным кодом страницы при использовании веб-клиента.

Старайтесь вот так не писать (красиво, но не практично), я обжегся уже на этом
Перем КолодаКарт, ОбщийСчетИгрок, ОбщийСчетПК;


1С настолько тупа, что по Ctrl+Space не находит переменных ОбщийСчетИгрок и ОбщийСчетПК объявленных через запятую.

Только так будет находить:

Перем КолодаКарт;
Перем ОбщийСчетИгрок;
Перем ОбщийСчетПК;
14. DrAku1a 1747 25.05.17 02:34 Сейчас в теме
(13) Delphi - это классика.
HTML5 не обязателен, обычного HTML + JS достаточно будет.
16. orefkov 1153 27.05.17 15:25 Сейчас в теме
(13)
1С настолько тупа, что по Ctrl+Space не находит переменных ОбщийСчетИгрок и ОбщийСчетПК объявленных через запятую.

Ну, может человек снегопат использует и знать не знает ни о ctrl+space, ни о таких тонкостях его использования :)
rpgshnik; +1 Ответить
15. orefkov 1153 27.05.17 13:54 Сейчас в теме
Получение следующей карты сделано конечно плоховато. На такой игре, как очко, конечно сойдёт, так как много карт всё-равно не выходит, но для игр с длинной раздачей - для последних карт может кучу раз цикл вхолостую крутить, пока попадёт в еще не выданные карты. Обычно делают нормальное тасование колоды. Для 1С например, можно сделать ТЗ с колонками ЗначениеКарты и КлючСортировки. Заполнить КлючСортировки случайными числами и отсортировать по ней. Потом брать последовательно карты из отсортированной ТЗ.
rpgshnik; +1 Ответить
17. user621724_Dimav1979 411 27.05.17 16:02 Сейчас в теме
(15) Александр полностью с вами согласен. Алгоритм можно оптимизировать до бесконечности...но главная цель данной статьи не в алгоритме игры...а в навыках применения компоненты актив икс
asmuk; Fox-trot; +2 Ответить
Оставьте свое сообщение