Автоматизация и боты

 Помощь      Поиск      Пользователи
Сайт Кибор     Программируемый кликер Кибор     Видео обучение     Заказать бот

 Страниц (16): « 1 [2] 3 4 5 6 7 8 9 » В конец    

> Описание: Создание меню и отлов клика по нему, отлов всех сообщений GetMessage полученных окном.
Dantes3000
Отправлено: 02 Февраля, 2019 - 03:02:24
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1464
Дата рег-ции: Июнь 2016  
Репутация: 58




Игра крестики-нолики (Отобразить)

Иногда багает, если играть несколько раз подряд.
Можно сломать, если тыкать быстро ко клеткам.
Чтобы исправить - надо ловить нажатие по клеткам чуть иначе.

(Отредактировано автором: 02 Февраля, 2019 - 03:05:56)

 
 Top
Kibor
Отправлено: 02 Февраля, 2019 - 04:22:35
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 8094
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 355




Немного поправил.
Пояснения почему "ломается":
Функции GetMessage вызываются при любом сообщение.
Программа не блокирует их прием даже если не завершилось выполнение кода который был в работе от предыдущего сообщения. То есть если мы кликнули по кнопке и пошел выполняться код, то второй клик по кнопке быстрый прервет выполнение кода и начнет сначала. Это для того что бы не было пропущенных сообщений и скрипт отрабатывал разные сообщения быстро.


Пояснение. Есть код:
CODE:
function getmessage(0, WM_COMMAND)
{
//Тут код
//Еще код есть
//Еще строка + message.lparam
//Если (это == то то) return;
//Еще код идет
}



К примеру вызвалась функция.
Код дошел до
//Еще код есть
и опять нажали на кнопку..
Эта функция опять вызовется прервавшись.

Как бороться:
CODE:
int f=0;

function getmessage(0, WM_COMMAND)
{
if (f==1) return;//Если мы уже выполняем код в функции
f=1;//Запрещаем ходить пока не закончим этот код
//Тут код
//Еще код есть
//Еще строка + message.lparam
//Если (это == то то) {f=0; return;}//Снимаем запрет
//Еще код идет
f=0;//Снимаем запрет
}

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

Но еще есть проблема
Если во время выполнения этого кода будет какое то сообщение, то даже при блокировке с помощью переменной f будет перезаписан параметр message.lparam, с которым работает этот код.
Решение:

CODE:
int f=0;
int p;

function getmessage(0, WM_COMMAND)
{
if (f==1) return;//Если мы уже выполняем код в функции
f=1;//Запрещаем ходить пока не закончим этот код
p=message.lparam;
//Тут код
//Еще код есть
//Еще строка + p
//Если (это == то то) {f=0; return;}//Снимаем запрет
//Еще код идет
f=0;//Снимаем запрет
}

Мы при получение сообщения и начале работы кода сразу сохраняем значение message.lparam в p
и теперь работаем с ней. И нам не важно что message.lparam может измениться.

Так же поправил пару неточностей:
Было:
CODE:
if (m[i*3] == m[i*3+1] && m[i*3+1] == m[i*3+2]) return m[i];//Возвращало m[i], который относится к другой линии

Так же добавил нужные проверки.
Стало:
CODE:
if (m[i*3]!= "-" && m[i*3] == m[i*3+1] && m[i*3+1] == m[i*3+2]) return m[i*3];//Комбинации для победы вычисляются по формулам

CODE:
external(INT, "CreateWindow", "CreateWindowExA", "User32.dll" );
external(INT, "SetWindowTextA", "SetWindowTextA", "User32.dll" );

createdialog(0);
showdialog(0, "Диалог",100, 100, 180, 250, 1, 1);

while(window ("Диалог")==0)sleep(10);
win w=window ("Диалог");



int b[9]; //кнопки
int move=0; //счетчик хода
string m[9]={"-","-","-","-","-","-","-","-","-"}; //текст кнопок


b[0]=CreateWindow(0, "BUTTON", "-", 1342177280, 10, 10, 50, 50, formatwi(w), 0, 0, 0);
b[1]=CreateWindow(0, "BUTTON", "-", 1342177280, 60, 10, 50, 50, formatwi(w), 0, 0, 0);
b[2]=CreateWindow(0, "BUTTON", "-", 1342177280, 110, 10, 50, 50, formatwi(w), 0, 0, 0);

b[3]=CreateWindow(0, "BUTTON", "-", 1342177280, 10, 60, 50, 50, formatwi(w), 0, 0, 0);
b[4]=CreateWindow(0, "BUTTON", "-", 1342177280, 60, 60, 50, 50, formatwi(w), 0, 0, 0);
b[5]=CreateWindow(0, "BUTTON", "-", 1342177280, 110, 60, 50, 50, formatwi(w), 0, 0, 0);

b[6]=CreateWindow(0, "BUTTON", "-", 1342177280, 10, 110, 50, 50, formatwi(w), 0, 0, 0);
b[7]=CreateWindow(0, "BUTTON", "-", 1342177280, 60, 110, 50, 50, formatwi(w), 0, 0, 0);
b[8]=CreateWindow(0, "BUTTON", "-", 1342177280, 110, 110, 50, 50, formatwi(w), 0, 0, 0);


int f=1;//флаг для блокировки что бы не отрабатывала функция пока не закончится работа

//запишется в p message.lparam если клик разрешен.так как при любом сообщение lparam перезапишется
//даже если f=1. Что бы не ломалась логика будет работать с сохраненным значением p
int p=0;
pc_move();
f=0;//Разрешили клик

loop()
{
sleep(10);
rename("Ход №"+format(move));
}

function check_win()
{
for(int i = 0; i < 3; i++) //Для победы нужны 3 клеточки
{
if (m[i*3]!= "-" && m[i*3] == m[i*3+1] && m[i*3+1] == m[i*3+2]) return m[i*3];//Комбинации для победы вычисляются по формулам
if (m[i]!= "-" && m[i] == m[i+3] && m[i+3] == m[i+6]) return m[i];//Вертикальная
if ((m[2]!= "-" && m[2] == m[4] && m[4] == m[6]) || (m[0]!= "-" && m[0] == m[4] && m[4] == m[8])) return m[2];//наискось
}
return '-'; //Иначе - ничья
}


function result()
{
if(check_win()=='O') {messagebox("Вы выиграли"); goto global st;}
if(check_win()=='X') {messagebox("Вы проиграли"); goto global st;}
if(move>8 && check_win()=='-') {messagebox("Ничья"); goto global st;}
}


function pc_move()
{
int r;

loop()
{
r=rand(0, 9);
if(m[r]=="-") break;
}
move++;
m[r]="X";
SetWindowTextA(b[r], "X");
result();
}

function getmessage(0, WM_COMMAND)
{
if (f==1) return;//Если комп не сделал ход выходим
f=1;//Запрещаем ходить пока комп не ответит
p=message.lparam;
for(int k=0; k<9; k++)
{
if(p==b[k])
{

if(m[k]=="X" || m[k]=="O") break;
m[k]="O";
while(getkeystate(1)) sleep(10);
move++;
SetWindowTextA(b[k], "O");
//pause(500);
result();
pc_move();
}
}

f=0;//Разрешаем ход

}




st:;


Потом сделаю возможность делать блокирующие функции и не блокирующие.
 
 Top
Dantes3000
Отправлено: 02 Февраля, 2019 - 11:24:13
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1464
Дата рег-ции: Июнь 2016  
Репутация: 58




Kibor , Спасибо за объяснение) У меня было немного другое решение, но в 3 ночи уже не хотел его допиливать.
И в текущем коде все таки есть ошибка. При победе игрока по диагонали - ничего не пишет, а потом пишет поражение\проигрыш.


Нажмите для увеличения


А вообще, пора начала эру GameDev'a в кибор...после крестиков пойдут пятнашки. а в конце тетрис
 
 Top
Kibor
Отправлено: 02 Февраля, 2019 - 11:57:48
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 8094
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 355




Для этого малая скорость выполнения программы.
(Добавление)
 Dantes3000 пишет:
пора начала эру GameDev'a в кибор

Когда то давно я страдал (учился) созданием визуального движка для создания 3D игр.
3D Мастер назывался. http://ocean-games.com/soft/3dmaster.php
Можно было начертить 3Д мир, создать объекты, управляемые объекты, автономно управляемые, аптечки и тд. Расставить их в этом мире, назначить им свойства и собрать игру)) Все это без единой строчки кода. Мир и все объекты создавались в самом редакторе.
Ну естественно благополучно он мне надоел.))




 
 Top
Dantes3000
Отправлено: 02 Февраля, 2019 - 13:49:59
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1464
Дата рег-ции: Июнь 2016  
Репутация: 58




Kibor , и есть какая-то отдача от движка этого? кроме опыта. пользуется кто-то?
 
 Top
Kibor
Отправлено: 02 Февраля, 2019 - 13:59:06
Post Id



Администратор
Эксперт


Покинул форум
Сообщений всего: 8094
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 355




Да какая там отдача) Я его делал из за сильного интереса. Да и это была моя вторая программа после крестиков ноликов) Ну и еще пару подобных.
Я пользуюсь) Вот себе квартиру свою делал и смотрел перепланировку и ремонт)






Создание таймера на winapi

CODE:
external(INT, "SetTimer", "SetTimer", "User32.dll" );

createdialog(0);
//////////

showdialog(0, "Диалог", 558, 234, 250, 300, 1, 1);

while(window ("Диалог")==0)sleep(10);
win w=window ("Диалог");

//////////
SetTimer(formatwi(w), 1, 1000, 0);
loop()
{
beep(500, 100);
looptime(300)sleep(10);
}


function getmessage(0, WM_TIMER)
{
beep(2500, 100);
}
 
 Top
Zireael
Отправлено: 02 Февраля, 2019 - 19:05:32
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4394
Дата рег-ции: Нояб. 2017  
Репутация: 580




Пример как вывести изображение на диалог и кнопку (Отобразить)

Вот так это выглядит:

Нажмите для увеличения

Картинки (https://drive.google.com/open?id...1b57mjyRENipDRXp) закинуть на диск C:\ или сделать свои.
 
 Top
Zireael
Отправлено: 02 Февраля, 2019 - 23:13:22
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4394
Дата рег-ции: Нояб. 2017  
Репутация: 580




Пример как добавить список (Отобразить)

Если строки в список не поместятся, то будет добавлена вертикальная полоса прокрутки.
Выбирать можно несколько строк с нажатыми Shift или Ctrl.
 
 Top
Dantes3000
Отправлено: 03 Февраля, 2019 - 00:50:07
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 1464
Дата рег-ции: Июнь 2016  
Репутация: 58




Это я туплю или так нельзя?

CODE:
external(INT, "CreateWindow", "CreateWindowExA", "User32.dll" );

createdialog(0);
showdialog(0, "Диалог",100, 100, 300, 300, 1, 1);

while(window ("Диалог")==0)sleep(10);
win w=window ("Диалог");

int nums_text[15];
int xk=5;
int yk=5;

for(int k=0; k>4; k++)
{
nums_text[k]=CreateWindow(0, "BUTTON", "s "+format(k), 1342177280, xk, yk, 50, 50, formatwi(w), 0, 0, 0);
xk=xk+50;
}


loop()sleep(1);
 
 Top
Zireael
Отправлено: 03 Февраля, 2019 - 01:09:16
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4394
Дата рег-ции: Нояб. 2017  
Репутация: 580




 Цитата:
for(int k=0; k>4; k++)
 
 Top
Страниц (16): « 1 [2] 3 4 5 6 7 8 9 » В конец
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« О программе Кибор »


Все гости форума могут просматривать этот раздел.
Только администраторы и модераторы могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 




Powered by