Automatically add box2d contact listener
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
(ns play-clj.core
|
||||
(:require [clojure.set :as set]
|
||||
[play-clj.g2d-physics :as g2dp]
|
||||
[play-clj.ui :as ui]
|
||||
[play-clj.utils :as u])
|
||||
(:import [com.badlogic.gdx Application Audio Files Game Gdx Graphics Input
|
||||
@@ -18,12 +19,13 @@
|
||||
IsometricStaggeredTiledMapRenderer
|
||||
IsometricTiledMapRenderer
|
||||
OrthogonalTiledMapRenderer]
|
||||
[com.badlogic.gdx.physics.box2d World]
|
||||
[com.badlogic.gdx.scenes.scene2d Actor Stage]))
|
||||
|
||||
(load "core_global")
|
||||
(load "core_graphics")
|
||||
|
||||
(defn ^:private reset-if-changed!
|
||||
(defn ^:private reset-changed!
|
||||
[e-atom e-old e-new]
|
||||
(when (not= e-old e-new)
|
||||
(compare-and-set! e-atom e-old e-new)))
|
||||
@@ -33,10 +35,6 @@
|
||||
:as options}]
|
||||
(let [screen (atom {})
|
||||
entities (atom '())
|
||||
_ (add-watch entities
|
||||
:changed
|
||||
(fn [_ _ _ new-entities]
|
||||
(refresh-renderer! @screen new-entities)))
|
||||
execute-fn! (fn [func & {:keys [] :as options}]
|
||||
(when func
|
||||
(let [old-entities @entities]
|
||||
@@ -44,18 +42,21 @@
|
||||
list
|
||||
flatten
|
||||
(remove nil?)
|
||||
(reset-if-changed! entities old-entities)))))
|
||||
listeners [(input-processor options execute-fn!)
|
||||
(gesture-detector options execute-fn!)]
|
||||
ui-listeners (ui/create-listeners options execute-fn!)
|
||||
update-fn! #(swap! screen merge %)]
|
||||
(reset-changed! entities old-entities)))))]
|
||||
; update screen when either the screen or entities are changed
|
||||
(add-watch screen :changed (fn [_ _ _ new-screen]
|
||||
(update-screen! new-screen)))
|
||||
(add-watch entities :changed (fn [_ _ _ new-entities]
|
||||
(update-screen! @screen new-entities)))
|
||||
; return a map with all values related to the screen
|
||||
{:screen screen
|
||||
:entities entities
|
||||
:show (fn []
|
||||
(swap! screen assoc
|
||||
:total-time 0
|
||||
:update-fn! update-fn!
|
||||
:ui-listeners ui-listeners)
|
||||
:update-fn! #(swap! screen merge %)
|
||||
:ui-listeners (ui/ui-listeners options execute-fn!)
|
||||
:g2dp-listener (g2dp/contact-listener options execute-fn!))
|
||||
(execute-fn! on-show))
|
||||
:render (fn [d]
|
||||
(swap! screen #(assoc % :total-time (+ (:total-time %) d)))
|
||||
@@ -64,7 +65,8 @@
|
||||
:pause #(execute-fn! on-pause)
|
||||
:resize #(execute-fn! on-resize :width %1 :height %2)
|
||||
:resume #(execute-fn! on-resume)
|
||||
:listeners listeners}))
|
||||
:input-listeners [(input-processor options execute-fn!)
|
||||
(gesture-detector options execute-fn!)]}))
|
||||
|
||||
(defmacro defscreen
|
||||
[n & {:keys [] :as options}]
|
||||
@@ -88,8 +90,8 @@
|
||||
[^Game game & screens]
|
||||
(let [add-inputs! (fn []
|
||||
(input! :set-input-processor (InputMultiplexer.))
|
||||
(doseq [{:keys [listeners]} screens]
|
||||
(doseq [listener listeners]
|
||||
(doseq [{:keys [input-listeners]} screens]
|
||||
(doseq [listener input-listeners]
|
||||
(add-input! listener))))
|
||||
run-fn! (fn [k & args]
|
||||
(doseq [screen screens]
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
(in-ns 'play-clj.core)
|
||||
|
||||
(defn ^:private update-screen!
|
||||
([{:keys [world g2dp-listener]}]
|
||||
(when (isa? (type world) World)
|
||||
(.setContactListener ^World world g2dp-listener)))
|
||||
([{:keys [renderer ui-listeners]} entities]
|
||||
(when (isa? (type renderer) Stage)
|
||||
(doseq [^Actor a (.getActors ^Stage renderer)]
|
||||
(.remove a))
|
||||
(doseq [{:keys [object]} entities]
|
||||
(when (isa? (type object) Actor)
|
||||
(.addActor ^Stage renderer object)
|
||||
(doseq [listener ui-listeners]
|
||||
(.addListener ^Actor object listener))))
|
||||
(remove-input! renderer)
|
||||
(add-input! renderer))))
|
||||
|
||||
; tiled maps
|
||||
|
||||
(defn tiled-map*
|
||||
@@ -197,19 +213,6 @@
|
||||
(render! screen)
|
||||
(draw! screen entities)))
|
||||
|
||||
(defn ^:private refresh-renderer!
|
||||
[{:keys [renderer ui-listeners]} entities]
|
||||
(when (isa? (type renderer) Stage)
|
||||
(doseq [^Actor a (.getActors ^Stage renderer)]
|
||||
(.remove a))
|
||||
(doseq [{:keys [object]} entities]
|
||||
(when (isa? (type object) Actor)
|
||||
(.addActor ^Stage renderer object)
|
||||
(doseq [listener ui-listeners]
|
||||
(.addListener ^Actor object listener))))
|
||||
(remove-input! renderer)
|
||||
(add-input! renderer)))
|
||||
|
||||
; cameras
|
||||
|
||||
(defn orthographic*
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
(ns play-clj.g2d-physics
|
||||
(:require [play-clj.math :as m]
|
||||
[play-clj.utils :as u])
|
||||
(:import [com.badlogic.gdx.physics.box2d World]))
|
||||
(:import [com.badlogic.gdx.physics.box2d ContactListener World]))
|
||||
|
||||
(defn box2d*
|
||||
(defn box-2d*
|
||||
([]
|
||||
(box2d* 0 0 true))
|
||||
(box-2d* 0 0 true))
|
||||
([gravity-x gravity-y]
|
||||
(box2d* gravity-x gravity-y true))
|
||||
(box-2d* gravity-x gravity-y true))
|
||||
([gravity-x gravity-y sleep?]
|
||||
(World. (m/vector-2 gravity-x gravity-y) sleep?)))
|
||||
|
||||
(defmacro box2d
|
||||
(defmacro box-2d
|
||||
[gravity-x gravity-y & options]
|
||||
`(let [object# (box2d* ~gravity-x ~gravity-y)]
|
||||
`(let [object# (box-2d* ~gravity-x ~gravity-y)]
|
||||
(u/calls! ^World object# ~@options)
|
||||
object#))
|
||||
|
||||
(defmacro box2d!
|
||||
(defmacro box-2d!
|
||||
[{:keys [^World world]} k & options]
|
||||
`(u/call! ^World ~world ~k ~@options))
|
||||
|
||||
(defn contact-listener
|
||||
[{:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]} execute-fn!]
|
||||
(reify ContactListener
|
||||
(beginContact [this c]
|
||||
(execute-fn! on-begin-contact :contact c))
|
||||
(endContact [this c]
|
||||
(execute-fn! on-end-contact :contact c))
|
||||
(postSolve [this c i]
|
||||
(execute-fn! on-post-solve :contact c :impulse i))
|
||||
(preSolve [this c m]
|
||||
(execute-fn! on-pre-solve :contact c :old-manifold m))))
|
||||
|
||||
@@ -476,7 +476,7 @@
|
||||
(scrollFocusChanged [e a f]
|
||||
(execute-fn! on-ui-scroll-focus-changed :event e :actor a :focused? f))))
|
||||
|
||||
(defn create-listeners
|
||||
(defn ui-listeners
|
||||
[options execute-fn!]
|
||||
[(gesture-listener options execute-fn!)
|
||||
(change-listener options execute-fn!)
|
||||
|
||||
Reference in New Issue
Block a user