TEACH RC_SPRITE Aaron Sloman, Dec 2000 LIB rc_sprite A DRAFT teach file showing how to use the DRAFT library, The rc_sprite library allows you to make simple triangular coloured "sprites", i.e. moving objects which have a current location and a current heading, and optionally a label which is shown as the object moves and rotates. The sprites can be moved by means of the mouse, and either moved or rotated by means of pop-11 programs. The library and the teach file together provide a demonstration of some of the basic facilities of the rclib package, introduced in TEACH rclib_demo.p and summarised in HELP RCLIB To make the rc_sprite package available, first load the relevant libraries (e.g. use ESC d): uses rclib uses rc_sprite ;;; Create a window in which to draw sprites, in the top right corner ;;; of the screen vars win1 =rc_new_window_object("right", "top", 500, 500, true, 'WIN1'); ;;; The procedure rc_make_sprite takes five arguments and returns a ;;; sprite. the format is: ;;; rc_make_sprite(x, y, base, height, axis, colour, name) -> sprite; ;;; create a sprite called s1, at location -100, 100, ;;; with triangle of base 20, height 30, ;;; orientation 0, i.e. facing east (to the right) ;;; coloured blue, and without a label (hence the false). vars s1 = rc_make_sprite(-100, 100, 20, 30, 0, 'blue', false); ;;; You should be able to move it using the mouse, by dragging with ;;; mouse button 1. Try that, leaving it somewhere near the centre. ;;; The sprite can be moved or rotated using the procedures illustrated ;;; in TEACH rc_linepic, and defined in HELP rc_linepic ;;; Move the sprite to the centre of the window rc_move_to(s1, 0, 0, true); ;;; repeatedly move it up and to the right by 5 steps repeat 5 times rc_move_by(s1, 5, 5, true); endrepeat; ;;; repeatedly move it down and to the left by 5 steps repeat 10 times rc_move_by(s1, -5, -8, true); endrepeat; ;;; When the orientation is 0, the sprite's heading is "east", ;;; i.e. to the right. Try altering it: rc_set_axis(s1, 90, true); rc_set_axis(s1, 45, true); rc_set_axis(s1, 0, true); rc_set_axis(s1, -45, true); rc_set_axis(s1, -135, true); ;;; rc_turn_by can be used to alter the orientation by a specified ;;; number of degrees. A positive number turns the sprite counter- ;;; clockwise. Syssleep can be used to slow down the rotation repeat 60 times rc_turn_by(s1, 2, true); syssleep(5); endrepeat; ;;; A negative number turns it clockwise repeat 60 times rc_turn_by(s1, -3, true); syssleep(1); endrepeat; ;;; The sprite can be made to move in the direction of its current ;;; heading, using the procedure rc_move_sprite, which has ;;; the following format. ;;; rc_move_sprite(s, steplen, turnang, delay, num, trail); ;;; Move the sprite s num times, with a delay after each move. ;;; Each step moves it forward a distance steplen, and turns it by ;;; an angle. The last argument is a boolean determining whether it ;;; should leave a trail or not ;;; to keep it moving in a straight line, without a trail, in steps ;;; of length 2, with a delay of 1 hundredth of a second, and 20 steps rc_move_sprite(s1, 1, 0, 1, 40, false); ;;; it can also move backward rc_move_sprite(s1, -2, 0, 1, 40, false); ;;; prepare it to move up the screen rc_set_axis(s1, 90, true); ;;; now move it rc_move_sprite(s1, 1, 0, 1, 60, false); ;;; prepare it to move left rc_turn_by(s1, 90, true); ;;; now move it another 40 steps of size 1 rc_move_sprite(s1, 1, 0, 1, 80, false); ;;; Now replace the turn angle 0, by 5, to make it turn in steps ;;; of 5 degrees, moving forward 2 pixels each time, 120 times. rc_move_sprite(s1, 2, 5, 1, 120, false); ;;; redo the above a few times ;;; try with delay = 0 rc_move_sprite(s1, 2, 5, 0, 120, false); ;;; Change the turn angle from 5 to 2 degrees rc_move_sprite(s1, 2, 2, 1, 120, false); ;;; or 1 degree rc_move_sprite(s1, 2, 1, 1, 120, false); ;;; 2 degrees but a steplength of 3 instead of 1 rc_move_sprite(s1, 3, 2, 1, 120, false); What happens to the shape as steplength gets larger? What happens to the shape as turn angle gets larger? ;;; more steps and delay = 0 rc_move_sprite(s1, 3, 2, 0, 720, false); ;;; do the same leaving a trail rc_move_sprite(s1, 3, 5, 1, 60, true); ;;; move it without a trail rc_move_sprite(s1, 3, 5, 1, 60, false); ;;; make a new sprite with a red triangle and label, 's2' vars s2 = rc_make_sprite(10, -100, 30, 30, 0, 'red', 's2'); ;;; Try moving it in various ways, with or without a trail rc_move_sprite(s2, 3, 5, 1, 60, true); rc_move_sprite(s2, 3, 2, 1, 60, false); rc_move_sprite(s2, 3, 2, 1, 60, true); rc_move_sprite(s2, 3, -2, 1, 60, true); ;;; bring it back to the middle rc_move_to(s2, 0, 0, true); rc_move_sprite(s2, 5, 2, 1, 60, true); ;;; We can also give a sprite a succession of moves, using the method: ;;; rc_move_sprite_on_path(s, path, delay, trail); ;;; where s is a sprite, path species parameters for a sequence of ;;; commands for rc_move_sprite, delay is an integer specifying the ;;; delay between steps in hundredths of a second. trail is a boolean ;;; specifying whether to leave a trail or not. ;;; Path is a list of three element lists or vectors, each containing ;;; three numbers, to be combined with the variables delay and trail, ;;; to provide inputs for rc_move_sprite. ;;; E.g. put s1 near the bottom left pointing up right rc_move_to(s1, -200, -200, true); rc_set_axis(s1, 45, true); ;;; suppose we give three commands using rc_move_sprite. ;;; See what they do rc_move_sprite(s1, 3, 1, 1, 60, true); rc_move_sprite(s1, 3, -2, 1, 120, true); rc_move_sprite(s1, 2, 4, 1, 60, true); ;;; can use rc_move_sprite_on_path to combine the above three ;;; commands. First re-set the position at bottom left, and orientation rc_move_to(s1, -200, -200, true); rc_set_axis(s1, 45, true); ;;; watch how this compound movement takes it over the same path as ;;; before rc_move_sprite_on_path(s1, [[3 1 60] [3 -2 120] [2 4 60]], 1, false); ;;; Start it a little higher up and give the same command with the final ;;; argument true, to draw a trail. rc_move_to(s1, -200, -150, true); rc_set_axis(s1, 45, true); rc_move_sprite_on_path(s1, [[3 1 60] [3 -2 120] [2 4 60]], 1, true); ;;; Now try s2 rc_move_to(s2, -200, -100, true); rc_set_axis(s2, 45, true); rc_move_sprite_on_path(s2, [[3 1 60] [3 -2 120] [2 4 60]], 1, true); ;;; try again, making the step lengths all negative rc_move_sprite_on_path(s2, [[-3 1 60] [-3 -2 120] [-2 4 60]], 1, true); Exercises: 1. Make one of the sprites draw an equilateral triangle. 2. Make one of the sprites draw a square with a circle at each corner. 3. Try making a sprite weave a path between obstacles: First clear the window rc_redraw_window_object(win1); Then put sprite1 at bottom right facing up left rc_move_to(s1, 220, -200, true); rc_set_axis(s1, 135, true); Now draw some pink blobs to form obstacles. rc_draw_blob(-100, 100, 50, 'pink'); rc_draw_blob(0, 0, 30, 'pink'); rc_draw_blob(100, -100, 60, 'pink'); Now try using rc_move_sprite_on_path so that it moves s1 to the top left corner, first going round to the left of a pink blob, then round to the right of the next one then round to the left of the next one, like a slalom skier going past flags. --- $poplocal/local/rclib/teach/rc_sprite --- Copyright University of Birmingham 2000. All rights reserved. ------