Перевод программы из QB64 на FB
|
|
salexeiy | Дата: Четверг, 21.12.2017, 20:31 | Сообщение # 1 |
Лейтенант
Группа: Пользователи
Сообщений: 72
Статус: Offline
| Проверьте, пожалуйста, правильно ли я перевёл программу из QB64 на FB. Смысл прост: летает изображение шарика и отскакивает от углов. Шарик то летает, но почему то дёргается немного. Может что не так понял в процессе перевода. Изображение шарика прилепил, чтобы вы не искали его: шарик
Команды QB64 закомментировал, они стоят на своих местах. Вместо них я сделал на FB. Всё остальное 1:1 как и было в исходнике, т.е. ничего больше не менял.
Код 'DIM Image AS LONG ' Закомментил за ненадобностью DIM x AS INTEGER DIM y AS INTEGER DIM MoveUp AS INTEGER DIM MoveRight AS INTEGER
'SCREEN _NEWIMAGE(800,600,32) SCREENRES 800,600,32,2 ' Этого, как и строчки ниже, не было SCREENSET 1,0
DIM Image AS ANY PTR=IMAGECREATE(64,64) ' Пример взял из хелпа FB, чтобы заработала команда PUT
x=0 y=0 MoveUp=0 MoveRight=0 'Image=_LOADIMAGE("Ball.bmp") BLOAD "Ball.bmp",Image
DO '_LIMIT 100 ' Как я понял, LIMIT - это задержка, но чем больше число, тем меньше задержка. CLS ' Я написал IF x>=800-64 THEN MoveRight=0 IF x<=0 THEN MoveRight=1 IF y>=599-64 THEN MoveUp=1 IF y<=0 THEN MoveUp=0 IF MoveRight=1 THEN x+=3 ELSE x-=3 END IF IF MoveUp=1 THEN y-=3 ELSE y+=3 END IF 'PCOPY _DISPLAY,1 '_PUTIMAGE(x,y),Image '_DISPLAY ' По-моему, это буфер изображения. 'PCOPY 1,_DISPLAY ' Три строчки ниже тоже я написал PUT(x,y),Image PCOPY 1,0 SLEEP 15 LOOP WHILE INKEY()=""
Сообщение отредактировал salexeiy - Четверг, 21.12.2017, 20:48 |
|
| |
haav | Дата: Четверг, 21.12.2017, 20:55 | Сообщение # 2 |
Генералиссимус
Группа: Администраторы
Сообщений: 1373
Статус: Offline
| Мне кажется проблема здесь:
Код IF MoveRight=1 THEN x+=3 ELSE x-=3 END IF IF MoveUp=1 THEN y-=3 ELSE y+=3 END IF
Попробуй прибавлять\вычитать по единичке. Правда упадет скорость движения шарика , но можно просто уменьшить паузу. В этой программе пофигу, но в больших программах (с большим кол-вом расчетов) советую cls ставить прямо перед отрисовкой (в данном случае перед командой PUT(x,y),Image).
Тему завтра перемещу в раздел "Вопросы по языку FreeBasic", нечего ей делать во флудилке.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
WQ | Дата: Четверг, 21.12.2017, 21:57 | Сообщение # 3 |
Полковник
Группа: Проверенные
Сообщений: 215
Статус: Offline
| salexeiy Посмотрите эту тему https://www.freebasic.net/forum/viewtopic.php?f=3&t=8903&hilit=balls
|
|
| |
salexeiy | Дата: Суббота, 23.12.2017, 14:25 | Сообщение # 4 |
Лейтенант
Группа: Пользователи
Сообщений: 72
Статус: Offline
| Цитата haav ( ) Попробуй прибавлять\вычитать по единичке. Двойка ничего не дала, единица сильно замедлила движение, но стало более плавно. Понижал значение SLEEP, ничего не помогало, тогда решил убрать SLEEP. Шар начал нехило так дёргаться, как будто телепортируется из одного места в другое.Цитата WQ ( ) Посмотрите эту тему Спасибо огромное за ссылку!!! Алгоритмы отскока - это я ещё исследую, но заметил, что шары в этих примерах отрисовываются с помощью запирания/отпирания экрана, никаких там видео страниц и путов нет. Кстати хорошая техника, на форуме этим уже развлекались, особенно человек (не помню ника), который издевался над эллипсами, заставляя их отрисовываться с огромными скоростями без всяких переключений страниц.
Надо будет пересмотреть код, убрать путы, страницы и т.д., и попробовать поработать с запиранием экрана, хоть это и сделает код не похожим на исходник из QB64. Кстати, а как в этом случае работать с файлом изображения шарика? То, что с кружками, я понял.
На следующий день...
В самом первом примере, который по ссылке на форум бейсика, всё таки используются страницы. Перебросил работу с изображением из своего кода в этот и всё заработало. Значит Стас был прав, косяк где то в расчётах. Буду думать...
Вот что получилось. Взял расчёты движения из кода по ссылке и перенёс в свою программу. Стало намного лучше, но теперь появилась другая проблема - шар постепенно замедляет своё движение Да, откуда взял расчёты, на это и было расчитано, но теперь, не знаю как сделать так, чтобы шар сохранял свою постоянную скорость. Если убираю расчёт замедления, то шарик снова начинает дёргаться. Тупик.
В коде ниже переменные vx,vy отвечают за начальное ускорение. Если они будут равны 20, то шар будет бешеным в начале, так что поставил 5 для начала.
Код DIM AS DOUBLE x,y,vx,vy,g=.01 DIM radius AS INTEGER=64
SCREENRES 800,600,32,2
DIM Image AS ANY PTR=IMAGECREATE(64,64)
BLOAD "Ball.bmp",Image
x=RND*800 y=RND*300 vx=5 vy=5
DO WHILE INKEY="" SCREENSET 1:CLS ' Проверка по Y IF y>=600-radius THEN vy=-.9*vy y=600-radius END IF IF y<=0 THEN vy=-.9*vy y=0 END IF vy=.999*vy ' Какая то симуляция air-friction. Если эту строчку (и аналогичную для Х) закомментить, то ничего не изменяется толком. y+=vy ' Проверка по X IF x>=800-radius THEN vx=.9*-vx x=800-radius END IF IF x<=0 THEN vx=.9*-vx x=0 END IF vx=.999*vx x+=vx PUT(x,y),Image,TRANS ' Переделал картинку для этого параметра с цветом фона (255,0,255). Вроде бы тоже стало плавнее движение. FLIP SLEEP 9 LOOP
END
Добавлено (23.12.2017, 14:25) --------------------------------------------- Оказалось всё куда печальнее. Глючит видеокарта... Так что дёрганье от этого. Но код переписал по другому, взяв подсказку из уроков по яваскрипту. Теперь всё выглядит вот так:
Код SCREENRES 800,600,32,2 DIM Image AS ANY PTR=IMAGECREATE(64,64)
BLOAD "Ball.bmp",Image
DIM AS INTEGER x,y,dx,dy,diam=64
x=800/2 y=600/2
dx=3 dy=3
DO WHILE INKEY="" SCREENSET 1: CLS IF (x+dx>800-diam) OR (x+dx<=0) THEN dx=-dx END IF IF (y+dy>600-diam) OR (y+dy<=0) THEN dy=-dy END IF x+=dx y+=dy
PUT(x,y),Image,TRANS FLIP SLEEP 10 LOOP И тут же Всё, решил!!! Двигается теперь ну просто идеально гладко!!! Виноват был SLEEP, а ещё надо было поставить синхронизацию с видеокартой и вынести Screenset из цикла с добавлением параметра. Вопрос решён, всем спасибо!!! Вот обновлённый код:
Код SCREENRES 800,600,32,2 DIM Image AS ANY PTR=IMAGECREATE(64,64)
BLOAD "Ball.bmp",Image
DIM AS INTEGER x,y,dx,dy,diam=64
x=800/2 y=600/2
dx=3 dy=3
screenset 1,0
DO WHILE INKEY="" CLS IF (x+dx>800-diam) OR (x+dx<=0) THEN dx=-dx END IF IF (y+dy>600-diam) OR (y+dy<=0) THEN dy=-dy END IF x+=dx y+=dy
PUT(x,y),Image,TRANS screensync ' Синхронизация screencopy LOOP end
Сообщение отредактировал salexeiy - Суббота, 23.12.2017, 14:37 |
|
| |
|