mark.warren
2020-4-14 13:28:20

I am trying to draw a screen for a game in big-bang 2htdp an I’m running into performance problems, can anyone point me in the direction of a fast way to draw an ‘offscreen’ buffer without having to return a new image after every draw I do and then setting the screen variable to that new image. Sorry that didn’t come out very well, but I’m not sure how to describe it.


mark.warren
2020-4-14 13:31:03

Code will explain better


mark.warren
2020-4-14 13:31:12

#lang racket (require 2htdp/universe 2htdp/image) (define WIDTH 800) (define HEIGHT 600) (define CELL-SIZE 5) (define CELLS-X (/ WIDTH CELL-SIZE)) (define CELLS-Y (/ HEIGHT CELL-SIZE)) (define FINISHED #f) (define TILE (freeze (square 5 "outline" "red"))) (define (create-world-state) (define world-state (make-vector CELLS-X (make-vector CELLS-Y))) (for ([y (in-range CELLS-Y)]) (for ([x (in-range CELLS-X)]) (vector-set! (vector-ref world-state x) y 0))) world-state) (define world-state (create-world-state)) (define (render-world ws) (define es (empty-scene WIDTH HEIGHT "black")) (for ([y (in-range CELLS-Y)]) (for ([x (in-range CELLS-X)]) (set! es (place-image TILE (* CELL-SIZE x) (* CELL-SIZE y) es)))) es) (define (check-stop ws) FINISHED) (define (key-handler ws key-event) (set! FINISHED #t)) (define (update-world ws) world-state) (big-bang world-state (on-tick update-world) (on-key key-handler) (to-draw render-world) (stop-when check-stop) (close-on-stop #t))


mark.warren
2020-4-14 13:32:06

I am trying to avoid the set! in render-world as I’m sure this may be slowing things down.


soegaard2
2020-4-14 13:38:14

I am almost sure (define world-state (make-vector CELLS-X (make-vector CELLS-Y))) is not what you intend. It will create one vector (make-vector CELLS-Y)) and store that vector in every cell of the vector (make-vector CELLS-X ...) .


soegaard2
2020-4-14 13:38:49

I think you’ll want to use build-vector instead.


mark.warren
2020-4-14 13:40:30

EEK! Thanks @soegaard2 hadn’t got as far as using the vectors yet, but it’s a good point that would have bitten me later.


soegaard2
2020-4-14 13:41:54

The reason this becomes slow over time is that es holds the inial empty scene and then for each frame 25 tiles are attached.


soegaard2
2020-4-14 13:42:21

So in frame 2 there are 50 tiles attached, in frame 3 there 75 and so on.


soegaard2
2020-4-14 13:43:08

I think, you can fix it by adding: (set! es (freeze es)) in render-word right before returning es.


soegaard2
2020-4-14 13:43:26

This will replace an image with attached smaller images into a single image.


mark.warren
2020-4-14 13:43:47

Ok, I’ll look at that.


soegaard2
2020-4-14 13:45:38

An alternative is to put es outside render-world: (define es ...) . Then use (set! es (empty-schene ...)) inside render-world. That way the “start image” has no attached sub images.


mark.warren
2020-4-14 13:46:23

I’ll have a look at that too, thanks for the pointers.


soegaard2
2020-4-14 13:46:23

This will erase the previous tiles - they are kept in your current version.


mark.warren
2020-4-14 14:10:12

@soegaard2 Also place-images might be a better fit rather that doing separate place-image if I set up two lists first.