#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:
Вот две вещи, которые могут помочь:
-
Предложение on-tick принимает необязательный параметр, который определяет время между двумя тактами. Значение по умолчанию равно 1/28, поэтому, если вы уменьшите это значение, вы получите больше кадров, что приведет к более плавной анимации.
-
Если вашей программе требуется больше времени, чем время между каждым тиком для создания изображения, вы увидите заикание. Предварительное вычисление всего, что можно предварительно вычислить, — это хорошо. Например, нет причин каждый раз создавать новую пустую сцену, поэтому ниже я просто сохранил ее в переменной.
(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. Оно должно быть более плавным. Я предполагаю, что вы испытываете не мерцание (когда вы можете видеть стирание (частей) предыдущего кадра и рисование нового кадра), а постоянство видения (которое вызывает заикание, как выразился Соегаард): когда мяч прыгает из одной позиции в другую,но недостаточно быстро, ваши глаза видят это в двух разных местах одновременно, и вы можете бессознательно интерпретировать это как движение взад и вперед между старой и новой позицией в течение небольшого периода времени.