Games on Scheme(Lisp) in the DrRacket environment

this article uses the development environment DrRacket. To begin, consider the link state machine and the gaming process. The control object in the game can be represented in the form of a finite state machine. Consider a program that simulates a traffic light. This example was described in previous article.

The transition to the other stable state is to change the traffic signal. The state diagram can be represented as follows.

image

In order to create the traffic light, draw a circle in the center of a blank scene.

the
#lang racket
(require picturing-programs)
(define (DOT s) (circle 100 "solid" s))

s is the variable responsible for the color. The transition to a different state you can imagine
the following construction:

the
(define (traffic-light-next s)
(cond
[(string=? "red" s) "green"]
[(string=? "green" s) "yellow"]
[(string=? "yellow" s) "red"]))

In order to simulate the switching signal, use the function big-bang.

the
(big-bang "red"
[on-tick traffic-light-next 1]
[to-draw DOT]) 

Now the light moves to the next steady state is 1 times per second. Control effects in games can also provide the platforms, obstacles, enemies, etc. for Example, in some games the movement of the object may "jump" to the next one, i.e., close to the border of the canvas, the object disappears and reappears on the opposite border. The condition for the transition ("leap") is determined by comparing the coordinates of the object and the edges of the canvas.

the
 [(>(+x DELTA) WIDTH) 0]

If the condition is not fulfilled, remain on the same screen.

the
(cond
[(>(+x dx) WIDTH) 0]
[else (+ x dx)] )

Movement is determined by the DELTA increment to the x coordinate. Write a program in full:

the
#lang racket
(require 2htdp/image)
(require 2htdp/universe)
(define WIDTH 100)
(define DELTA 1)
(define BALL (circle 5 "solid" "red"))
(define MT (empty-scene WIDTH 10))
(define (main x0)
(big-bang x0
[to-draw render]
[on-tick bounce]))
(define (bounce x)
(cond
[(>(+x DELTA) WIDTH) 0]
[else (+ x DELTA)] ))
(define (render x)
(place-image BALL x 5 MT))
(main 50)

This examples of programs that use the big-bang. To run the program in the "Beginner student", adding the required packages.

Next, write a program in which the management of the facility is
keys "left" and "right".

Here we need a function for processing keys.

the
#lang racket
(require 2htdp/image)
(require 2htdp/universe)
(define BACKGROUND (empty-scene 100 100))
(define DOT (circle 10 "solid" "red"))
(define (place-dot-at x)
(place-image DOT x 50 BACKGROUND))
(define (change-func p k) ; processing keys
(cond
[(string=? "left" k)
(- p 5)]
[(string=? "right" k)
(+ p 5)]
[else p]))
( big-bang 50
[to-draw place-dot-at] 
[on-key change-func] )

If, however, we also need to handle key presses "up", "down", then the coordinates of the object should be stored in the structure like this:

the
(define-struct posn (x y))
(define INIT-WORLD (make-posn 100 100))

Write a program in which the object can move both horizontally and vertically.

the
#lang racket
(require picturing-programs) 
(define WIDTH 200)
(define HEIGHT 200)
(define BACKGROUND (empty-scene WIDTH HEIGHT))
(define obj1 (circle 10 "solid" "red"))
(define-struct posn (x y)) ;declare a structure
(define INIT-WORLD (make-posn 100 100) )
(define (change-current-world-key current-world a-key-event) ;handle "events" keyboard 
(cond
[(key=? a-key-event 'up')
(make-posn (posn-x current-world) (- (posn-y current-world) 5))]
[(key=? a-key-event "down")
(make-posn (posn-x current-world) (+ (posn-y current-world) 5))]
[(key=? a-key-event "left")
(make-posn (-(posn-x current-world)5) (posn-y current-world) )]
[(key=? a-key-event "right")
(make-posn (+(posn-x current-world)5) (posn-y current-world) )]
[else current-world]))
(define (redraw-current-world)
(place-image obj1
(posn-x current-world)
(posn-y current-world)
BACKGROUND))
(big-bang INIT-WORLD
(on-key change-current-world-key)
(on-redraw draw) )

Yes, but usually in games there are multiple features. Write a program that has two objects. We use two structures: world and posn.

the
#lang racket
(require picturing-programs) 
(define WIDTH 300)
(define HEIGHT 300)
(define BACKGROUND (empty-scene WIDTH HEIGHT))
(define obj1 (circle 10 "solid" "red"))
(define obj2 (circle 10 "solid" "green"))
(define-struct posn (x y))

; Initialization parameters in the structure of the world
(define INIT-WORLD (make-world (make-posn 100 100) (make-posn 200 100)))
(define (draw-game world)
(place-image 
obj1
(posn-x (world-obj1 world))
(posn-y (world-obj1 world))
(place-image 
obj2
(posn-x (world-obj2 world))
(posn-y (world-obj2 world))
BACKGROUND)))
(big-bang INIT-WORLD
[to-draw draw-game])

Now, in order to control one of the objects, add a processing function keys.

the
#lang racket
(require picturing-programs) 
(define WIDTH 300)
(define HEIGHT 300)
(define BACKGROUND (empty-scene WIDTH HEIGHT))
(define obj1 (circle 10 "solid" "red"))
(define obj2 (circle 10 "solid" "green"))
(define-struct posn (x y))
(define-struct world [obj1, obj2])
(define INIT-WORLD (make-world (make-posn 50 150) (make-posn 250 150)))
(define (change-current-world-key current-world a-key-event)
(make-world (change-obj1 (world-obj1 current-world) a-key-event)
(world-obj2 current-world)))
(define (change-arg1 a-posn a-key-event)
(cond
[(key=? a-key-event 'up')
(make-posn (posn-x a-posn) (- (posn-y a-posn) 5))]
[(key=? a-key-event "down")
(make-posn (posn-x a-posn) (+ (posn-y a-posn) 5))]
[(key=? a-key-event "left")
(make-posn (-(posn-x a-posn) 5) (posn-y a-posn) )]
[(key=? a-key-event "right")
(make-posn (+(posn-x a-posn)5) (posn-y a-posn) )]
[else a-posn]))
(define (draw-game world)
(place-image 
obj1
(posn-x (world-obj1 world))
(posn-y (world-obj1 world))
(place-image 
obj2
(posn-x (world-obj2 world))
(posn-y (world-obj2 world))
BACKGROUND)))
(big-bang INIT-WORLD
(on-key change-current-world-key)
[to-draw draw-game] )

Learn more about creating games can be found in the book How to Design Worlds.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

March Habrameeting in Kiev

PostgreSQL load testing using JMeter, Yandex.Tank and Overload

Monitoring PostgreSQL with Zabbix