This is a quick guide that should introduce you to all the basic features of R-cade and (hopefully) allow you to start making your own game!
Once you feel you’ve seen enough of the tutorials, head over to the documentation page for a complete list of all functions provided by R-cade at your disposal.
This is about the simplest “game” that can be made in R-cade:
(require r-cade)
;; Our game loop. This function will be called once per frame by
;; the R-cade engine. Each frame it will clear video RAM and then
;; draw the current frame number at pixel (2,2).
(define (game-loop)
(cls)
(text 2 2 (frame)))
;; This will create an R-cade window, set the size of video RAM to
;; 128 x 128 pixels, and immediately start calling the our game
;; loop function at a rate of 60 times per second. It will keep
;; running until the window is closed.
(run game-loop 128 128)
R-cade provides functions for 9 keyboard “buttons”:
Each btn-*
function returns #f
if it is not currently pressed, otherwise it returns a number indicating how many frames it has been pressed for. Let’s try using them:
(require r-cade)
(require racket/match)
(define (test-button state btn x y)
(let ([state (match state
[#f "not pressed"]
[1 "just pressed"]
[n "pressed"])])
(text x y (format "~a is ~a" btn state))))
(define (game-loop)
(cls)
; test each button and show its current state
(test-button (btn-up) 'up 2 2)
(test-button (btn-down) 'down 2 9)
(test-button (btn-right) 'right 2 16)
(test-button (btn-left) 'left 2 23)
(test-button (btn-start) 'start 2 30)
(test-button (btn-select) 'select 2 37)
(test-button (btn-z) 'z 2 44)
(test-button (btn-x) 'x 2 51)
; quit when escape is pressed
(when (btn-quit)
(quit)))
(run game-loop 256 128)
Sometimes you may want to change which button does something, or how often it does it. For this reason, you can use the define-action
macro to create a simple herlper function that tests the state of a given input button.
(require r-cade)
;; (turn-right) will be true if btn-right is pressed
(define turn-right (action btn-right #t))
;; (jump) will be true only if btn-z was just pressed
(define jump (action btn-z))
;; (shoot) will be true 5 times per second as long as btn-x is pressed
(define shoot (action btn-x #t 5))
(define (game-loop)
(cls)
(when (turn-right)
(text 2 2 "Turn right!"))
(when (jump)
(text 2 9 "Jump!"))
(when (shoot)
(text 2 16 "Shoot!")))
(run game-loop 64 64)
In addition to the keyboard, the mouse is also managed. There is btn-mouse
which returns the state of the left mouse button, as well as mouse-x
and mouse-y
that return the current position of the mouse in pixels.
In addition to the cls
and text
functions you’ve already been introduced to, there are 4 additional drawing functions:
draw
line
rect
circle
The draw
function is the most common, and is how you draw sprites to video memory. You provide an x
and y
coordinate to draw at and a list of bytes. Each byte is just a series of 8-bits to draw. If a bit is set, the pixel is overwritten with the current color.
(require r-cade)
(define (game-loop)
(cls)
; draw a box with a redicule
(when (btn-z)
(let ([x (mouse-x)]
[y (mouse-y)])
(draw x y '(#b01111100
#b10000010
#b10010010
#b10111010
#b10010010
#b10000010
#b01111100)))))
(run game-loop 128 128)
NOTE: The most significant bit of each byte is drawn at x
. This is important, because if you’d like to draw a single pixel at (x,y)
, you need to draw #x80
or #b10000000
and not #x01
!
There are 16 colors available in the R-cade palette. All drawing operations (except for cls
) use the currently active color to draw. The active color is changed at any time with the color
function. It is also possible to change a color in the palette with the set-color!
function.
(require r-cade)
(define (game-loop)
(for ([i (range 16)])
(color i)
(draw 0 i '(#xff))))
(run game-loop 8 16)
There are 4 channels available for playing sounds. You needn’t manage them, but it does mean that more than 4 sounds cannot play at the same time.
Sounds are created using the sound
function, which is given a frequency curve function, a duration (in seconds), an optional instrument (wave function) and an optional amplitude envelope function. There are also several helper functions for creating sounds.
Once a sound has been created, it can be played on an available channel using the play-sound
function.
(require r-cade)
;; create a simple sound
(define boop (sweep 440 ; start frequency
300 ; end frequency
0.1 ; duration
(voice sawtooth-wave z-envelope)))
(define (do-boop)
(btn-z #t 3))
(define (game-loop)
(text 2 2 "Press Z to play the boop sound.")
(when (do-boop)
(play-sound boop)))
(run game-loop 128 128)
There is a single sound channel dedicated to playing music. Like sounds, you first create a musical tune using the music
function. Once you have a tune, you can play it with the play-music
function.
(require r-cade)
;; create a song
(define theme
(music "E4-B3C4D-CB3A-AC4E-DCB3-C4D-E-C-A3-A-.D4-FA-GFE-CE-DCB3-BC4D-E-C-A3-A-."
#:tempo 280))
(define (game-loop)
(text 2 2 "Playing the Tetris theme song.")
(wait)
(quit))
(define (start-music)
(play-music theme))
(run game-loop 128 128 #:init start-music)
NOTE: See the documentation for more details on the music
function and how to use it.
More tutorials will come as features are added. Until then, head over to the documentation page for a complete list of all functions and how to use them.