Более плавное движение снаряда в ракетке?

#racket #game-physics

#ракетка #игра-физика

Вопрос:

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

 (require 2htdp/universe
         2htdp/image)

(define gx 0)
(define gy 0.35)

(struct ballstate (x y vx vy) #:transparent)

(define startstate (ballstate 10 590 7 -20))

(define (make-new-state old)
  (define newvx (  (ballstate-vx old) gx))
  (define newvy (  (ballstate-vy old) gy))
  (ballstate (  (ballstate-x old) newvx)
             (  (ballstate-y old) newvy)
             newvx
             newvy))


(define (main)
  (big-bang startstate
            [on-tick make-new-state]
            [to-draw place-ball-at]
            [on-key reset]))

(define (place-ball-at s)
  (place-image (circle 10 "solid" "red")
               (ballstate-x s)
               (ballstate-y s)
               (empty-scene 800 600)))

(define (reset s ke)
  startstate)

(main)
  

Вопрос в том, как сделать это лучше, быстрее, плавнее и без мерцания?

Комментарии:

1. Это кажется актуальным (но, возможно, не слишком полезным) groups.google.com/forum /#!тема/plt-схема/HJDkNor277E

2. @DaoWen В 2htdp / universe встроена двойная буферизация.

3. @soegaard — Если вы прочтете весь поток, вы увидите часть внизу, где они предполагают, что проблема заключается не в двойной буферизации, а в отсутствии поддержки перерисовки только небольшой части холста для обновлений. Это та часть, о которой я говорил, и причина, по которой это «не слишком полезно», заключается в том, что нет предлагаемого обходного пути.

4. @daowen Хорошо — поток был длинным, поэтому подумал, что вы имели в виду двойную буферизацию.

Ответ №1:

Вот две вещи, которые могут помочь:

  1. Предложение on-tick принимает необязательный параметр, который определяет время между двумя тактами. Значение по умолчанию равно 1/28, поэтому, если вы уменьшите это значение, вы получите больше кадров, что приведет к более плавной анимации.

  2. Если вашей программе требуется больше времени, чем время между каждым тиком для создания изображения, вы увидите заикание. Предварительное вычисление всего, что можно предварительно вычислить, — это хорошо. Например, нет причин каждый раз создавать новую пустую сцену, поэтому ниже я просто сохранил ее в переменной.

 (define (main)
  (big-bang startstate
            [on-tick make-new-state 1/50]
            [to-draw place-ball-at]
            [on-key reset]))

(define background (empty-scene 800 600))

(define (place-ball-at s)
  (place-image (circle 10 "solid" "red")
               (ballstate-x s)
               (ballstate-y s)
               background))
  

Комментарии:

1. Спасибо, но даже с вашими изменениями мяч все еще мерцает. 🙁

2. @RacketNoob Какую платформу вы используете?

3. @RacketNoob Обратите внимание, что когда в секунду показывается вдвое больше кадров, вы можете уменьшить vx до половины. Поскольку мяч перемещается на меньшее расстояние за кадр, результат будет более плавным.

4. @RacketNoob: Попробуйте с 1/100. Оно должно быть более плавным. Я предполагаю, что вы испытываете не мерцание (когда вы можете видеть стирание (частей) предыдущего кадра и рисование нового кадра), а постоянство видения (которое вызывает заикание, как выразился Соегаард): когда мяч прыгает из одной позиции в другую,но недостаточно быстро, ваши глаза видят это в двух разных местах одновременно, и вы можете бессознательно интерпретировать это как движение взад и вперед между старой и новой позицией в течение небольшого периода времени.