Delphi:Вопрос-Ответ
| |
TimKruz | Дата: Четверг, 27 Декабря 2012, 20:55 | Сообщение # 301 |
старожил
Сейчас нет на сайте
| CyberStorm, скриншот под спойлер спрячь. Цитата (CyberStorm) то выделнный красным квадрат - был бы белым. Он был бы не совсем белым (для этого нужно больше итераций), но белых точек содержал бы больше, чем на остальной поверхности.
Раз уж делать тестирующую программу, то вот что я сделал: Можно скачать, поиграться для наглядности (а ещё проверить - вдруг у кого-то random не такой). Примечание: "общее число вычислений" должно быть во много раз больше "верхняя граница", иначе фигня получится; чем больше числа - тем лучше, но слишком большие числа приведут к очень медленному процессу на 98%-99% (но она не зависает, она думает); включённый флаг "Randomize каждое вычисление" заставляет перед каждым random() делать randomize (это я сделал на всякий случай, если кто-то именно так пытается применять randomize).
Если бы было следующее:Цитата (Nanotentacle) с вероятностью в 95% эти числа попадают в промежуток 1700-2000 то график получался бы со смещением правого (1700..2000) конца сильно вверх (к тысячам и десяткам тысяч), а левый (0..1700) стремился бы к нулю.
Цитата (Nanotentacle) Есть ли более "случайные" генераторы для Делфи Хм, поищи в интернете... Генераторы наверняка есть, вот только "случайность" у них будет примерно такая же. Цитата (Nanotentacle) или лучше написать его самостоятельно? Попробуй написать, но всё равно будет что-то вроде random...
Сообщение отредактировал TimKruz - Четверг, 27 Декабря 2012, 21:07 |
|
| |
Nanotentacle | Дата: Пятница, 28 Декабря 2012, 09:15 | Сообщение # 302 |
был не раз
Сейчас нет на сайте
| Да, сейчас проверил собственноручно, вы правы. Но тогда возникает вопрос: в моей программе при создании объекта вычисляется случайная величина, и каждый раз она оказывается как раз в промежутке 1700-2000. Не было ни одного случая, чтобы значение оказывалось меньше 1700. С чем такое может быть связано?
|
|
| |
CyberStorm | Дата: Пятница, 28 Декабря 2012, 12:37 | Сообщение # 303 |
был не раз
Сейчас нет на сайте
| Цитата (Nanotentacle) Да, сейчас проверил собственноручно, вы правы. Но тогда возникает вопрос: в моей программе при создании объекта вычисляется случайная величина, и каждый раз она оказывается как раз в промежутке 1700-2000. Не было ни одного случая, чтобы значение оказывалось меньше 1700. С чем такое может быть связано? Думаю у тебя там ведь не такая функция: a:=rndom(2000), скорее всего перемедрил где-то типа a:=1700+random(300) без кода трудно анализировать
|
|
| |
Nanotentacle | Дата: Пятница, 28 Декабря 2012, 14:03 | Сообщение # 304 |
был не раз
Сейчас нет на сайте
| Там именно a := random(2000). Перед всеми рандомами стоит randomize.
Я и раньше замечал, что с помощью рандома не получается делать случайные события. Допустим, после x := random(100) все попытки разделить вероятности, например, по 20 путем if x <= 20 if (x > 20) and(x <=40) ни к чему не приводило, приходилось подбирать некие коэффициенты, чтобы получать те самые 20 процентов, которые мне требовались. Возможно, дело в том, что у меня не 10 миллионов итераций, а порядка 100-1000.
Сообщение отредактировал Nanotentacle - Пятница, 28 Декабря 2012, 14:08 |
|
| |
Destroy | Дата: Четверг, 10 Января 2013, 23:46 | Сообщение # 305 |
постоянный участник
Сейчас нет на сайте
| возникла проблема пытаюсь связать timage и timagelist решил записать все в таймер чтобы сменял картинки через некоторое время Код procedure TForm1.tmr1Timer(Sender: TObject); const n:integer=0;
begin ImageList1.Draw(Image1.Canvas, 10,10,n);
n:=n+1;//n это номер картинки
end;
выдает ошибку: [Error] Unit1.pas(35): Left side cannot be assigned to
|
|
| |
GECK | Дата: Пятница, 11 Января 2013, 11:51 | Сообщение # 306 |
заслуженный участник
Сейчас нет на сайте
| Destroy, дык еще бы, ты константе присвоить что-то пытаешься. Замени const на var.
Всё гениальное просто. И хреново работает.
Сообщение отредактировал GECK - Пятница, 11 Января 2013, 11:54 |
|
| |
TimKruz | Дата: Пятница, 11 Января 2013, 21:29 | Сообщение # 307 |
старожил
Сейчас нет на сайте
| GECK, запись вида n:integer=0; не константа, точнее не простая константа, а типизированная, т.е. может менять значение по ходу выполнения программы. Но в данном случае записать её в разделе var нельзя, т.к. нельзя давать инициализирующее значение переменным в процедурах/функциях. Почему вылетает ошибка - не знаю (она ведь на n:=n+1 указывает?), но лучше просто вынеси описание переменной n из обработчика таймера в переменные модуля, так будет логичнее и ошибок не будет. А конструкцию n:=n+1 тут можно заменить на inc(n), так удобнее, если название переменной длинное (ты же не собираешься делать n1, n2, n3 и т.д.?).
|
|
| |
GECK | Дата: Пятница, 11 Января 2013, 21:54 | Сообщение # 308 |
заслуженный участник
Сейчас нет на сайте
| Цитата (TimKruz) запись вида n:integer=0; не константа, точнее не простая константа, а типизированная, т.е. может менять значение по ходу выполнения программы. Менять значение она может только в том случае, если это явно разрешить компилятору(директива {$WriteableConst On}). Обычно же делфи этого не позволяет, именно с такой ошибкой. Так что либо разрешать переписывать константы, либо делать из n переменную(что как-то логичней, на мой взгляд)
Всё гениальное просто. И хреново работает.
|
|
| |
Destroy | Дата: Воскресенье, 20 Января 2013, 21:54 | Сообщение # 309 |
постоянный участник
Сейчас нет на сайте
| вытащил n:integer из процедуры описал в разделе var перед implementation теперь работает и это тоже позаимствовал всем спасибо за внимание Добавлено (20.01.2013, 21:54) --------------------------------------------- попытался тут сделать небольшой эффект моря бьющегося об берег. беру из имейдж листа изображение и вывожу имейдж. Возникла проблема. 1 изображение оставляет после себя белые следы вот исходник
|
|
| |
CyberStorm | Дата: Воскресенье, 20 Января 2013, 22:54 | Сообщение # 310 |
был не раз
Сейчас нет на сайте
| ты вроде .pas файл забыл приложить в архив "Unit1 in '..\..\..\..\games\Delphi7\Projects\pirate project\Unit1.pas' {Form1};"
|
|
| |
Destroy | Дата: Понедельник, 21 Января 2013, 10:05 | Сообщение # 311 |
постоянный участник
Сейчас нет на сайте
| ой прошу прощения вот сейчас вроде все положил
|
|
| |
CyberStorm | Дата: Понедельник, 21 Января 2013, 12:34 | Сообщение # 312 |
был не раз
Сейчас нет на сайте
| В ImageList'e ты вроде выставил прозрачный цвет, а вот надо было еще указать в инспекторе - чтоб заместо него ничего не выводил:
Не советую рисовать на Image'ах, выводи изображения на канвас формы http://rghost.ru/43199466
|
|
| |
masb8ly-GC | Дата: Понедельник, 21 Января 2013, 12:37 | Сообщение # 313 |
постоянный участник
Сейчас нет на сайте
| CyberStorm, canvas не лучший способ хранения графики по той причине, что, например, при "наезжании" другим окном на окно с канвасом, канвас очищается. И таких нюансов очень много!
Backend Developer ESIS Client Side Developer Room8Studio Technical Leader Lucid Reality Labs Chief Technology Officer The Intruders Chief Technology Officer RoyalePlay Games
|
|
| |
Destroy | Дата: Понедельник, 21 Января 2013, 14:15 | Сообщение # 314 |
постоянный участник
Сейчас нет на сайте
| Цитата (CyberStorm) В ImageList'e ты вроде выставил прозрачный цвет, а вот надо было еще указать в инспекторе - чтоб заместо него ничего не выводил: все равно все также без измененийДобавлено (21.01.2013, 14:15) --------------------------------------------- но да ладно более менее разобрался с этим
|
|
| |
TimKruz | Дата: Понедельник, 21 Января 2013, 16:34 | Сообщение # 315 |
старожил
Сейчас нет на сайте
| Цитата (masb8ly-GC) canvas не лучший способ хранения графики Ну если ты игру пишешь, то у тебя минимум 30 кадров в секунду, так что канва формы будет постоянно обновляться. Канва TImage просто сама по себе обновляется заданной картинкой, поэтому сохраняет изображение. А канва TForm вроде бы по-умолчанию непрерывно обновляется, поэтому просто нарисовать не получится, нужно самому всё обновлять (если вручную [средствами WinAPI, без использования VCL] создать окно - такого не будет, т.к. обработчик события перерисовки окна самому писать надо, хотя не обязательно). Если у тебя игра не использует какие-то сложные компоненты VCL (ну которые ты кидаешь на форму), то лучше создавать окно вручную, так быстрее должно получиться (правда структура приложения усложнится и никакими дизайнерами не воспользуешься). А вообще, для игр лучше OpenGL использовать... Конечно, он устроен иначе, и придётся потратить какое-то время на его изучение, но вообще-то ничего в нём особо сложного нет... Вот, например, книга: Краснов М.В., "OpenGL графика в проектах Delphi", там основы просто и понятно изложены.
Короче, изучай всё постепенно, но не старайся написать очень сложную (графически) игру чисто на канве image и тому подобного...
|
|
| |
Destroy | Дата: Суббота, 26 Января 2013, 17:22 | Сообщение # 316 |
постоянный участник
Сейчас нет на сайте
| вот у меня например есть 3 переменные img1, img2, img3. можно ли сделать что то типа imgN, где N (1,2,3) то есть мне не нужен массив. в зависимости от значения N вызывается разные img чтобы имя переменной изменялось может немного некорректно изложил мысль
Сообщение отредактировал Destroy - Суббота, 26 Января 2013, 17:22 |
|
| |
TimKruz | Дата: Воскресенье, 27 Января 2013, 20:32 | Сообщение # 317 |
старожил
Сейчас нет на сайте
| Цитата (Destroy) вот у меня например есть 3 переменные img1, img2, img3. можно ли сделать что то типа imgN, где N (1,2,3) то есть мне не нужен массив. в зависимости от значения N вызывается разные img чтобы имя переменной изменялось Так сделать не получится (вообще, по-моему, ни в одном компилируемом языке нельзя менять идентификаторы "на лету", потому что в коде не может быть двусмысленности - компилятор просто не поймёт такого imgN). Придётся использовать массив img[n], а если требуется задание неопределённого заранее числа переменных - использовать динамический массив. Если ты не можешь использовать массивы напрямую, например, у тебя заранее созданы визуальные компоненты с именами img1/img2/../imgn, а ты хочешь перебирать их циклом for - тогда можно использовать массив указателей. Каждый элемент массива img содержит ссылку на соответствующий компонент. Если ты используешь классы (типа TImage), то можно сделать так: Код type TForm1=class(TForm) img1,img2,img3:TImage; //Описание компонентов в классе формы <...> var img:array [1..3] of TImage; //Где-то задан массив указателей на эти компоненты <...> //Где-то копируем ссылки на экземпляры класса TImage в наш массив img[1]:=img1; img[2]:=img2; img[3]:=img3; <...> //А тут используем их в цикле: for i:=1 to 3 do img[i].canvas.clear; <...> Вроде бы должно работать. Писать в месте копирования ссылок много, но если циклов for достаточно много - будет всё-таки проще делать так.
Теоретически, можно в классе формы (TForm1) задать массив компонентов img:array [1..3] of TImage, только, наверное, возникнут сложности с редактором форм. Но в обычном классе (не привязанном к редактору форм) такое легко делается.
|
|
| |
Destroy | Дата: Вторник, 05 Февраля 2013, 20:38 | Сообщение # 318 |
постоянный участник
Сейчас нет на сайте
| спасибо, немного по другому решил проблему. но схоже с твоим Добавлено (05.02.2013, 15:27) --------------------------------------------- Очередной вопрос. очень прошу объяснить про потоки (treads), желательно с комментариями, на примере приложения, которое допустим должно менять img1 на img2, img3...img5. С интервалом в 1 секунду. Таймер не предлагать!нужны именно потоки Добавлено (05.02.2013, 20:38) --------------------------------------------- up
|
|
| |
TimKruz | Дата: Среда, 06 Февраля 2013, 00:20 | Сообщение # 319 |
старожил
Сейчас нет на сайте
| Цитата (Destroy) очень прошу объяснить про потоки (treads) Мог и сам посмотреть в интернете - уроков полно... Например, вот, первая ссылка в Яндексе... Цитата (Destroy) на примере приложения, которое допустим должно менять img1 на img2, img3...img5. С интервалом в 1 секунду. Ммм, хочешь использовать потоки для создания анимации? Бред какой-то... Я вообще не пойму, зачем тут потоки. Хотя... Нужна независимая от основного кода анимация, т.е. выполняемая в отдельном потоке? Но почему нельзя использовать таймер, ведь в нём можно производить несколько действий сразу...
Так. Вот, написал тебе простейший примерчик, на форме две надписи и кнопка: Код unit mainunit;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); end;
//Описываем собственный класс на основе базового TMyThread=class(TThread) //num юзаем для того, чтобы экземпляр класса //мог определить, кто он есть в этом мире... num:byte; //короче, типа идентификатора protected //Перезаписываем виртуальный абстрактный метод Execute procedure Execute; override; public //Создаём собственный конструктор constructor Create(nm:byte); end;
var Form1: TForm1; th1,th2:TMyThread; //Это наши экземплярчики
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin //Создаём два процесса, первый и второй th1:=TMyThread.Create(1); th2:=TMyThread.Create(2); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin //Завершаем поток и удаляем экземпляры th1.Terminate; th2.Terminate; end;
//Конструктор класса constructor TMyThread.Create; begin num:=nm; //Сохраняем тип //Следующая переменная, заданная в true, //удаляет экземпляр сразу после остановки FreeOnTerminate:=true; //Вызываем TThread.Create с параметром //CreateSuspended=true, т.е. поток изначально остановлен; //если false - поток запускается сразу после создания inherited Create(true); end;
procedure TMyThread.Execute; begin //Бесконечный цикл repeat //Выбираем действие по типу case num of 1: form1.Label1.Caption:=inttostr(strtoint(form1.Label1.Caption)+1); 2: form1.Label2.Caption:=inttostr(strtoint(form1.Label2.Caption)+1); end; //Делаем паузу sleep(500); until false; end;
procedure TForm1.Button1Click(Sender: TObject); begin //Переключаем состояние потоков: вкл/выкл if th1.Suspended then begin th1.Resume; th2.Resume; end else begin th1.Suspend; //Suspend - приостановка, но не завершение th2.Suspend; end; end;
end.
Ещё есть хороший пример от разработчиков Delphi - смотри в C:\Program Files\Borland\Delphi7\Demos\Threads, если ты устанавливал с примерами. Там демонстрируется сортировка трёх списков тремя разными методами в трёх потоках - типа наглядная демонстрация разности в скорости между методами сортировок, т.к. потоки, теоретически, выполняются синхронно, если у них одинаковый приоритет.
Сообщение отредактировал TimKruz - Среда, 06 Февраля 2013, 00:27 |
|
| |
Destroy | Дата: Четверг, 07 Февраля 2013, 15:12 | Сообщение # 320 |
постоянный участник
Сейчас нет на сайте
| Цитата (TimKruz) Ммм, хочешь использовать потоки для создания анимации? Бред какой-то.. нее, просто не знал на каком примере это можно сделать а так спасибо за разъяснение
|
|
| |
|