![]() |
Simple REBOL Game Programming For Young PeopleTo get started, download and install REBOL/View from http://www.rebol.com/download-view.html (it takes just a few seconds). Once it's installed, run REBOL (Start -> Programs -> REBOL -> REBOL View), then click the "Console" Icon. Type "editor none" at the prompt - that will run REBOL's built in text editor. At this point, you are ready to start typing in REBOL programs. Copy/paste each example in this tutorial into the REBOL editor to see what the code does. Every REBOL program must begin with the following header: REBOL [] To create a program window (a "GUI"), use the following code: REBOL [] view layout [size 600x440] In the REBOL editor, save the above program code to a file, then press F5 on your keyboard to run it. If you save your program with a ".r" extension in the file name (i.e., "myprogram.r"), then you can also click your program's file icon, and it will run just like an ".exe" file. To center a program window on your computer screen, use "center-face". Paste the following code into the REBOL text editor, then press the F5 key: REBOL [] view center-face layout [size 600x440] You can put a title in your program header, which will appear in the title bar of your program window. Paste the following code and press F5: REBOL [title: "Game Demo"] view center-face layout [size 600x440] By default, REBOL program windows have gray backdrop. You can change that using the "backdrop" word (paste this code and press F5): REBOL [title: "Game Demo"] view center-face layout [size 600x440 backdrop white] Here's how you add "widgets" (buttons, text fields, drop down lists, etc.) to your program window. Notice that everything in the window is between square brackets, and has been indented. Enclosed square brackets are called "blocks" in REBOL. Indentation is NOT required, but makes the code easier to read (paste this and press F5): REBOL [title: "Game Demo"] view center-face layout [ size 600x440 backdrop white btn "Click Me" field "Type Here" text-list data ["first" "second" "third"] ] Here's how you make your widgets perform an action. The "alert" function is used to create a message box with text for the user to read. Notice that the word "value" holds the current/selected value in the widget (paste and press F5): REBOL [title: "Game Demo"] view center-face layout [ size 600x440 backdrop white btn "Click Me" [alert "Clicked"] field "Type Here" [alert value] text-list data ["first" "second" "third"] [alert value] ] By default, REBOL puts widgets below one another in the program window. You can change that by using the "across" word. You can change back to the default behavior by using the word "below" (paste/F5): REBOL [] view center-face layout [ size 600x440 backdrop white across btn white btn red btn blue below btn green btn orange btn purple ] You can place your widgets at specified coordinate positions (XxY coordinates indicate X pixels over and Y pixels down) (paste/F5): REBOL [] view layout [ size 600x400 at 200x250 btn "button 1" at 300x350 btn "button 2" ] You can give any widget a LABEL by using a word of your choice, followed by a colon. You can change a labeled widget's position using the "/offset" refinement, followed by a colon. Whenever you make changes to a window's appearance (such as when moving a widget), you must use the "show" function to update the display. Notice the button widget below labeled "button1", and notice how clicking the other button changes button1's position (paste/F5): REBOL [] view layout [ size 600x400 at 20x20 button1: btn "button 1" at 100x20 btn "change button 1's position" [ button1/offset: 300x250 show button1 ] ] You can create a coordinate position from two separate numbers, using the "as-pair" function (paste/F5): REBOL [] x-size: 600 y-size: 400 x-position: 20 y-position: 20 view layout [ size (as-pair x-size y-size) at (as-pair x-position y-position) button1: btn "button 1" ] You'll need random numbers often when making games. You can create them with the "random" function. To be sure that random numbers are properly generated, include the code "random/seed now/time" in your program (paste/F5): REBOL [] random/seed now/time x: random 500 ; generates a random number up to 500 y: random 300 size-x: 600 size-y: 400 view layout [ size (as-pair size-x size-y) at (as-pair x y) button1: btn "button 1" ] You can also create random pairs directly (i.e., without using as-pair). Just set the upper limit for the the X and Y numbers (i.e., "random 500x400") (paste/F5): REBOL [] random/seed now/time view layout [ size 600x400 at 20x20 button1: btn "button 1" at 100x20 btn "change button 1's position" [ button1/offset: random 500x400 show button1 ] ] You can set the text of any widget using the "/text" refinement. You'll need this to update text information on screen (i.e., for scores, lives left, etc.). To make sure text gets properly formatted, use the "form" function (paste/F5): REBOL [] view layout [ text1: text "This is a text widget" btn "Change the text widget's text" [ text1/text: form "Changed!" show text1 ] ] Here is one way to check for user keystrokes. This is a great way to create game controls (paste/F5): REBOL [] view center-face layout [ size 600x440 text "Press an arrow key" key keycode [left] [alert "You pressed the LEFT arrow key"] key keycode [right] [alert "You pressed the RIGHT arrow key"] ] To create a repeating loop, just copy the line below that starts with the word "box", and the closing 3 square brackets, into your GUI code. Anything inside those brackets will be repeated continuously. This is a great way to create continuous motion and actions in a game (paste/F5): REBOL [] view layout [ size 600x440 btn1: btn red box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [ btn1/offset: btn1/offset + 2x2 show btn1 ]]] ] You can check if any condition is true, and make decisions in your program, using the "if" function. Put the actions to be performed (if the condition is true) inside square brackets following the if test (paste/F5): REBOL [] direction: "down" view layout [ size 600x440 btn1: btn red box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [ if btn1/offset/2 > 420 [direction: "up"] if btn1/offset/2 < 1 [direction: "down"] if direction = "down" [btn1/offset: btn1/offset + 0x5] if direction = "up" [btn1/offset: btn1/offset - 0x5] show btn1 ]]] ] Most games will involve testing for "collisions" - when graphics touch. Use REBOL's "within?" function to test if graphics share coordinate locations (i.e., are touching) (paste/F5): REBOL [] direction: "down" view layout [ size 600x440 btn1: btn red at 20x350 btn2: btn green box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [ if btn1/offset/2 > 420 [direction: "up"] if btn1/offset/2 < 1 [direction: "down"] if direction = "down" [btn1/offset: btn1/offset + 0x5] if direction = "up" [btn1/offset: btn1/offset - 0x5] show btn1 if (within? btn1/offset btn2/offset 1x1) [alert "Collision!"] ]]] ] Here's a little game using much of what you've learned so far. Catch the falling pieces (paste/F5): REBOL [title: "Catch Game"] alert "Arrow keys move left/right, up goes faster, down goes slower" random/seed now/time speed: 11 score: 0 view center-face layout [ size 600x440 backdrop white across at 270x0 text "Score:" t: text bold 100 (form score) at 280x20 y: btn 50x20 orange at 280x420 z: btn 50x20 blue key keycode [left] [z/offset: z/offset - 10x0 show z] key keycode [right] [z/offset: z/offset + 10x0 show z] key keycode [up] [speed: speed + 1] key keycode [down] [if speed > 1 [speed: speed - 1]] box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [ y/offset: y/offset + (as-pair 0 speed) show y if y/offset/2 > 440 [ y/offset: as-pair (random 550) 20 show y score: score - 1 ] if within? z/offset (y/offset - 50x0) 100x20 [ y/offset: as-pair (random 550) 20 show y score: score + 1 ] t/text: (form score) show t ]]] ] You can use the following short program to encode images, sounds, or any other types of files, so that they can be included directly in the code of your program (be sure to save this program to a separate file on your desktop - you will use it often): REBOL [Title: "Binary Resource Embedder"] system/options/binary-base: 64 uncompressed: read/binary to-file request-file/only editor compress to-string uncompressed Use the following "load to-binary decompress" code to load encoded files created by the program above. Assign each graphic a word label by using the colon symbol, and then display it in your program window using an "image" widget (paste/F5): REBOL [] gun-man: load to-binary decompress 64#{ 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 } view layout [ size 600x400 backdrop black image gun-man ] Just as with images, you can use the "Binary Resource Embedder" program, provided earlier, to save sound files as code in your programs. You can play .wav sounds using the last line of following code (paste/F5): REBOL [] my-sound: load to-binary decompress 64#{ eJxtlHtMU1ccx6vGR3kWLMWpm5pskc2pi3MkqFNYJsh0oigV5KEULK2lpdDb9vbe 9r56W1pogSKltBQqSGGAlYeimAlDkU1H1KgssrhBmFNhjAECHcZl2bVo1LjfyTm/ nO/vdf45n9joyMjphTTaoQj2Tq4QWB1Io9HmUSt8Fc2z59GWUEp6KpB6k8pC3zJs 7nzTvXbB/sdhmMdjcx5744q9SkHf1l4f/LLhq+K33jZnOI6/3gZBVAjq8Qj6Mkzl ek5KwBEpL11saGyrANhx4kKHzUBgmFKhUKKIAgBAlNRqNaSayiO1pEqeLeTzxZjJ nA+KAK2ByBaidle1XoGVnrLjx3kSlULEOSaBIBmkMZkL9Lo8owYUZYqyRLwMMVJo NqgkoL7MQoqOiXUVzpPl1a7OiyXS6K2RBxJiE1KgitrTteYyq0ktStgbE3MwTUha 7BXFmDxHjpGITE5Unu++dLaupc2UFTLfd5PEZi8xObp7W/Ts8N3Jx3npXMjqarQA 8XFHpJBUeAwscNRZ8wwF1a7auvIzVWRCwCL/XY6B4c5CWGYol+8LWfk52X63t1Ka mnw0Izk+XkCcbDpVKueKUdvpRofVfulms3TlIh8mODQ7fjpx2359ERTFZB3u+Gt2 MH+zr8+mgwJMZ2/vajYeDt2aYr72U7eNUDf+es+yYQFzQcQvs+MTmQH0zaTTsued j/HHT2b6vloc6L0+71Z/hw2RykVHvt6bVtTZd+ecraCq3sT28fNnFD4bdQ/sWhwQ xHG14HH7iHtPpi6ELgn0CnFNTQybdwSviYLs39TYyqwN565cq+evoQctDvv+6cjT ns/ogQGH6r4tVwh0PWMjzq1egb5rqqfHJhq3+Pt9kOW61l2jh3TOG0Pt/BV01sL9 A+7H/5xi+TGWpl/pq0cScxruP2qI8g70W2Zxj7ovb/cJYCS0D49dMXC5up4H13OC vFkLEodnhv8t8WUE+AsHn9w27totPj94XbXCZ6l31uj45MOkJUz65tbJiZGahJ1p rv6fcZYXa/7eodlHtLplXqyFkXenJ7qSwz4VNlxuTlrK8NvYNDPqrl9LDcq4Pzk5 aIyNFpdftITSmfQP256NuH9jL2L6MhVDk2Mdiojt8WBZniB8bWha7f2JOyf2BLO2 4b1jk301pAxAeFtWegfvbJgan36ofc/Hj7G/cuCPvlaYx04SZPCT4lKExvqLbRXg wS+jBZbv+vuuNhWDieuCAoN3EP0zU5PnOcu9vEO41Tdu9zp1AOc4N4PDPpSYlV/T dtaBcWJi+YbWH+/e7HAoD6zyZyyP0t9z//1nq2Cjj/8nKaXtP1ytOyHn8TkZ3DRu ugjWWU9WFqMivhCznunq6W42Z4Yt8wrYwGt++NR9x5K0/t33I0TFrZ1tTj3ATU7l iUFQli2SwFrTiaJ8jdZgrmpou+CqkOz+yD94XZK568Hvt5rwo3u+iEmR6IttZUYS yBRkyhFCDcnEmdkArMkvsTlqapx1VeWGnCNRYWHhidKi+pbW+tJ8pVwuQ3G1BoVz eOkcbg6caywoyMWVIKTEqf9ozNPrcrUYLMuRABBO6nUkppACAIzpqLQ8LYmpIBAE FRAEwbASwQmCwFSwgpIgJarW6inTUfUakiTVOAJTMkJoNCSuAmVSQCqHUdwTec4X tRrHVEpYqaKMIg9OqNVqAvcgh9RoczUkgSKeGMUlRKWkBqpQah6Gzkko/oJjOE7g L2FFAc2DM8zTjHoZDKsw4vlEDwyRF5xUKZVUj7lagsCxOfYR/wHwfuhW/AUAAA== } insert port: open sound:// my-sound wait port close port Here's a version of the "Catch Game" above that replaces buttons with graphics, and adds a sound effect. You can create any game initially this way, simply using buttons, and later replace the buttons with more interesting graphic images, add sounds, etc. (paste/F5): REBOL [title: "Feed The Gator"] bird: load to-binary decompress 64#{ eJzF2LuL4kAcwHG3shBURHDRRW3E+wuuPOEaC9lGC60EXyCClQjiM4qdzVWWVjYW iiA2Cj7wPOzEThALG7HYRixF737EU/bMTTLGzOQLgxCTyaeYxMTv77/0CravML7A +AbjDcaL4pXd/gO+/6m+jGu/n6vRaDAMY7fbTSaTzWa7zOn3+xm2zWbz5Pw8fSzF HTcajYLBoAIjn8/XbDalVV963J5KpXDIdwUCgV6vJ6tdhPour9crh/15+K1QKDSZ TER4t9ttsVhUsJcpnr3b7UoI/1wsFiuVSsw12HI+nz+fulAoVCoV7oF49sFgQAjO TaVSwRmPxyOQjUYjz54Oh0PIPh6PqcGhVqsluI/Vak2n08PhkNc+nU4pePGDlb5e r288tL3f78tt/ZtGo8lkMlwh2q5Wq4WnJZZSqYRreLnkWxYIuyyrJZFIZLPZxWLB 48WwwzQ01ZFIBNMrZJ/NZtTUuVxOhBpt12q1FNSwLEWrEXZYbqTVtVrtSTXCbjab yanhuV4S9b/21Wp1OBzIwaPRaKfTkRDO2vP5PCHvrWQyKa36aj+dToTIHo+n3W6T UF/tl09425TEa7FYnE4nPCuRI3PskF6vF4F1u93lchmwu92Oghdhh3Q63UNwae8b j8a5RxoMBkx4vV6XhXzrf7+rOPBqtUofexfiWSwcDvPAKRtR8b43xePxO7XL5aJG Ewzvf4L9fg8v8fP5nDTnoT6WfwB19HCVxhQAAA== } alligator: load to-binary decompress 64#{ eJxd0s1KW0EUB3C1K+lDuHVjXWSnkAvuXfgCBRG7bBeFlormPkKXQhuaN9BNxYUm UxF00UUWhUoIcRQXoYTkUm7T8Tof/845Z0o/5nL43XPmn+HmJmvrzx7N8KrHWoy1 HGs71my8aC2mfVpzf25nAMQKaAe69zqZLbEu/8hWaf+31u+JlnM3NXtK6kt7xBrL OYVyTzSpNx0yQ3FA5iiekA3oV9Hg8had4x6yjHLefUKD9Ajk/RR4SvkN4Dnl5xEc 9Y9lH1fgPAxCEF0yXCcn/+77/3VJL1Zt0Y7/nv9AxZa5rchuZi3ZUiXPc2VO2IEp k4aeF4PhS3Y0pPxP3JU0vwFYYwHyHGIrQp4Npa8ugSJa7ou3x0A3erEKT71/I3O/ K3nnVxYMv78z7uHjL0YGmPei/sxq3EmPMply4O+D13Biwe8JL87RYJvicsewh40R +yHf7LDYYpuoXZMDv8p9L6g62beK8/1Ri/1itPTQnOsXb8XDrqgL+bwapr7kc3vw E+7Vw1eZhzXym/I75Ah2l1VY4bkWxxnekVOEC/J7Bj7nPkf6/4txRX8BGfoeSmYD AAA= } gulp-sound: load to-binary decompress 64#{ eJxtlHtMU1ccx6vGR3kWLMWpm5pskc2pi3MkqFNYJsh0oigV5KEULK2lpdDb9vbe 9r56W1pogSKltBQqSGGAlYeimAlDkU1H1KgssrhBmFNhjAECHcZl2bVo1LjfyTm/ nO/vdf45n9joyMjphTTaoQj2Tq4QWB1Io9HmUSt8Fc2z59GWUEp6KpB6k8pC3zJs 7nzTvXbB/sdhmMdjcx5744q9SkHf1l4f/LLhq+K33jZnOI6/3gZBVAjq8Qj6Mkzl ek5KwBEpL11saGyrANhx4kKHzUBgmFKhUKKIAgBAlNRqNaSayiO1pEqeLeTzxZjJ nA+KAK2ByBaidle1XoGVnrLjx3kSlULEOSaBIBmkMZkL9Lo8owYUZYqyRLwMMVJo NqgkoL7MQoqOiXUVzpPl1a7OiyXS6K2RBxJiE1KgitrTteYyq0ktStgbE3MwTUha 7BXFmDxHjpGITE5Unu++dLaupc2UFTLfd5PEZi8xObp7W/Ts8N3Jx3npXMjqarQA 8XFHpJBUeAwscNRZ8wwF1a7auvIzVWRCwCL/XY6B4c5CWGYol+8LWfk52X63t1Ka mnw0Izk+XkCcbDpVKueKUdvpRofVfulms3TlIh8mODQ7fjpx2359ERTFZB3u+Gt2 MH+zr8+mgwJMZ2/vajYeDt2aYr72U7eNUDf+es+yYQFzQcQvs+MTmQH0zaTTsued j/HHT2b6vloc6L0+71Z/hw2RykVHvt6bVtTZd+ecraCq3sT28fNnFD4bdQ/sWhwQ xHG14HH7iHtPpi6ELgn0CnFNTQybdwSviYLs39TYyqwN565cq+evoQctDvv+6cjT ns/ogQGH6r4tVwh0PWMjzq1egb5rqqfHJhq3+Pt9kOW61l2jh3TOG0Pt/BV01sL9 A+7H/5xi+TGWpl/pq0cScxruP2qI8g70W2Zxj7ovb/cJYCS0D49dMXC5up4H13OC vFkLEodnhv8t8WUE+AsHn9w27totPj94XbXCZ6l31uj45MOkJUz65tbJiZGahJ1p rv6fcZYXa/7eodlHtLplXqyFkXenJ7qSwz4VNlxuTlrK8NvYNDPqrl9LDcq4Pzk5 aIyNFpdftITSmfQP256NuH9jL2L6MhVDk2Mdiojt8WBZniB8bWha7f2JOyf2BLO2 4b1jk301pAxAeFtWegfvbJgan36ofc/Hj7G/cuCPvlaYx04SZPCT4lKExvqLbRXg wS+jBZbv+vuuNhWDieuCAoN3EP0zU5PnOcu9vEO41Tdu9zp1AOc4N4PDPpSYlV/T dtaBcWJi+YbWH+/e7HAoD6zyZyyP0t9z//1nq2Cjj/8nKaXtP1ytOyHn8TkZ3DRu ugjWWU9WFqMivhCznunq6W42Z4Yt8wrYwGt++NR9x5K0/t33I0TFrZ1tTj3ATU7l iUFQli2SwFrTiaJ8jdZgrmpou+CqkOz+yD94XZK568Hvt5rwo3u+iEmR6IttZUYS yBRkyhFCDcnEmdkArMkvsTlqapx1VeWGnCNRYWHhidKi+pbW+tJ8pVwuQ3G1BoVz eOkcbg6caywoyMWVIKTEqf9ozNPrcrUYLMuRABBO6nUkppACAIzpqLQ8LYmpIBAE FRAEwbASwQmCwFSwgpIgJarW6inTUfUakiTVOAJTMkJoNCSuAmVSQCqHUdwTec4X tRrHVEpYqaKMIg9OqNVqAvcgh9RoczUkgSKeGMUlRKWkBqpQah6Gzkko/oJjOE7g L2FFAc2DM8zTjHoZDKsw4vlEDwyRF5xUKZVUj7lagsCxOfYR/wHwfuhW/AUAAA== } alert "Arrow keys move left/right, up goes faster, down goes slower" random/seed now/time speed: 9 score: 0 view center-face layout [ size 600x440 backdrop white across at 270x0 text "Score:" t: text bold 100 (form score) at 280x20 y: image bird at 280x340 z: image alligator key keycode [left] [z/offset: z/offset - 10x0 show z] key keycode [right] [z/offset: z/offset + 10x0 show z] key keycode [up] [speed: speed + 1] key keycode [down] [if speed > 1 [speed: speed - 1]] box 0x0 rate 0 feel [engage: func [f a e] [if a = 'time [ y/offset: y/offset + (as-pair 0 speed) show y if y/offset/2 > 440 [ y/offset: as-pair (random 550) 20 show y score: score - 1 ] if within? z/offset (y/offset - 50x0) 100x20 [ y/offset: as-pair (random 550) 20 show y score: score + 1 insert port: open sound:// gulp-sound wait port close port ] t/text: (form score) show t ]]] ] This game contains some GUI layout parameters that make the widgets squeeze together, without any space in between ("origin 0x0" and "space 0x0"). It also uses the "style" word to define a completely new widget called "piece". Every time a "piece" widget is added to the GUI, it performs all the actions in the piece's style definition (in this example, "piece" is a 60x60 button that performs a number of offset calculations). You could make this program much more interesting by using images instead of buttons - give it a try if you really want to learn! (paste/F5): REBOL [title: "Sliding Puzzle"] view center-face layout [ origin 0x0 space 0x0 across style piece button 60x60 [ if not find [0x60 60x0 0x-60 -60x0] (face/offset - empty/offset) [ exit ] temp: face/offset face/offset: empty/offset empty/offset: temp ] piece "1" piece "2" piece "3" piece "4" return piece "5" piece "6" piece "7" piece "8" return piece "9" piece "10" piece "11" piece "12" return piece "13" piece "14" piece "15" empty: piece 200.200.200 edge [size: 0] ] This shooting game contains a text widget labeled "info". That widget displays text that is joined together ("concatenated) using the "rejoin" function. The entire game is also wrapped in square brackets, and labeled "game". When the screen needs to be refeshed, the entire GUI is simply "unview"ed, and the game code is done again (paste/F5): REBOL [title: "Shooter"] score: 0 speed: 10 lives: 5 fire: false random/seed now/time alert "[SPACE BAR: fire] | [Arrows: move left/right]" do game: [ view center-face layout [ size 600x440 backdrop black at 246x0 info: text tan rejoin ["Score: " score " Lives: " lives] at 280x440 x: box 2x20 yellow at (as-pair -50 (random 300) + 30) y: btn 50x20 orange at 280x420 z: btn 50x20 blue key keycode [right] [z/offset: z/offset + 10x0 show z] key keycode [left] [z/offset: z/offset + -10x0 show z] key keycode #" " [ if fire = false [ fire: true x/offset: as-pair (z/offset/1 + 25) 440 ] ] box 0x0 rate speed feel [engage: func [f a e] [if a = 'time [ if fire = true [x/offset: x/offset + 0x-30] if x/offset/2 < 0 [x/offset/2: 440 fire: false] show x y/offset: y/offset + as-pair ((random 20) - 5) ((random 10) - 5) if y/offset/1 > 600 [ lives: lives - 1 if lives = 0 [ alert join "GAME OVER!!! Final Score: " score quit ] alert "-1 Life!" unview do game ] show y if within? x/offset (y/offset - 5x5) 60x30 [ alert "Ka-blammmm!!!" score: score + 1 speed: speed + 5 fire: false unview do game ] ]]] ] ] The following game of "Collect the Boxes" starts by setting some word labels ("variables"). The word "start-time" is set to hold the time at which the program was begun (you can always get the current time using "now/time"). Next, the "level" word is set to hold a number requested from the user. Then the word "gui" is set to hold a layout block of GUI widgets. Inside the repeating loop in the GUI, a "foreach" loop is used to perform several "if" calculations on each widget in the GUI (the list of current GUI widgets is held in "system/view/screen-face/pane/1/pane"). The first "if" in the foreach loop removes any boxes from the GUI which the player's piece is touching. The second "if" ends the game when all the small boxes have been removed from the GUI. Before actually viewing the GUI block, a collection of buttons is added to the block, using a "for" loop. The for loop repeats the number of times held in the "level" variable, each time appending a box with a random position and color. Finally, the player's piece (a 20x20 red button) is added to the GUI layout, and the window is shown using "view layout". Try to collect the boxes as quickly as possible!: REBOL [Title: "Collect the Boxes"] random/seed now start-time: now/time level: to-integer request-text/title/default "Number of Boxes?" "10" gui: [ size 600x440 backdrop white at -99x0 key keycode [up] [p/offset: p/offset + 0x-10 show p] at -99x0 key keycode [down] [p/offset: p/offset + 0x10 show p] at -99x0 key keycode [left] [p/offset: p/offset + -10x0 show p] at -99x0 key keycode [right] [p/offset: p/offset + 10x0 show p] at -99x0 box rate 0 feel [engage: func [f a e][if a = 'time [ foreach f system/view/screen-face/pane/1/pane [ if f <> p [ if within? (f/offset + 10x10) p/offset 30x30 [ remove find system/view/screen-face/pane/1/pane f show system/view/screen-face/pane/1/pane ] ] if (length? system/view/screen-face/pane/1/pane) < 8 [ alert rejoin ["Your time: " now/time - start-time] quit ] ] ]]] ] for counter 1 level 1 [ append gui [at random 590x420 box 10x10 random 255.255.255] ] append gui [p: btn red 20x20] view center-face layout gui This game uses REBOL's "draw" dialect. It's a bit beyond the scope of this tutorial, but a nice preview of things you can focus on learning next (paste/F5): REBOL [title: "Little 3D Game"] beep-sound: load to-binary decompress 64#{ eJwBUQKu/VJJRkZJAgAAV0FWRWZtdCAQAAAAAQABABErAAARKwAAAQAIAGRhdGEl AgAA0d3f1cGadFQ+T2Z9jn1lSjM8T2uNsM/j7Midc05PWGh4eXVrXE5DQEZumsTn 4M2yk3hiVU9fcX+GcFU8KkNmj7rR3+HYroJbPUpfdoqAbldBP0ZWbpW62OvRrohk WlleaHB2dW9bRzo1WYWy3OHbyrKObVNCVGp/jXpgRC48Vnievtfm6MCUaUVLWW1/ fXNkUkdCRlN7ps3r3cSkgm1fWFhmdH2AaVA6LElwnMja4dzNpHtXPUxje45/aVA5 PUtif6TG3uvMpHtXU1lkcnd2cGVURT0+ZJC84+HUvaGCZ1NIWm6AinVaQCtAX4Wu yt3k37aJYEBKXXOHf3FdSEJET2KJsdPr1reUcGJbW2FsdXl2YUs5MFF7qdPe3tO+ mHNUP1Bnfo59ZEkyPFFukbTR5OvGm3BMTVlpent1aVpMQ0FJcZ3I6uHMsJB2YlZR YXJ/hW5UOypEaJK90+Dg1qyBWjxKYHeLgG1WPz9HWXKYvNnr0KyFYVhZX2pydnVu Wkc7N1yHtN3h2sivjGxTRFZrgI15X0MtPVh7osHZ5ua+kmdES1tvgn5zY1BGQ0hW fqjO69vBoX9rXllaaHV9fmhPOi1Lcp/K2+DayaF4Vj1NY3uNfmhONjxLZIKnyODr yqJ4VFFYZHN3dm5iUUM9QGaTv+Th0rqdf2VTSltvgIl0WT4rQGCIssze5N60iF8/ Sl10h39vW0ZBRFFljLPU69W1kG1gWlxiYHkWb1ECAAA= } alert { Try to click the bouncing REBOLs as many times as possible in 30 seconds. The speed increases with each click! } do game: [ speaker: open sound:// g: 12 i: 5 h: i * g j: negate h x: y: z: w: sc: 0 v2: v1: 1 o: now img1: to-image layout [backcolor brown box red center logo.gif] img2: to-image layout [backcolor aqua box yellow center logo.gif] img3: to-image layout [backcolor green box tan center logo.gif] cube: [[h h j][h h h][h j j][h j h][j h j][j h h][j j j][j j h]] view center-face layout/tight [ f: box white 550x550 rate 15 feel [engage: func [f a e] [ if a = 'time [ b: copy [] x: x + 3 y: y + 3 ; z: z + 3 repeat n 8 [ if w > 500 [v1: 0] if w < 50 [v1: 1] either v1 = 1 [w: w + 1] [w: w - 1] if j > (g * i * 1.4) [v2: 0] if j < 1 [v2: 1] either v2 = 1 [h: h - 1] [h: h + 1] j: negate h p: reduce pick cube n zx: p/1 * cosine z - (p/2 * sine z) - p/1 zy: p/1 * sine z + (p/2 * cosine z) - p/2 yx: (p/1 + zx * cosine y) - (p/3 * sine y) - p/1 - zx yz: (p/1 + zx * sine y) + (p/3 * cosine y) - p/3 xy: (p/2 + zy * cosine x) - (p/3 + yz * sine x) - p/2 - zy append b as-pair (p/1 + yx + zx + w) (p/2 + zy + xy + w) ] f/effect: [draw [ image img1 b/6 b/2 b/4 b/8 image img2 b/6 b/5 b/1 b/2 image img3 b/1 b/5 b/7 b/3 ]] show f if now/time - o/time > :00:20 [ close speaker either true = request [ join "Time's Up! Final Score: " sc "Again" "Quit" ] [do game] [quit] ] ] if a = 'down [ xblock: copy [] yblock: copy [] repeat n 8 [ append xblock first pick b n append yblock second pick b n ] if all [ e/offset/1 >= first minimum-of xblock e/offset/1 <= first maximum-of xblock e/offset/2 >= first minimum-of yblock e/offset/2 <= first maximum-of yblock ][ insert speaker beep-sound wait speaker sc: sc + 1 t1/text: join "Score: " sc show t1 if (modulo sc 3) = 0 [f/rate: f/rate + 1] show f ] ] ]] at 200x0 t1: text brown "Click the bouncing REBOLs!" ] ] There a number of additional games, and many more programming concepts and techniques explained in far greater detail, in the tutorial at http://re-bol.com. Read through that tutorial, and you'll learn to accomplish just about every other type of programming task you can imagine! |
![]() | MakeDoc2 by REBOL - 25-May-2010 |