Кибор » Кибор - Интегрированная среда разработки ботов » О программе Кибор » Версия 5.50 Получение и обработка сообщений в немодальных окнах Кибор

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

11. Dantes3000 - 01 Февраля, 2019 - 19:02:24 - перейти к сообщению
Игра крестики-нолики (Отобразить)

Иногда багает, если играть несколько раз подряд.
Можно сломать, если тыкать быстро ко клеткам.
Чтобы исправить - надо ловить нажатие по клеткам чуть иначе.
12. Kibor - 01 Февраля, 2019 - 20:22:35 - перейти к сообщению
Немного поправил.
Пояснения почему "ломается":
Функции 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:;


Потом сделаю возможность делать блокирующие функции и не блокирующие.
13. Dantes3000 - 02 Февраля, 2019 - 03:24:13 - перейти к сообщению
Kibor , Спасибо за объяснение) У меня было немного другое решение, но в 3 ночи уже не хотел его допиливать.
И в текущем коде все таки есть ошибка. При победе игрока по диагонали - ничего не пишет, а потом пишет поражение\проигрыш.


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


А вообще, пора начала эру GameDev'a в кибор...после крестиков пойдут пятнашки. а в конце тетрис
14. Kibor - 02 Февраля, 2019 - 03:57:48 - перейти к сообщению
Для этого малая скорость выполнения программы.
(Добавление)
 Dantes3000 пишет:
пора начала эру GameDev'a в кибор

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




15. Dantes3000 - 02 Февраля, 2019 - 05:49:59 - перейти к сообщению
Kibor , и есть какая-то отдача от движка этого? кроме опыта. пользуется кто-то?
16. Kibor - 02 Февраля, 2019 - 05:59:06 - перейти к сообщению
Да какая там отдача) Я его делал из за сильного интереса. Да и это была моя вторая программа после крестиков ноликов) Ну и еще пару подобных.
Я пользуюсь) Вот себе квартиру свою делал и смотрел перепланировку и ремонт)






Создание таймера на 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);
}
17. Zireael - 02 Февраля, 2019 - 11:05:32 - перейти к сообщению
Пример как вывести изображение на диалог и кнопку (Отобразить)

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

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

Картинки (https://drive.google.com/open?id...1b57mjyRENipDRXp) закинуть на диск C:\ или сделать свои.
18. Zireael - 02 Февраля, 2019 - 15:13:22 - перейти к сообщению
Пример как добавить список (Отобразить)

Если строки в список не поместятся, то будет добавлена вертикальная полоса прокрутки.
Выбирать можно несколько строк с нажатыми Shift или Ctrl.
19. Dantes3000 - 02 Февраля, 2019 - 16:50:07 - перейти к сообщению
Это я туплю или так нельзя?

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);
20. Zireael - 02 Февраля, 2019 - 17:09:16 - перейти к сообщению
 Цитата:
for(int k=0; k>4; k++)

Powered by ExBB FM 1.0 Final