indexing description: "[ An EM_NEVER_ENDING_BACKGROUND uses an EM_TILE_PATTERN that is glued together infinite times in either horizontal or vertical direction. You can move that background in the corresponding direction at any speed (given in pixels per second). See the tile_pattern example for a demonstration. ]" date: "$Date$" revision: "$Revision$" deferred class EM_NEVER_ENDING_BACKGROUND inherit EM_TIME_SINGLETON EM_ANIMATABLE EM_DRAWABLE feature -- Status set_speed (i: INTEGER) is -- Sets the speed to `i' pixels per second do if speed = 0 and i /= 0 then last_time_pos_changed := time.ticks end speed := i end speed: INTEGER -- The speed in pixels per sec cur_position: INTEGER -- The current position in the image set_cur_position (i: INTEGER) is -- Sets `cur_position' to `i', only change `cur_position' if you know what you are doing do cur_position := i ensure set: cur_position = i end feature {NONE} -- Implementation update_cur_position (size, cur_time: INTEGER) is -- Upadates `cur_position' in the image. -- `size' is the size of the image (the maximum position cur_position can reach). -- only call this feature once per draw (from go_to_time). -- 'time' is `Current' time of animation in milliseconds -- (as argument passed to `go_to_time'). local pixel_count: INTEGER do if cur_time - last_time_pos_changed>2000 then last_time_pos_changed := cur_time end -- I need to smooth out here since ticks is not precise enough -- the result is a very smooth motion but it is required that -- the frame rate is stable which will be the case in most situations. -- If not decrease the smoothing_parameter that is set to 95% per default interval := interval * smoothing_parameter + ( cur_time - last_time_pos_changed) * (1 - smoothing_parameter) last_time_pos_changed := cur_time -- I have to trick a lot here to make motion slower than one pixel per -- frame possible position := position + ( (interval / 1000) * speed).abs if position - last_pixel_count > 1.0 then pixel_count := (position - last_pixel_count).rounded last_pixel_count := last_pixel_count + pixel_count if speed < 0 then pixel_count := - pixel_count end end cur_position := cur_position + pixel_count cur_position := pos_to_image_size (cur_position, size) end smoothing_parameter: DOUBLE is 0.9 -- See comment in `update_cur_position' last_time_pos_changed: INTEGER -- The last time `cur_position' was updated last_pixel_count: INTEGER -- The Last over all position quantizised by pixel position: DOUBLE -- The last over all position precise interval: DOUBLE -- Every `interval' ms a call to draw is made img: EM_DRAWABLE -- The image pos_to_image_size (pos: INTEGER; size: INTEGER): INTEGER is -- Returns `pos' if `pos' is element [0,`size'] -- else returns correct position if `pos' is outside `size' require size_greater_zero: size > 0 do if pos > size then result := pos \\ size elseif pos < 0 then result := size + (pos \\ size) else result := pos end ensure result_element_size: result >= 0 and result <= size end min (a: INTEGER;b: INTEGER): INTEGER is -- Return the smaller number of `a' and `b' do if a0.0 end