Intro to programming games with clojure

58
Intro to Programming Games with Clojure Julio Barros E-String.com 1 / 57

Transcript of Intro to programming games with clojure

Page 1: Intro to programming games with clojure

Intro to Programming Gameswith Clojure

Julio Barros

E-String.com

1 / 57

Page 2: Intro to programming games with clojure

We are all here to learn

No mistakes. Learningopportunities.

Learn from each other

2 / 57

Page 3: Intro to programming games with clojure

"Give a person an app, frustratethem for a day. Teach a person to

code, frustrate them for alifetime."

-- Someone Internet Famous

3 / 57

Page 4: Intro to programming games with clojure

Agenda

1. Introduce the game

2. Hands-on modifications

3. Game and Clojure concepts

4. Questions and experiments

4 / 57

Page 5: Intro to programming games with clojure

Before

5 / 57

Page 6: Intro to programming games with clojure

After

6 / 57

Page 7: Intro to programming games with clojure

AboutJulio Barros / @JulioBarros

Assistants: Jed, Justin and Nuatu

Thank: Maureen Dugan & Jennifer / Epicodus

7 / 57

Page 8: Intro to programming games with clojure

Creating a game1. Double click nightcode-0.4.2-standalone.jar2. Create an game using the Arcade Template named PDXvsSEA3. Play it

8 / 57

Page 9: Intro to programming games with clojure

Resources1. Download http://bit.ly/intro-game-clojure2. Copy files from Downloads/intro-game-clojure/resources into your-

home/Nightmod/pdxvssea

9 / 57

Page 10: Intro to programming games with clojure

Our first mod

10 / 57

Page 11: Intro to programming games with clojure

Change Player

1. Open core.clj go to line 25.

2. Change "player.png" to "tram.png"

3. Save the file

(defscreen main-screen

:on-show

(fn [screen entities]

(update! screen :renderer (stage) :camera (orthographic)) (add-timer! screen :spawn-enemy 0 2)

(assoc (texture "player.png") ;; make this "tram.png"

:player? true

:x (/ (game :width) 2)

:y 10

:width 64

:height 64))

11 / 57

Page 12: Intro to programming games with clojure

Change the enemy

1. Open entities.clj

2. Go to line 57

3. Change "enemy.png" to "needle.png"

(defn create-enemy

"Returns an enemy at a random position."

[]

(assoc (texture "enemy.png") ;; make this "needle.png"

:enemy? true

:x (rand (game :width))

:y (game :height)

:width 6 4

:height 64))

12 / 57

Page 13: Intro to programming games with clojure

Change the missileStarts on line 24 in entities.clj

(defn create-missile "Returns a missile at the same x position as the mouse." [] (assoc (shape :filled :set-color (color :blue) ;; make :red :circle 0 0 10) ;; :ellipse 0 0 10 50 :missile? true :x (game :x) :y 50 ;; make 70 :width 10 :height 10)) ;; make 50

13 / 57

Page 14: Intro to programming games with clojure

Play a sound when the missilefires(defn create-missile "Returns a missile at the same x position as the mouse." [] (sound "laser.wav" :play) ;; Add this (assoc (shape :filled :set-color (color :red) :ellipse 0 0 10 70) :missile? true :x (game :x) :y 70 :width 20 :height 70))

14 / 57

Page 15: Intro to programming games with clojure

Play background music

Back in core.clj around line 21

(defscreen main-screen

:on-show

(fn [screen entities]

(sound "music.wav" :loop) ;; Add this

(update! screen :renderer (stage) :camera (orthographic)) (add-timer! screen :spawn-enemy 0 2)

(assoc (texture "tram.png")

:player? true

:x (/ (game :width) 2)

:y 10

:width 64

:height 64))

...

*Originally called http://ccmixter.org/files/djlang59/37792

15 / 57

Page 16: Intro to programming games with clojure

Silence the background music(defscreen main-screen :on-show (fn [screen entities] ;; (sound "music.wav" :loop) (update! screen :renderer (stage) :camera (orthographic)) (add-timer! screen :spawn-enemy 0 2) (assoc (texture "tram.png") :player? true :x (/ (game :width) 2) :y 10 :width 64 :height 64)) ...

16 / 57

Page 17: Intro to programming games with clojure

Games1) Setup

2) Loop

17 / 57

Page 18: Intro to programming games with clojure

Setupcore.clj line 20

(defscreen main-screen :on-show (fn [screen entities] (update! screen :renderer (stage) :camera (orthographic)) (add-timer! screen :spawn-enemy 0 2) (assoc (texture "tram.png") :player? true :x (/ (game :width) 2) :y 10 :width 64 :height 64))...

18 / 57

Page 19: Intro to programming games with clojure

Game space

19 / 57

Page 20: Intro to programming games with clojure

Game loops are like flip books

20 / 57

Page 21: Intro to programming games with clojure

The game loop - Hollywood

principle

Don't call us we'll call you.

Every time its time to draw a new screen :on-render (line 32) is called

:on-render

(fn [screen entities]

(clear!)

(->> entities

(move-missiles)

(move-enemies)

(update-score!)

(remove-missiles)

(remove-enemies)

(remove :remove?)

(render! screen)))

21 / 57

Page 22: Intro to programming games with clojure

Move missilesentities.clj line 37

(defn move-missiles "Moves the missiles up." [entities] (for [e entities] (if (:missile? e) (assoc e :y (+ (:y e) 5)) e)))

22 / 57

Page 23: Intro to programming games with clojure

Move enemiesentities.clj line 65

(defn move-enemies "Moves the enemies down." [entities] (for [e entities] (if (:enemy? e) (assoc e :y (- (:y e) 3)) e)))

23 / 57

Page 24: Intro to programming games with clojure

Clojure Maps - A little bundle of

information

Other languages call them hash maps, hash or dictionary.

Maps associate keys and values.

Curly braces, {}, denote maps.

;; a map or record for a person

{:first-name "Julio"

:last-name "Barros"

:age 29}

;; a map for a game entity

{:texture-info "some stuff the system builds for us"

:missile? true :x 23

:y 30

:color :red}

24 / 57

Page 25: Intro to programming games with clojure

The REPL

Open the repl and type (+ 2 4) and {:name "your name here"}

25 / 57

Page 26: Intro to programming games with clojure

assocAssociates (adds or updates) a key and value in one map creating a new map.

(assoc {:name "Julio" } :loves "Clojure")

;; results in - ie outputs

{ :name "Julio" :loves "Clojure"}

(assoc {:x 10, :color :red} :x 11);; results in

{ :color :red :x 11}

26 / 57

Page 27: Intro to programming games with clojure

Getting values from a map(get {:y "because"} :y) ;; gets the value of y

(:y {:y "because"}) ;; same thing just shorter

({:y "because"} :y) ;; this works too

27 / 57

Page 28: Intro to programming games with clojure

What's with all those round ()things?Parentheses (round braces) denote lists. Lists are a sequence of things.

The special thing about lists is that usually the first item is executed.

(action argument1 argument2)

(function parameter1 parameter2)

(+ 3 4)

(assoc e :x 33)(assoc {:x 22, :color :red} :x 33)

quote or ' keeps the list from being executed

'(1 2 3) ;; [1 2 3] more common

28 / 57

Page 29: Intro to programming games with clojure

What's up with the square []things?Square brackets, [] denote a vector (array). Vectors are also a sequence.

[1 2 3][1 2 [3 4]]

(count [5 5 5])=> 3

(get [1 2 3] 1) ;; Note: zero based.=> 2

You can have any length vector (or list) made up of any "type"

[3 {:name "Joe"} [1 2 3] '(1 2 [3 5])]'(3 {:name "Joe"} [1 2 3] '(1 2 [3 5]))

29 / 57

Page 30: Intro to programming games with clojure

Other interesting types

"I'm a string" ;; strings

:name ;; keyword

3 ;; integer

3.0 ;; double

;; Note: 3.0 is different than "3.0"

0.5 ;; must start with a number

{} ;; map

[] ;; vectors

() ;; lists

#{} ;; set - unordered collection with no duplicates

30 / 57

Page 31: Intro to programming games with clojure

if(if (some-test) (if-true-return-this) (if-not-true-return-this))

(if true "Told you so" "Never mind")=> "Told you so"

(if (= 1 2) "Told you so" "Never mind")=> "Never mind"

(if (even? x) x (+ x 1))

31 / 57

Page 32: Intro to programming games with clojure

forWalks through vector/sequence giving each element the name "e" and using it in the stepsthat follow.

"e" can be any name.

Returns a vector.

(for [e [1 2 3]] (+ e e))

=> (2 4 6)

(for [current-n [1 2 3]] (even? current-n))

=> (false true false)

(for [e entities] (if (:missile? e) (assoc e :y (+ (:y e) 5)) e))

32 / 57

Page 33: Intro to programming games with clojure

FunctionsTakes zero or more input parameters and returns a single value.

The return value could be a list or map or vectors of multiple things.

Returns the result of the last expression executed.

(defn my-function-name "A documentation string" [param1 param2] (functionA param1) (functionB param1 param2))

(defn increment "Adds one to the parameter" [a-number] (+ 1 a-number))

(increment 3)=> 4

33 / 57

Page 34: Intro to programming games with clojure

Move enemies(defn move-enemies "Moves the enemies down." [entities] (for [e entities] (if (:enemy? e) (assoc e :y (- (:y e) 3)) e)))

(move-enemies [{:enemy? true :y 100} {:enemy? false :y 25} {:missile? true :y 50}])

=> ({:y 97, :enemy? true} {:y 25, :enemy? false} {:y 50, :missile? true})

34 / 57

Page 35: Intro to programming games with clojure

Create an enemy(defn create-enemy "Returns an enemy at a random position." [] (assoc (texture "needle.png") :enemy? true :x (rand (game :width)) :y (game :height) :width 64 :height 64))

(create-enemy)

{:object "... some stuff about com.badlogic.gdx.graphics.g2d.TextureRegion" :height 64, :width 64, :y 965, :x 173.37581878372418, :enemy? true}

35 / 57

Page 36: Intro to programming games with clojure

Random numbersRandom numbers are super useful in games.

(rand-int n) returns a random integer between 0 (inclusive) and n (exclusive).

(rand-int 10)=> 3 ;; or 0 or 1 or 2 .. or 9

36 / 57

Page 37: Intro to programming games with clojure

Exercise: Our own Function -choose-oneWrite a function called choose-one that randomly chooses one element from a vector(choose-one [3 6]) chooses either 3 or 6 randomly. Put the function at the top of entities.clj

Things to think about:

1. How do you know how many things are in the vector?2. How do you pick an index between 0 and the last index in the vector?3. How do you get the item in the vector at that index?

37 / 57

Page 38: Intro to programming games with clojure

Step 1Figure out how many things we have to choose from.

38 / 57

Page 39: Intro to programming games with clojure

Step 1Figure out how many things we have to choose from.

(defn choose-one "Pick and return one thing from v. Well just the number of things in v." [v] (count v))

39 / 57

Page 40: Intro to programming games with clojure

Step 2Pick a random index - a number from 0 to the number of things we have to choose from.

40 / 57

Page 41: Intro to programming games with clojure

Step 2Pick a random index - a number from 0 to the number of things we have to choose from.

(defn choose-one "Pick and return one thing from v. Well a random valid index into v." [v] (rand-int (count v)))

41 / 57

Page 42: Intro to programming games with clojure

Step 3Get the item at that index in the vector.

42 / 57

Page 43: Intro to programming games with clojure

A solutionGet the item at that index in the vector

(defn choose-one "Pick and return one thing from v." [v] (get v (rand-int (count v))))

43 / 57

Page 44: Intro to programming games with clojure

Use choose-one to pick differentenemies(defn create-enemy "Returns an enemy at a random position." [] (assoc (texture (choose-one ["enemy.png","needle.png"])) :enemy? true :x (rand (game :width)) :y (game :height) :width 6 4 :height 64))

44 / 57

Page 45: Intro to programming games with clojure

Exercise: one-inWrite a function called one-in that takes a number, n, and returns true 1 in n times. (one-in5) returns true ~20% (1 in 5) of the time

Use it to create an old style enemy 1 out of 10 times.

Can you use choose-one to do the same thing?

45 / 57

Page 46: Intro to programming games with clojure

Back to the game loop

Every function takes a list of entities and returns a list of entities.

May be the same list. More likely a new list made from the old list with a few changes.

(->> entities

(move-missiles)

(move-enemies)

(update-score!)

(remove-missiles) ;; mark missiles for removal

(remove-enemies) ;; mark enemies for removal

(remove :remove?) ;; actually do the remove

(render! screen)))

The remove step logic is a little tricky.

Homework: Study it to see if you can figure out how it works.

46 / 57

Page 47: Intro to programming games with clojure

Wrap up

47 / 57

Page 48: Intro to programming games with clojure

Programmable Music - Sonic Pihttp://sonic-pi.net

http://vimeo.com/113811476

48 / 57

Page 49: Intro to programming games with clojure

Today's Parts ReviewClojure - Modern LISP targeting the Java Virtual Machine (JVM). http://clojure.org

Java / JVM - Mature enterprise programming language and the system that runs it.https://www.java.com/

Nightmod - Tool for making live-moddable games using Clojure and play-clj.https://nightmod.net

play-clj - Clojure game library that uses libGDX. https://github.com/oakes/play-clj

libGDX - Game development framework written in Java. http://libgdx.badlogicgames.com

49 / 57

Page 50: Intro to programming games with clojure

Clojure ResourcesClojure Cheat Sheet

http://clojure.org/cheatsheet

Clojure From The Ground Up

https://aphyr.com/tags/Clojure-from-the-ground-up

Clojure For the brave and true

http://www.braveclojure.com

ClojureBridge

https://github.com/ClojureBridge/curriculum

Nightmod / Nightcode - thank Zach

https://nightmod.net

Emacs, Clojure Cursive, LightTable - other environments (IDEs).

50 / 57

Page 51: Intro to programming games with clojure

Other popular languages

Javascript - Runs in the browser.

ClojureScript - Clojure for Javascript.

Ruby - Popular language with startups.

Python - Popular for data science.

Many many more.

Find one you (and your friends) like and form a

study group.

51 / 57

Page 52: Intro to programming games with clojure

Programming ResourcesEpicodus - https://www.epicodus.com

Meetup.com

Clojure - http://www.meetup.com/clojerks/

Python - http://www.meetup.com/pdxpython/

PyLadies - http://www.meetup.com/PyLadies-PDX/

Ruby Brigade - http://pdxruby.org

Portland Indie Game Squad (PIGSquad) - http://pigsquad.com

Portland Tech Calendar - http://calagator.org

52 / 57

Page 53: Intro to programming games with clojure

Games Resources

Cocos2D - http://cocos2d.org

For JavaScript, C++, Python, Swift, ...

GameKit - iOS/MacOS only

Unity, LibGDX - http://en.wikipedia.org/wiki/List_of_game_engines

Portland Indie Game Squad (PIGSquad) - http://pigsquad.com

53 / 57

Page 54: Intro to programming games with clojure

Questions?

54 / 57

Page 55: Intro to programming games with clojure

Thank You

Julio Barros - http://twitter.com/JulioBarros

Justin Holguin

Jed Clinger

Nuatu Tseggai

55 / 57

Page 56: Intro to programming games with clojure

Feedback

1. What went well?

2. What can be improved?

3. How do we reach more people?

56 / 57

Page 57: Intro to programming games with clojure

Exercise: Better Motion1) Make the enemies drift to the right as they fall.

2) Make some enemies go much faster than other enemies

3) Make enemies zig zag in a smooth(ish) manner as they fall.

57 / 57

Page 58: Intro to programming games with clojure