Merge remote-tracking branch 'oakes/master'

This commit is contained in:
2015-02-20 11:33:32 -08:00
36 changed files with 389 additions and 216 deletions

View File

@@ -14,7 +14,7 @@ There are several different ways to create a project:
The best thing about making a game in Clojure is that you can modify it in a REPL while it's running. By simply reloading a namespace, your code will be injected into the game, uninhibited by the restrictions posed by tools like HotSwap. Additionally, a REPL lets you read and modify the _state_ of your game at runtime, so you can quickly experiment and diagnose problems.
Clojure also brings the benefits of functional programming. This is becoming a big topic of discussion in gamedev circles, including by [John Carmack](http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/). Part of this is due to the prevalence of multi-core hardware, making concurrency more important. Additionally, there is a general difficulty of maintaining object-oriented game codebases as they grow, due to complicated class hierarchies and state mutations.
Clojure also brings the benefits of functional programming. This is becoming a big topic of discussion in gamedev circles, including by [John Carmack](http://gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php). Part of this is due to the prevalence of multi-core hardware, making concurrency more important. Additionally, there is a general difficulty of maintaining object-oriented game codebases as they grow, due to complicated class hierarchies and state mutations.
## Documentation

View File

@@ -44,10 +44,10 @@ Right now, you're using the `play-clj.ui` library to display a label. This libra
[play-clj.g2d :refer :all]))
```
Now let's find an image to use as a texture in the game. Find one you'd like to use, such as [this Clojure logo](http://upload.wikimedia.org/wikipedia/commons/c/c5/Clojure-icon.gif), and save it to the `desktop/resources` folder. Next, simply change the line where the label entity is being created, so it creates a texture from that file instead:
Now let's find an image to use as a texture in the game. Find one you'd like to use, such as [this Clojure logo](http://upload.wikimedia.org/wikipedia/en/1/1d/Clojure_logo.gif), and save it to the `desktop/resources` folder. Next, simply change the line where the label entity is being created, so it creates a texture from that file instead:
```clojure
(texture "Clojure-icon.gif")
(texture "Clojure_logo.gif")
```
## Size and Position
@@ -61,14 +61,14 @@ If you run the code now, you'll see the image in the bottom-left corner. As ment
A `texture` contains the underlying Java object. By default, it will be drawn at the bottom-left corner with the size of the image itself. You can change the position and size by simply using `assoc`:
```clojure
(assoc (texture "Clojure-icon.gif")
(assoc (texture "Clojure_logo.gif")
:x 50 :y 50 :width 100 :height 100)
```
You can also set scaling and rotation on a texture using :scale-x, :scale-y, and :angle, which all use (:origin-x, :origin-y) as the center. For example, here we rotate it 45 degrees counter-clockwise around the bottom-left corner:
```clojure
(assoc (texture "Clojure-icon.gif")
(assoc (texture "Clojure_logo.gif")
:x 50 :y 50 :width 100 :height 100
:angle 45 :origin-x 0 :origin-y 0)
```
@@ -117,13 +117,13 @@ The [game](http://oakes.github.io/play-clj/core.game.html) function gives you co
:on-touch-down
(fn [screen entities]
(cond
(> (game :point-y) (* (game :height) (/ 2 3)))
(> (game :y) (* (game :height) (/ 2 3)))
(println "up")
(< (game :point-y) (/ (game :height) 3))
(< (game :y) (/ (game :height) 3))
(println "down")
(> (game :point-x) (* (game :width) (/ 2 3)))
(> (game :x) (* (game :width) (/ 2 3)))
(println "right")
(< (game :point-x) (/ (game :width) 3))
(< (game :x) (/ (game :width) 3))
(println "left")))
```
@@ -162,13 +162,13 @@ Now we can update our `:on-key-down` and `:on-touch-down` functions to move the
:on-touch-down
(fn [screen entities]
(cond
(> (game :point-y) (* (game :height) (/ 2 3)))
(> (game :y) (* (game :height) (/ 2 3)))
(move (first entities) :up)
(< (game :point-y) (/ (game :height) 3))
(< (game :y) (/ (game :height) 3))
(move (first entities) :down)
(> (game :point-x) (* (game :width) (/ 2 3)))
(> (game :x) (* (game :width) (/ 2 3)))
(move (first entities) :right)
(< (game :point-x) (/ (game :width) 3))
(< (game :x) (/ (game :width) 3))
(move (first entities) :left)))
```
@@ -252,13 +252,13 @@ At some point, you will need to do more than simple positioning and sizing. For
In play-clj, many different calls, such as `texture`, are actually macros that allow you to call the underlying Java methods after the required argument(s). In this case, the underlying class is called [TextureRegion](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureRegion.html). Consider this:
```clojure
(texture "Clojure-icon.gif" :flip true false)
(texture "Clojure_logo.gif" :flip true false)
```
...which is transformed into:
```clojure
(let [entity (texture "Clojure-icon.gif")]
(let [entity (texture "Clojure_logo.gif")]
(doto ^TextureRegion (:object entity)
(.flip true false))
entity)
@@ -267,7 +267,7 @@ In play-clj, many different calls, such as `texture`, are actually macros that a
You can even call multiple methods in the same expression this way. For example:
```clojure
(texture "Clojure-icon.gif"
(texture "Clojure_logo.gif"
:flip true false
:set-region 0 0 100 100)
```
@@ -275,10 +275,10 @@ You can even call multiple methods in the same expression this way. For example:
...which is transformed into:
```clojure
(let [entity (texture "Clojure-icon.gif")]
(let [entity (texture "Clojure_logo.gif")]
(doto ^TextureRegion (:object entity)
(.flip true false)
(.setRegion 0 0 100 100)
(.setRegion 0 0 100 100))
entity)
```

View File

@@ -1,9 +1,9 @@
{"Actor" {"actor!" :methods}
"ActorGestureListener" {"actor-gesture-listener!" :methods}
"Align" {"align" :static-fields}
"Align" {"align" :static-fields-camel}
"com.badlogic.gdx.graphics.g2d.Animation" {"animation" :methods
"animation!" :methods}
"Animation.PlayMode" {"play-mode" :static-fields}
"Animation.PlayMode" {"play-mode" :static-fields-upper}
"AnimationController" {"animation-controller" :methods
"animation-controller!" :methods}
"Application" {"app!" :methods}
@@ -19,7 +19,7 @@
"BitmapFont" {"bitmap-font" :methods
"bitmap-font!" :methods}
"BlendingAttribute" {"attribute :blending" :constructors
"attribute-type :blending" :static-fields
"attribute-type :blending" :static-fields-pascal
"attribute! :blending" :static-methods}
"Body" {"body!" :methods}
"BodyDef" {"body-def" :fields}
@@ -37,10 +37,10 @@
"CircleMapObject" {"map-object :circle" :methods}
"ChangeListener" {"change-listener!" :methods}
"ClickListener" {"click-listener!" :methods}
"Color" {"color" :static-fields
"Color" {"color" :static-fields-upper
"color!" :methods}
"ColorAttribute" {"attribute :color" :constructors
"attribute-type :color" :static-fields
"attribute-type :color" :static-fields-pascal
"attribute! :color" :static-methods}
"ConvexHull" {"convex-hull" :methods
"convex-hull!" :methods}
@@ -52,12 +52,12 @@
"CircleShape" {"circle-shape" :methods
"circle-shape!" :methods}
"CubemapAttribute" {"attribute :cubemap" :constructors
"attribute-type :cubemap" :static-fields
"attribute-type :cubemap" :static-fields-pascal
"attribute! :cubemap" :static-methods}
"DelaunayTriangulator" {"delaunay-triangulator" :methods
"delaunay-triangulator!" :methods}
"DepthTestAttribute" {"attribute :depth-test" :constructors
"attribute-type :depth-test" :static-fields
"attribute-type :depth-test" :static-fields-pascal
"attribute! :depth-test" :static-methods}
"Dialog" {"dialog" :methods
"dialog!" :methods}
@@ -76,7 +76,7 @@
"Fixture" {"fixture!" :methods}
"FixtureDef" {"fixture-def" :fields}
"FloatAttribute" {"attribute :float" :constructors
"attribute-type :float" :static-fields
"attribute-type :float" :static-fields-pascal
"attribute! :float" :static-methods}
"FloatCounter" {"float-counter" :methods
"float-counter!" :methods}
@@ -93,7 +93,7 @@
"GridPoint3" {"grid-point-3" :methods
"grid-point-3!" :methods}
"GL20" {"gl!" :methods
"gl" :static-fields}
"gl" :static-fields-upper}
"HexagonalTiledMapRenderer" {"hexagonal-tiled-map" :methods
"hexagonal-tiled-map!" :methods}
"HorizontalGroup" {"horizontal" :methods
@@ -107,15 +107,15 @@
"image-text-button!" :methods}
"ImageTextButton.ImageTextButtonStyle" {"style :image-text-button" :constructors}
"Input" {"input!" :methods}
"Input.Keys" {"key-code" :static-fields
"key-pressed?" :static-fields}
"Input.Buttons" {"button-code" :static-fields
"button-pressed?" :static-fields}
"Input.Keys" {"key-code" :static-fields-upper
"key-pressed?" :static-fields-upper}
"Input.Buttons" {"button-code" :static-fields-upper
"button-pressed?" :static-fields-upper}
"InputProcessor" {"input-processor!" :methods}
"Interpolation" {"interpolation" :static-classes}
"Intersector" {"intersector!" :static-methods}
"IntAttribute" {"attribute :int" :constructors
"attribute-type :int" :static-fields
"attribute-type :int" :static-fields-pascal
"attribute! :int" :static-methods}
"IsometricStaggeredTiledMapRenderer" {"isometric-staggered-tiled-map" :methods
"isometric-staggered-tiled-map!" :methods}
@@ -146,6 +146,8 @@
"ModelInstance" {"model" :constructors
"model!" :methods}
"MouseJointDef" {"joint-def :mouse" :fields}
"Music" {"music" :methods
"music!" :methods}
"Net" {"net!" :methods}
"NinePatch" {"nine-patch" :methods
"nine-patch!" :methods}
@@ -160,10 +162,10 @@
"perspective!" :methods}
"Pixmap" {"pixmap" :methods
"pixmap!" :methods}
"Pixmap.Format" {"pixmap-format" :static-fields}
"Pixmap.Format" {"pixmap-format" :static-fields-pascal}
"Plane" {"plane" :methods
"plane!" :methods}
"Plane.PlaneSide" {"plane-side" :static-fields}
"Plane.PlaneSide" {"plane-side" :static-fields-pascal}
"Polygon" {"polygon" :methods
"polygon!" :methods}
"PolygonMapObject" {"map-object :polygon" :methods}
@@ -185,7 +187,7 @@
"RectangleMapObject" {"map-object :rectangle" :methods}
"RevoluteJointDef" {"joint-def :revolute" :fields}
"RopeJointDef" {"joint-def :rope" :fields}
"Scaling" {"scaling" :static-fields}
"Scaling" {"scaling" :static-fields-camel}
"ScrollPane" {"scroll-pane" :methods
"scroll-pane!" :methods}
"ScrollPane.ScrollPaneStyle" {"style :scroll-pane" :constructors}
@@ -196,7 +198,7 @@
"SelectBox.SelectBoxStyle" {"style :select-box" :constructors}
"ShapeRenderer" {"shape" :methods
"shape!" :methods}
"ShapeRenderer.ShapeType" {"shape-type" :static-fields}
"ShapeRenderer.ShapeType" {"shape-type" :static-fields-pascal}
"Skin" {"skin" :methods
"skin!" :methods}
"Slider" {"slider" :methods
@@ -216,7 +218,7 @@
"TextureAtlas" {"texture-atlas" :methods
"texture-atlas!" :methods}
"TextureAttribute" {"attribute :texture" :constructors
"attribute-type :texture" :static-fields
"attribute-type :texture" :static-fields-pascal
"attribute! :texture" :static-methods}
"TextButton" {"text-button" :methods
"text-button!" :methods}
@@ -242,7 +244,7 @@
"vector-2!" :methods}
"Vector3" {"vector-3" :methods
"vector-3!" :methods}
"VertexAttributes.Usage" {"usage" :static-fields}
"VertexAttributes.Usage" {"usage" :static-fields-pascal}
"VerticalGroup" {"vertical" :methods
"vertical!" :methods}
"WeldJointDef" {"joint-def :weld" :fields}

View File

@@ -1,12 +1,14 @@
/*
Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
*/
/**
* Obsidian style
* ported by Alexander Marenin (http://github.com/ioncreature)
*/
.hljs {
display: block; padding: 0.5em;
background: #444;
display: block;
overflow-x: auto;
padding: 0.5em;
background: #282b2e;
-webkit-text-size-adjust: none;
}
.hljs-keyword,
@@ -14,36 +16,77 @@ Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Or
.hljs-change,
.hljs-winutils,
.hljs-flow,
.lisp .hljs-title,
.clojure .hljs-built_in,
.nginx .hljs-title,
.css .hljs-id,
.tex .hljs-special {
color: #93c763;
}
.hljs-number {
color: #ffcd22;
}
.hljs {
color: #e0e2e4;
}
.css .hljs-tag,
.css .hljs-pseudo {
color: #d0d2b5;
}
.hljs-attribute,
.hljs .hljs-constant {
color: #668bb0;
}
.xml .hljs-attribute {
color: #b3b689;
}
.xml .hljs-tag .hljs-value {
color: #e8e2b7;
}
.hljs-code,
.hljs-class .hljs-title,
.hljs-header {
color: white;
}
.hljs,
.hljs-subst {
color: #DDD;
.hljs-class,
.hljs-hexcolor {
color: #93c763;
}
.hljs-string,
.hljs-title,
.haskell .hljs-type,
.ini .hljs-title,
.hljs-tag .hljs-value,
.css .hljs-rules .hljs-value,
.hljs-regexp {
color: #d39745;
}
.hljs-at_rule,
.hljs-at_rule .hljs-keyword {
color: #a082bd;
}
.hljs-doctype {
color: #557182;
}
.hljs-link_url,
.hljs-tag,
.hljs-tag .hljs-title,
.hljs-bullet,
.hljs-subst,
.hljs-emphasis,
.hljs-type,
.hljs-preprocessor,
.hljs-pragma,
.ruby .hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.ruby .hljs-class .hljs-parent,
.hljs-built_in,
.sql .hljs-aggregate,
.django .hljs-template_tag,
.django .hljs-variable,
.smalltalk .hljs-class,
.hljs-javadoc,
.ruby .hljs-string,
.django .hljs-filter .hljs-argument,
.smalltalk .hljs-localvars,
.smalltalk .hljs-array,
@@ -55,32 +98,36 @@ Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Or
.apache .hljs-tag,
.apache .hljs-cbracket,
.tex .hljs-command,
.hljs-prompt,
.coffeescript .hljs-attribute {
color: #D88;
.hljs-prompt {
color: #8cbbad;
}
.hljs-string {
color: #ec7600;
}
.hljs-comment,
.java .hljs-annotation,
.python .hljs-decorator,
.hljs-template_comment,
.hljs-annotation,
.hljs-blockquote,
.hljs-horizontal_rule,
.hljs-decorator,
.hljs-pi,
.hljs-doctype,
.hljs-deletion,
.hljs-shebang,
.apache .hljs-sqbracket,
.tex .hljs-formula {
color: #777;
color: #818e96;
}
.hljs-keyword,
.hljs-literal,
.hljs-title,
.css .hljs-id,
.hljs-phpdoc,
.haskell .hljs-type,
.hljs-dartdoc,
.hljs-title,
.hljs-header,
.hljs-type,
.vbscript .hljs-built_in,
.sql .hljs-aggregate,
.rsl .hljs-built_in,
.smalltalk .hljs-class,
.diff .hljs-header,
@@ -90,6 +137,7 @@ Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Or
.apache .hljs-tag,
.tex .hljs-special,
.hljs-request,
.hljs-at_rule .hljs-keyword,
.hljs-status {
font-weight: bold;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,39 +1,64 @@
body {
font-family: "Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif;
font-family: "Fira Sans", "Source Sans Pro", "Helvetica Neue", sans-serif;
background-color: #293134;
color: #c1cbc2;
font-size: 16px;
line-height: 1.4em;
}
a {
color: #c1cbc2;
transition-property: color;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(.53,.4,.46,.75);
color: #f2ecd7;
box-shadow: 0 2px 0 0 rgba(255,255,255,0.1);
text-decoration: none;
}
a:hover {
color: #f2dc77;
}
.sidebar {
width: 240px;
height: 100%;
top: 0px;
left: 0px;
position: fixed;
overflow: auto;
margin-left: 10px;
transition-property: opacity;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(.53,.4,.46,.75);
opacity: 0.6;
}
.sidebar a {
text-decoration: none;
.sidebar:hover {
opacity: 0.9;
}
.ns {
font-size: 24px;
font-weight: bold;
padding: 20px 0 0px 0;
margin-bottom: 10px;
display: inline-block;
color: #ccf;
}
.name {
margin-top: 5px;
margin-bottom: 5px;
text-indent: 10px;
}
.content {
margin-left: 250px;
padding: 20px 0px 20px 20px;
}
.content code {
box-shadow: 0 0 0 1px rgba(255,255,255,0.2);
border-radius: 3px;
padding: 0px 3px;
background: rgba(255,255,255,0.1);
text-shadow: 0 1px 0 rgba(0,0,0,0.5);
}
.content code, .content pre {
font-family: "Fira Mono", "Source Code Poro", "Consolas", "Menlo", monospace;
}
.item {
@@ -41,41 +66,65 @@ a {
}
.clj {
margin-bottom: 2em;
}
.c-head {
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
margin-bottom: 1em;
color: #ccf;
font-size: 1.5em;
}
.c-doc {
}
.c-src {
margin-bottom: 2em;
}
.java {
background: #444444;
margin-bottom: 2em;
}
.j-text {
margin-bottom: 5px;
}
.j-item {
margin-bottom: 10px;
.j-item * {
transition-property: opacity;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(.53,.4,.46,.75);
}
.j-item {
margin-bottom: 0px;
padding: 0.8em 0 0.8em 0;
line-height: 1.4em;
background: rgba(0, 0, 0, 0.15);
}
.j-item:nth-child(2n) {
background: rgba(0, 0, 0, 0.25);
}
.j-name {
font-weight: bold;
color: #69e;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.8);
margin: 0 0px 0 20px;
display: inline-block;
font-size: 1.4em;
line-height: 1.4em;
border-right: 5px transparent solid;
box-shadow: 0 2px 0 0 rgba(150,200,255,0.08);
}
.j-args {
margin-left: 5px;
padding-left: 1em;
opacity: 0.4;
display: inline-block;
}
.j-item:hover .j-args {
opacity: 0.95;
}
.j-arg {
@@ -87,4 +136,7 @@ a {
}
.j-doc {
display: block;
padding: 17px 20px 0px 20px;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);
}

9
doclet/resources/nav.js Normal file
View File

@@ -0,0 +1,9 @@
function goToHash() {
if (window.location.hash != "") {
document.getElementById("content-frame").src = window.location.hash.substr(1)
}
}
function setHash(link) {
window.parent.location.hash = link.getAttribute("newHash")
}

View File

@@ -13,49 +13,55 @@
(def classes (-> "classes.edn" io/resource slurp edn/read-string))
(defn split-string
[s]
(if (= s (string/upper-case s))
(string/split s #"_")
(string/split s #"(?=[A-Z])")))
(defn string->keyword
[s]
(->> (split-string s)
[s case-type]
(->> (case case-type
:upper #"_"
:pascal #"(?<=.)(?=[A-Z])"
:camel #"(?=[A-Z])"
(throw (Exception. "Unrecognized case type.")))
(string/split s)
(map string/lower-case)
(string/join "-")
keyword))
(defn parse-param
[^Parameter p]
[(.typeName p) (-> (.name p) string->keyword name)])
[(.typeName p) (-> (.name p) (string->keyword :camel) name)])
(defn after-last-period
[^String s]
(subs s (+ 1 (.lastIndexOf s "."))))
(defn parse-doc-name
[^Doc d]
(cond
(isa? (type d) ConstructorDoc)
[^String doc-name doc-type]
(case doc-type
:constructors
nil
(isa? (type d) ClassDoc)
(->> (+ 1 (.lastIndexOf (.name d) "."))
(subs (.name d))
string->keyword)
:classes
(string->keyword (after-last-period doc-name) :pascal)
(isa? (type d) FieldDoc)
(let [k (string->keyword (.name d))
s (name k)]
(if (= \- (first s))
(keyword (subs s 1))
k))
:static-classes
(string->keyword (after-last-period doc-name) :pascal)
:else
(string->keyword (.name d))))
:static-fields-upper
(string->keyword doc-name :upper)
:static-fields-pascal
(string->keyword doc-name :pascal)
:static-fields-camel
(string->keyword doc-name :camel)
; else
(string->keyword doc-name :camel)))
(defn parse-doc
[^Doc d clj-name]
[^Doc d clj-name doc-type]
(merge {}
{:name (->> [(second (string/split clj-name #" "))
(parse-doc-name d)]
(parse-doc-name (.name d) doc-type)]
(remove nil?)
(string/join " "))}
(when (> (count (.commentText d)) 0)
@@ -70,18 +76,20 @@
{:args [[(-> d .type .typeName) "value"]]})))
(defn parse-class-entry
[^ClassDoc c [clj-name type]]
(some->> (case type
[^ClassDoc c [clj-name doc-type]]
(some->> (case doc-type
:methods (filter #(-> % .isStatic not) (.methods c))
:static-methods (filter #(.isStatic %) (.methods c))
:fields (filter #(-> % .isStatic not) (.fields c))
:static-fields (filter #(.isStatic %) (.fields c))
:static-fields-upper (filter #(.isStatic %) (.fields c))
:static-fields-pascal (filter #(.isStatic %) (.fields c))
:static-fields-camel (filter #(.isStatic %) (.fields c))
:classes (filter #(-> % .isStatic not) (.innerClasses c))
:static-classes (filter #(.isStatic %) (.innerClasses c))
:constructors (filter #(-> % .isStatic not) (.constructors c))
nil)
(filter #(.isPublic %))
(map #(parse-doc % clj-name))
(map #(parse-doc % clj-name doc-type))
(concat (when-let [sc (.superclass c)]
(when (not= (.typeName sc) "Object")
(parse-class-entry sc [clj-name type]))))

View File

@@ -20,7 +20,7 @@
(cons [:div {:class "ns"} ns]
(for [{:keys [name]} groups]
[:div {:class "name"}
[:a {:href (str->filename ns name)}
[:a {:href (str->filename ns name) :target "content-frame" :onClick (str "setHash(this)") :newHash (str->filename ns name)}
name]])))])
(defn java-param
@@ -41,12 +41,17 @@
[:div {:class "j-doc"} text])])
(defn content
[{:keys [name docstring arglists java raw raw*]}]
[{:keys [name docstring arglists java raw raw*]} & [home-link-hash]]
[:div {:class "content"}
[:div {:class "item"}
[:div {:class "clj"}
(for [args arglists]
[:div {:class "c-head"} (pr-str args)])
[:div {:class "c-head"}
(if home-link-hash
[:a {:href (str "index.html" (str "#" home-link-hash))
:target "_top"}
(pr-str args)]
(pr-str args))])
[:div {:class "c-doc"} docstring]]
(when (> (count java) 0)
(list [:div {:class "c-head"} "Options"]
@@ -61,17 +66,17 @@
[:pre raw]]]])
(defn create-site-file
[name sidebar content]
(html [:html
[:head
[:title name]
[:link {:rel "stylesheet" :href "highlight.css"}]
[:link {:rel "stylesheet" :href "main.css"}]]
[:body
sidebar
content
[:script {:src "highlight.js"}]
[:script {:src "main.js"}]]]))
([name content]
(html [:html
[:head
[:title name]
[:script {:src "nav.js"}]
[:link {:rel "stylesheet" :href "highlight.css"}]
[:link {:rel "stylesheet" :href "main.css"}]]
[:body
content
[:script {:src "highlight.js"}]
[:script {:src "main.js"}]]])))
(defn create-embed-file
[content]
@@ -82,19 +87,39 @@
(spit (io/file dir file-name)
(-> file-name io/resource slurp)))
(defn index-frameset
[]
(html
[:html
[:head
[:title "play-clj docs"]
[:script {:src "nav.js"}]
[:link {:rel "stylesheet" :href "highlight.css"}]
[:link {:rel "stylesheet" :href "main.css"}]]
[:frameset {:cols "250px,100%" :onLoad "goToHash();"}
[:frame {:src "sidebar.html"}]
[:frame {:src "blank.html" :name "content-frame" :id "content-frame"}]
[:script {:src "highlight.js"}]
[:script {:src "main.js"}]]]))
(defn create-site!
[dir parsed-files]
(.mkdir (io/file dir))
(copy-from-res dir "main.css")
(copy-from-res dir "main.js")
(copy-from-res dir "nav.js")
(copy-from-res dir "highlight.css")
(copy-from-res dir "highlight.js")
(doseq [[ns groups] parsed-files]
(doseq [{:keys [name] :as group} groups]
(spit (io/file dir (str->filename ns name))
(create-site-file name (sidebar parsed-files) (content group)))))
(create-site-file name (content group (str->filename ns name))))))
(spit (io/file dir "sidebar.html")
(create-site-file "sidebar" (sidebar parsed-files)))
(spit (io/file dir "blank.html")
(create-site-file "blank" nil))
(spit (io/file dir "index.html")
(create-site-file "play-clj docs" (sidebar parsed-files) nil))
(index-frameset))
(println "Created" (str dir "/")))
(defn create-embed!

View File

@@ -1,11 +1,11 @@
(defproject play-clj "0.4.2-SNAPSHOT"
(defproject play-clj "0.4.5-SNAPSHOT"
:description "A libGDX wrapper for easy cross-platform game development"
:url "https://github.com/oakes/play-clj"
:license {:name "Public Domain"
:url "http://unlicense.org/UNLICENSE"}
:dependencies [[com.badlogicgames.gdx/gdx "1.4.1"]
[com.badlogicgames.gdx/gdx-box2d "1.4.1"]
[com.badlogicgames.gdx/gdx-bullet "1.4.1"]
:dependencies [[com.badlogicgames.gdx/gdx "1.5.3"]
[com.badlogicgames.gdx/gdx-box2d "1.5.3"]
[com.badlogicgames.gdx/gdx-bullet "1.5.3"]
[org.clojure/clojure "1.6.0"]]
:repositories [["sonatype"
"https://oss.sonatype.org/content/repositories/releases/"]]

View File

@@ -172,7 +172,8 @@ via the screen map.
entities))
; input functions
; Tip: convert :input-x and :input-y to screen coordinates with input->screen
; Tip: convert :input-x and :input-y to screen coordinates with input->screen,
; or just use (game :x) and (game :y) instead
(defscreen my-screen
; a key was pressed
:on-key-down
@@ -225,7 +226,6 @@ via the screen map.
entities))
; gesture functions
; Tip: use gesture-detector! to configure these functions
(defscreen my-screen
; the user dragged over the screen and lifted
:on-fling
@@ -322,21 +322,13 @@ via the screen map.
entities))
; ui input functions (for play-clj.ui)
; Tip: use click-listener! to configure these functions
(defscreen my-screen
; the ui entity was changed
; the ui entity was clicked or changed
:on-ui-changed
(fn [screen entities]
(println (:event screen)) ; the ChangeListener.ChangeEvent - http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ChangeListener.ChangeEvent.html
(println (:actor screen)) ; the Actor - http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/Actor.html
entities)
; the ui entity was clicked
:on-ui-clicked
(fn [screen entities]
(println (:event screen)) ; the InputEvent - http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/InputEvent.html
(println (:input-x screen)) ; the x position of the finger/mouse
(println (:input-y screen)) ; the y position of the finger/mouse
entities)
; the finger/mouse moved over the ui entity
:on-ui-enter
(fn [screen entities]
@@ -383,7 +375,6 @@ via the screen map.
entities))
; ui drag functions (for play-clj.ui)
; Tip: use drag-listener! to configure these functions
(defscreen my-screen
:on-ui-drag
(fn [screen entities]
@@ -517,6 +508,10 @@ keywords and functions in pairs."
(set-screen! my-game main-screen text-screen)"
[^Game game-object & screen-objects]
(doseq [screen screen-objects]
(assert (every? #(fn? (get screen %))
[:show :render :hide :pause :resize :resume])
"Attempted to set an invalid screen."))
(let [run-fn! (fn [k & args]
(doseq [screen screen-objects]
(apply (get screen k) args)))]

View File

@@ -101,10 +101,10 @@
:fps (graphics! :get-frames-per-second)
:fullscreen? (graphics! :is-fullscreen)
:touched? (input! :is-touched)
:x (throw (Exception. "Replace (game :x) with (input! :get-x)"))
:y (throw (Exception. "Replace (game :y) with (input! :get-y)"))
:point-x (input! :get-x (or arg 0))
:point-y (- (graphics! :get-height) (input! :get-y (or arg 0)))
:x (input! :get-x (or arg 0))
:y (- (graphics! :get-height) (input! :get-y (or arg 0)))
:point-x (game :x arg)
:point-y (game :y arg)
(u/throw-key-not-found k)))
(defmacro key-code
@@ -153,7 +153,7 @@
(audio! :new-sound (files! :internal path))))
(defmacro sound
"Returns a [Sound](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/audio/Sound.html).
"Returns a [Sound](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/audio/Sound.html). Supports wav, mp3, and ogg.
(sound \"playerhurt.wav\")
(sound \"playerhurt.wav\" :play)"
@@ -170,29 +170,25 @@
`(let [^Sound object# ~object]
(u/call! object# ~k ~@options)))
(defn music*
[path]
(let [^FileHandle fh (if (string? path)
(files! :internal path)
path)]
(or (u/load-asset (.path fh) Music)
(audio! :new-music fh))))
[^String path]
(or (u/load-asset path Music)
(audio! :new-music (files! :internal path))))
(defmacro music
"Returns a [Sound](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/audio/Sound.html).
"Returns a [Music](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/audio/Music.html). Supports wav, mp3, and ogg.
(sound \"playerhurt.wav\")
(sound \"playerhurt.wav\" :play)"
(music \"song.wav\")
(music \"song.wav\" :play)"
[path & options]
`(let [^Music object# (music* ~path)]
(u/calls! object# ~@options)))
(defmacro music!
"Calls a single method on a `sound`.
"Calls a single method on a `music`.
(sound! object :play)
(sound! object :dispose)"
(music! object :play)
(music! object :dispose)"
[object k & options]
`(let [^Music object# ~object]
(u/call! object# ~k ~@options)))

View File

@@ -165,14 +165,13 @@ of the camera will be set."
"Sets the position of `object`. If `object` is a screen, the position of the
camera will be set."
([object vec-3]
(let [^Camera camera (u/get-obj object :camera)]
(set! (. camera position) vec-3)))
(position! object (x vec-3) (y vec-3) (z vec-3)))
([object x-val y-val]
(position! object x-val y-val nil))
([object x-val y-val z-val]
(when x-val (x! object x-val))
(when y-val (y! object y-val))
(when z-val (z! object z-val))))
(some->> x-val (x! object))
(some->> y-val (y! object))
(some->> z-val (z! object))))
(defn direction
"Returns the direction of the camera in `screen`."
@@ -182,9 +181,24 @@ camera will be set."
(defn direction!
"Sets the direction of the camera in `screen`."
[screen x y z]
[screen x-val y-val z-val]
(let [^Camera camera (u/get-obj screen :camera)]
(.lookAt camera x y z)
(.lookAt camera x-val y-val z-val)
(.update camera)))
(defn up [screen]
"Returns the up vector of the camera in `screen`."
(let [^Camera camera (u/get-obj screen :camera)]
(. camera up)))
(defn up!
"Sets the up vector of the camera in `screen`."
[screen x-val y-val z-val]
(let [^Camera camera (u/get-obj screen :camera)
^Vector3 up-vec (up screen)]
(some->> x-val (x! up-vec))
(some->> y-val (y! up-vec))
(some->> z-val (z! up-vec))
(.update camera)))
(defn near

View File

@@ -478,7 +478,7 @@ with the tiled map file at `path` and `unit` scale.
(defmethod draw! BatchTiledMapRenderer
[{:keys [^BatchTiledMapRenderer renderer] :as screen} entities]
(let [^Batch batch (.getSpriteBatch renderer)]
(let [^Batch batch (.getBatch renderer)]
(.begin batch)
(doseq [entity entities]
(e/draw! entity screen batch))
@@ -610,7 +610,7 @@ to overlap correctly with the entities.
(when-not (get-in screen [:layers ln])
(update-fn! assoc-in [:layers ln] (split-layer screen ln))))
(when camera (.setView renderer camera))
(let [^Batch batch (.getSpriteBatch renderer)]
(let [^Batch batch (.getBatch renderer)]
(.begin batch)
(doseq [entity (->> (map #(get-in screen [:layers %]) layer-names)
(apply concat entities)

View File

@@ -184,8 +184,6 @@ such as :on-begin-contact."
(defmacro circle-shape
"Returns a [CircleShape](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/CircleShape.html)."
[& options]
(when (some-> (first options) keyword? not)
(throw (Exception. "Replace (circle-shape radius) with (circle-shape :set-radius radius :set-position (vector-2 radius radius))")))
`(u/calls! ^CircleShape (circle-shape*) ~@options))
(defmacro circle-shape!

View File

@@ -153,7 +153,7 @@ new object to be created each time a field is set).
(defn gdx-array*
[clj-arr]
(Array. true (into-array clj-arr) 1 (count clj-arr)))
(Array. (into-array clj-arr)))
(defmacro gdx-array
"Returns an [Array](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Array.html).

View File

@@ -1,8 +1,8 @@
(defproject play-clj/lein-template "0.4.1"
(defproject play-clj/lein-template "0.4.4"
:description "A template for making play-clj projects"
:url "https://github.com/oakes/play-clj"
:license {:name "Public Domain"
:url "http://unlicense.org/UNLICENSE"}
:dependencies [[lein-droid "0.2.3"]]
:dependencies [[lein-droid "0.3.3"]]
:resource-paths ["resources"]
:eval-in-leiningen true)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -58,7 +58,7 @@
(render "AndroidLauncher.java" data)]
"android/src/clojure"
["android/AndroidManifest.xml"
(lein-droid-render "AndroidManifest.xml" data)]
(render "AndroidManifest.xml" data)]
["android/res/drawable-hdpi/ic_launcher.png"
(lein-droid-render "ic_launcher_hdpi.png")]
["android/res/drawable-mdpi/ic_launcher.png"

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="{{package-sanitized}}"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="{{target-sdk}}" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity android:name=".SplashActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".{{activity}}">
<intent-filter>
<action android:name='{{package-sanitized}}.MAIN'/>
<category android:name='android.intent.category.DEFAULT'/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,15 +1,14 @@
(defproject {{app-name}} "0.0.1-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[com.badlogicgames.gdx/gdx "1.4.1" :use-resources true]
[com.badlogicgames.gdx/gdx-backend-android "1.4.1"]
[com.badlogicgames.gdx/gdx-box2d "1.4.1"]
[com.badlogicgames.gdx/gdx-bullet "1.4.1"]
[neko/neko "3.0.2"]
:dependencies [[com.badlogicgames.gdx/gdx "1.5.3" :use-resources true]
[com.badlogicgames.gdx/gdx-backend-android "1.5.3"]
[com.badlogicgames.gdx/gdx-box2d "1.5.3"]
[com.badlogicgames.gdx/gdx-bullet "1.5.3"]
[neko/neko "3.1.1"]
[org.clojure-android/clojure "1.6.0-RC1" :use-resources true]
[play-clj "0.4.1"]]
:profiles {:dev {:dependencies [[android/tools.nrepl "0.2.0-bigstack"]
[compliment "0.1.3"]]
[play-clj "0.4.4"]]
:profiles {:dev {:dependencies [[org.clojure-android/tools.nrepl "0.2.6"]]
:android {:aot :all-with-unused}}
:release {:android
{;; Specify the path to your private
@@ -26,7 +25,7 @@
;; Uncomment this if dexer fails with OutOfMemoryException
;; :force-dex-optimize true
:assets-path "../desktop/resources"
:assets-paths ["../desktop/resources"]
:native-libraries-paths ["libs"]
:target-version "{{target-sdk}}"
:aot-exclude-ns ["clojure.parallel" "clojure.core.reducers"]

View File

@@ -1,18 +1,18 @@
(defproject {{app-name}} "0.0.1-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[com.badlogicgames.gdx/gdx "1.4.1"]
[com.badlogicgames.gdx/gdx-backend-lwjgl "1.4.1"]
[com.badlogicgames.gdx/gdx-box2d "1.4.1"]
[com.badlogicgames.gdx/gdx-box2d-platform "1.4.1"
:dependencies [[com.badlogicgames.gdx/gdx "1.5.3"]
[com.badlogicgames.gdx/gdx-backend-lwjgl "1.5.3"]
[com.badlogicgames.gdx/gdx-box2d "1.5.3"]
[com.badlogicgames.gdx/gdx-box2d-platform "1.5.3"
:classifier "natives-desktop"]
[com.badlogicgames.gdx/gdx-bullet "1.4.1"]
[com.badlogicgames.gdx/gdx-bullet-platform "1.4.1"
[com.badlogicgames.gdx/gdx-bullet "1.5.3"]
[com.badlogicgames.gdx/gdx-bullet-platform "1.5.3"
:classifier "natives-desktop"]
[com.badlogicgames.gdx/gdx-platform "1.4.1"
[com.badlogicgames.gdx/gdx-platform "1.5.3"
:classifier "natives-desktop"]
[org.clojure/clojure "1.6.0"]
[play-clj "0.4.1"]]
[play-clj "0.4.4"]]
:source-paths ["src" "src-common"]
:javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]

View File

@@ -1,11 +1,11 @@
(defproject {{app-name}} "0.0.1-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[com.badlogicgames.gdx/gdx "1.4.1"]
[com.badlogicgames.gdx/gdx-backend-robovm "1.4.1"]
[com.badlogicgames.gdx/gdx-box2d "1.4.1"]
[com.badlogicgames.gdx/gdx-bullet "1.4.1"]
:dependencies [[com.badlogicgames.gdx/gdx "1.5.3"]
[com.badlogicgames.gdx/gdx-backend-robovm "1.5.3"]
[com.badlogicgames.gdx/gdx-box2d "1.5.3"]
[com.badlogicgames.gdx/gdx-bullet "1.5.3"]
[org.clojure/clojure "1.6.0"]
[play-clj "0.4.1"]]
[play-clj "0.4.4"]]
:source-paths ["src/clojure" "../desktop/src-common"]
:java-source-paths ["src/java"]
:javac-options ["-target" "1.7" "-source" "1.7" "-Xlint:-options"]