KEMBAR78
Intro to programming games with clojure | PDF
Intro to Programming Games
with Clojure
Julio Barros
E-String.com
1 / 57
We are all here to learn
No mistakes. Learning
opportunities.
Learn from each other
2 / 57
"Give a person an app, frustrate
them for a day. Teach a person to
code, frustrate them for a
lifetime."
-- Someone Internet Famous
3 / 57
Agenda
1. Introduce the game
2. Hands-on modifications
3. Game and Clojure concepts
4. Questions and experiments
4 / 57
Before
5 / 57
After
6 / 57
About
Julio Barros / @JulioBarros
Assistants: Jed, Justin and Nuatu
Thank: Maureen Dugan & Jennifer / Epicodus
7 / 57
Creating a game
1. Double click nightcode-0.4.2-standalone.jar
2. Create an game using the Arcade Template named PDXvsSEA
3. Play it
8 / 57
Resources
1. Download http://bit.ly/intro-game-clojure
2. Copy files from Downloads/intro-game-clojure/resources into your-
home/Nightmod/pdxvssea
9 / 57
Our first mod
10 / 57
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
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
Change the missile
Starts 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
Play a sound when the missile
fires
(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
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
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
Games
1) Setup
2) Loop
17 / 57
Setup
core.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
Game space
19 / 57
Game loops are like flip books
20 / 57
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
Move missiles
entities.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
Move enemies
entities.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
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
The REPL
Open the repl and type (+ 2 4) and {:name "your name here"}
25 / 57
assoc
Associates (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
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
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
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
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
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
for
Walks through vector/sequence giving each element the name "e" and using it in the steps
that 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
Functions
Takes 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
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
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
Random numbers
Random 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
Exercise: Our own Function -
choose-one
Write 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
Step 1
Figure out how many things we have to choose from.
38 / 57
Step 1
Figure 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
Step 2
Pick a random index - a number from 0 to the number of things we have to choose from.
40 / 57
Step 2
Pick 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
Step 3
Get the item at that index in the vector.
42 / 57
A solution
Get 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
Use choose-one to pick different
enemies
(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
Exercise: one-in
Write a function called one-in that takes a number, n, and returns true 1 in n times. (one-in
5) 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
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
Wrap up
47 / 57
Programmable Music - Sonic Pi
http://sonic-pi.net
http://vimeo.com/113811476
48 / 57
Today's Parts Review
Clojure - 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
Clojure Resources
Clojure 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
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
Programming Resources
Epicodus - 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
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
Questions?
54 / 57
Thank You
Julio Barros - http://twitter.com/JulioBarros
Justin Holguin
Jed Clinger
Nuatu Tseggai
55 / 57
Feedback
1. What went well?
2. What can be improved?
3. How do we reach more people?
56 / 57
Exercise: Better Motion
1) 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
Intro to programming games with clojure

Intro to programming games with clojure

  • 1.
    Intro to ProgrammingGames with Clojure Julio Barros E-String.com 1 / 57
  • 2.
    We are allhere to learn No mistakes. Learning opportunities. Learn from each other 2 / 57
  • 3.
    "Give a personan app, frustrate them for a day. Teach a person to code, frustrate them for a lifetime." -- Someone Internet Famous 3 / 57
  • 4.
    Agenda 1. Introduce thegame 2. Hands-on modifications 3. Game and Clojure concepts 4. Questions and experiments 4 / 57
  • 5.
  • 6.
  • 7.
    About Julio Barros /@JulioBarros Assistants: Jed, Justin and Nuatu Thank: Maureen Dugan & Jennifer / Epicodus 7 / 57
  • 8.
    Creating a game 1.Double click nightcode-0.4.2-standalone.jar 2. Create an game using the Arcade Template named PDXvsSEA 3. Play it 8 / 57
  • 9.
    Resources 1. Download http://bit.ly/intro-game-clojure 2.Copy files from Downloads/intro-game-clojure/resources into your- home/Nightmod/pdxvssea 9 / 57
  • 10.
  • 11.
    Change Player 1. Opencore.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
  • 12.
    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
  • 13.
    Change the missile Startson 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
  • 14.
    Play a soundwhen the missile fires (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
  • 15.
    Play background music Backin 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
  • 16.
    Silence the backgroundmusic (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
  • 17.
  • 18.
    Setup core.clj line 20 (defscreenmain-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
  • 19.
  • 20.
    Game loops arelike flip books 20 / 57
  • 21.
    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
  • 22.
    Move missiles entities.clj line37 (defn move-missiles "Moves the missiles up." [entities] (for [e entities] (if (:missile? e) (assoc e :y (+ (:y e) 5)) e))) 22 / 57
  • 23.
    Move enemies entities.clj line65 (defn move-enemies "Moves the enemies down." [entities] (for [e entities] (if (:enemy? e) (assoc e :y (- (:y e) 3)) e))) 23 / 57
  • 24.
    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
  • 25.
    The REPL Open therepl and type (+ 2 4) and {:name "your name here"} 25 / 57
  • 26.
    assoc Associates (adds orupdates) 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
  • 27.
    Getting values froma 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
  • 28.
    What's with allthose 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
  • 29.
    What's up withthe 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
  • 30.
    Other interesting types "I'ma 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
  • 31.
    if (if (some-test) (if-true-return-this) (if-not-true-return-this)) (if true "Toldyou so" "Never mind") => "Told you so" (if (= 1 2) "Told you so" "Never mind") => "Never mind" (if (even? x) x (+ x 1)) 31 / 57
  • 32.
    for Walks through vector/sequencegiving each element the name "e" and using it in the steps that 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
  • 33.
    Functions Takes zero ormore 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
  • 34.
    Move enemies (defn move-enemies "Movesthe 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
  • 35.
    Create an enemy (defncreate-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
  • 36.
    Random numbers Random numbersare 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
  • 37.
    Exercise: Our ownFunction - choose-one Write 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
  • 38.
    Step 1 Figure outhow many things we have to choose from. 38 / 57
  • 39.
    Step 1 Figure outhow 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
  • 40.
    Step 2 Pick arandom index - a number from 0 to the number of things we have to choose from. 40 / 57
  • 41.
    Step 2 Pick arandom 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
  • 42.
    Step 3 Get theitem at that index in the vector. 42 / 57
  • 43.
    A solution Get theitem 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
  • 44.
    Use choose-one topick different enemies (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
  • 45.
    Exercise: one-in Write afunction called one-in that takes a number, n, and returns true 1 in n times. (one-in 5) 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
  • 46.
    Back to thegame 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
  • 47.
  • 48.
    Programmable Music -Sonic Pi http://sonic-pi.net http://vimeo.com/113811476 48 / 57
  • 49.
    Today's Parts Review Clojure- 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
  • 50.
    Clojure Resources Clojure CheatSheet 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
  • 51.
    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
  • 52.
    Programming Resources Epicodus -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
  • 53.
    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
  • 54.
  • 55.
    Thank You Julio Barros- http://twitter.com/JulioBarros Justin Holguin Jed Clinger Nuatu Tseggai 55 / 57
  • 56.
    Feedback 1. What wentwell? 2. What can be improved? 3. How do we reach more people? 56 / 57
  • 57.
    Exercise: Better Motion 1)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