FreeBasic
Главная
Вход
Регистрация
Суббота, 21.12.2024, 19:16Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Перевод программы из QB64 на FB
salexeiyДата: Четверг, 21.12.2017, 20:31 | Сообщение # 1
Лейтенант
Группа: Пользователи
Сообщений: 72
Репутация: 2
Статус: 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
Репутация: 50
Статус: 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
Репутация: 7
Статус: Offline
salexeiy
Посмотрите эту тему
https://www.freebasic.net/forum/viewtopic.php?f=3&t=8903&hilit=balls
 
salexeiyДата: Суббота, 23.12.2017, 14:25 | Сообщение # 4
Лейтенант
Группа: Пользователи
Сообщений: 72
Репутация: 2
Статус: Offline
Цитата haav ()
Попробуй прибавлять\вычитать по единичке.
Двойка ничего не дала, единица сильно замедлила движение, но стало более плавно. Понижал значение SLEEP, ничего не помогало, тогда решил убрать SLEEP. Шар начал нехило так дёргаться, как будто телепортируется из одного места в другое.
Цитата WQ ()
Посмотрите эту тему
Спасибо огромное за ссылку!!! Алгоритмы отскока - это я ещё исследую, но заметил, что шары в этих примерах отрисовываются с помощью запирания/отпирания экрана, никаких там видео страниц и путов нет. Кстати хорошая техника, на форуме этим уже развлекались, особенно человек (не помню ника), который издевался над эллипсами, заставляя их отрисовываться с огромными скоростями без всяких переключений страниц.

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

На следующий день...

В самом первом примере, который по ссылке на форум бейсика, всё таки используются страницы. Перебросил работу с изображением из своего кода в этот и всё заработало. Значит Стас был прав, косяк где то в расчётах. Буду думать...

Вот что получилось. Взял расчёты движения из кода по ссылке и перенёс в свою программу. Стало намного лучше, но теперь появилась другая проблема - шар постепенно замедляет своё движение smile Да, откуда взял расчёты, на это и было расчитано, но теперь, не знаю как сделать так, чтобы шар сохранял свою постоянную скорость. Если убираю расчёт замедления, то шарик снова начинает дёргаться. Тупик.

В коде ниже переменные 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

И тут же smile Всё, решил!!! Двигается теперь ну просто идеально гладко!!! Виноват был 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
 
  • Страница 1 из 1
  • 1
Поиск: