Loading assets in libgdx (clojure) - clojure

I'm trying to make a game using clojure and libgdx. The information at Using Libgdx with Clojure was immensely helpful but now I'm stuck on the simple step of displaying a sprite. In my screen I have this
(def main-screen
(let [stage (atom nil)]
(proxy [Screen] []
(show []
(reset! stage (Stage.))
(let [style (Label$LabelStyle. (BitmapFont.) (Color. 0 1 1 1))
label (Label. "Hello world!" style)]
(.addActor #stage label)))
(render [delta]
(.glClearColor (Gdx/gl) 0 1 0 1)
(.glClear (Gdx/gl) GL20/GL_COLOR_BUFFER_BIT)
(doto (SpriteBatch.)
(. begin)
(. draw (ship-texture) 10 10)
(. end))
(doto #stage
(.act delta)
(.draw)))
(dispose[])
(hide [])
(pause [])
(resize [w h])
(resume []))))
and that references a simple function above
(defn ship-texture [] (Texture. (.internal Gdx/files "AShip.PNG")))
But no matter where I put the file libgdx can't seem to find it. I've placed it in resources, src, assets and the base directory. I feel like I must be misssing something tremendously simple.

Related

ClojureScript function prints strings, but will not return hiccup

I have a ClojureScript component:
(defn main-panel []
(def nodes (-> #(re-frame/subscribe [::subs/nodes])))
(defn list-nodes [node]
(prn (node :name)))
(reagent/create-class
{:component-did-mount
(fn []
(api-service/get-file-tree))
:reagent-render
(fn []
(doseq [node nodes]
(if (= (node :depth) 0)
(list-nodes node))))}))
which prints strings to the console.
But when I change the first function to:
(defn list-nodes [node]
[:<>
[:h1 (node :name)]])
I don't get any HTML that is rendered - no errors and the browser window stays blank.
How can I change this so it renders html?
Update
In response to the answer below I have changed doseq for for.
The issue is now that I am getting the error Uncaught Invariant Violation: Objects are not valid as a React child which is fine if you're working with React because you can debug, but with reagent, not so much. consider the following. This function:
(defn node [nodes]
(prn (nodes :name)))
when called by this function:
:reagent-render
(fn []
(for [nodes all-nodes]
(if (= (nodes :depth) 0)
(do
(nodeComponent/node nodes)
))))
prints 5 strings. But changing the called function to this:
(defn node [nodes]
[:h1 (nodes :name)])
causes this error: Uncaught Invariant Violation: Objects are not valid as a React child.
Is this problem somehow related to another problem I'm having?
For one, def and defn create global bindings. In order to create local bindings, use let or letfn:
(defn main-panel []
(let [nodes (-> #(re-frame/subscribe [::subs/nodes]))
(letfn [(list-nodes [node]
(prn (node :name)))]
(reagent/create-class
{:component-did-mount
(fn []
(api-service/get-file-tree))
:reagent-render
(fn []
(doseq [node nodes]
(if (= (node :depth) 0)
(list-nodes node))))}))
Your problem is that the render function should return the hiccup forms, but doseq returns nil. The function inside gets run (that's why you see console output from prn), but its return value is thrown away (that's why you see no HTML). An immediate fix might be to replace doseq with for, but
You could maybe do it like this (first reagent form):
(defn main-panel []
[:ul (for [node #(re-frame/subscribe [::subs/nodes])
:when (zero? (:depth node))]
^{:key (:id node)} ; whatever identifies nodes, for performance
[:li {:class "node"} (:name node)]])
I would trigger data fetching not here but wherever you startup your application (more or less parallel to the initial app render step).

Clojure - tests with components strategy

I am implementing an app using Stuart Sierra component. As he states in the README :
Having a coherent way to set up and tear down all the state associated
with an application enables rapid development cycles without
restarting the JVM. It can also make unit tests faster and more
independent, since the cost of creating and starting a system is low
enough that every test can create a new instance of the system.
What would be the preferred strategy here ? Something similar to JUnit oneTimeSetUp / oneTimeTearDown , or really between each test (similar to setUp / tearDown) ?
And if between each test, is there a simple way to start/stop a system for all tests (before and after) without repeating the code every time ?
Edit : sample code to show what I mean
(defn test-component-lifecycle [f]
(println "Setting up test-system")
(let [s (system/new-test-system)]
(f s) ;; I cannot pass an argument here ( https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L718 ), so how can I pass a system in parameters of a test ?
(println "Stopping test-system")
(component/stop s)))
(use-fixtures :once test-component-lifecycle)
Note : I am talking about unit-testing here.
I would write a macro, which takes a system-map and starts all components before running tests and stop all components after testing.
For example:
(ns de.hh.new-test
(:require [clojure.test :refer :all]
[com.stuartsierra.component :as component]))
;;; Macro to start and stop component
(defmacro with-started-components [bindings & body]
`(let [~(bindings 0) (component/start ~(bindings 1))]
(try
(let* ~(destructure (vec (drop 2 bindings)))
~#body)
(catch Exception e1#)
(finally
(component/stop ~(bindings 0))))))
;; Test Component
(defprotocol Action
(do-it [self]))
(defrecord TestComponent [state]
component/Lifecycle
(start [self]
(println "====> start")
(assoc self :state (atom state)))
(stop [self]
(println "====> stop"))
Action
(do-it [self]
(println "====> do action")
#(:state self)))
;: TEST
(deftest ^:focused component-test
(with-started-components
[system (component/system-map :test-component (->TestComponent"startup-state"))
test-component (:test-component system)]
(is (= "startup-state" (do-it test-component)))))
Running Test you should see the out put like this
====> start
====> do action
====> stop
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

Stopping a threaded sound loop in Clojure

I have a threaded looping sound clip:
(def f
(future
(let [sound-file (java.io.File. "/path/to/file.wav")
sound-in (javax.sound.sampled.AudioSystem/getAudioInputStream sound-file)
format (.getFormat sound-in)
info (javax.sound.sampled.DataLine$Info. javax.sound.sampled.Clip format)
clip (javax.sound.sampled.AudioSystem/getLine info)]
(.open clip sound-in)
(.loop clip javax.sound.sampled.Clip/LOOP_CONTINUOUSLY))))
The problem is that when I try to kill the thread:
(future-cancel f)
it doesn't stop the clip, which plays forever. I found that the only way to stop it was to call (.stop clip) explicitly. My question: what would be the best/idiomatic way of doing this? I'm pretty new to Clojure, so I only experimented with future so far, but maybe an agent would be better suited in this context?
Update: given that the .loop function is non-blocking (as was discussed below), I simplified my design by getting rid of the initial future:
(defn play-loop [wav-fn]
(let [sound-file (java.io.File. wav-fn)
sound-in (javax.sound.sampled.AudioSystem/getAudioInputStream sound-file)
format (.getFormat sound-in)
info (javax.sound.sampled.DataLine$Info. javax.sound.sampled.Clip format)
clip (javax.sound.sampled.AudioSystem/getLine info)]
(.open clip sound-in)
(.loop clip javax.sound.sampled.Clip/LOOP_CONTINUOUSLY)
clip))
along with a controlling atom:
(def ^:dynamic *clip* (atom nil))
with which I start the loop:
(when (nil? #*clip*)
(reset! *clip* (play-loop "/path/to/file.wav")))
and stop it:
(when #*clip*
(future (.stop #*clip*) ; to avoid a slight delay caused by .stop
(reset! *clip* nil)))
You can try something like this:
(def f
(future
(let [sound-file (java.io.File. "/path/to/file.wav")
sound-in (javax.sound.sampled.AudioSystem/getAudioInputStream sound-file)
format (.getFormat sound-in)
info (javax.sound.sampled.DataLine$Info. javax.sound.sampled.Clip format)
clip (javax.sound.sampled.AudioSystem/getLine info)
stop (fn [] (.stop clip))]
(.open clip sound-in)
(.loop clip javax.sound.sampled.Clip/LOOP_CONTINUOUSLY)
stop)))
(def stop-loop #f)
(stop-loop)

Clojure Agent question - using send-off

I have a couple of questions about the following code:
(import
'(java.awt Color Graphics Dimension)
'(java.awt.image BufferedImage)
'(javax.swing JPanel JFrame))
(def width 900)
(def height 600)
(defn render
[g]
(let [img (new BufferedImage width height
(. BufferedImage TYPE_INT_ARGB))
bg (. img (getGraphics))]
(doto bg
(.setColor (. Color white))
(.fillRect 0 0 (. img (getWidth)) (. img (getHeight)))
(.setColor (. Color red))
(.drawOval 200 200 (rand-int 100) (rand-int 50)))
(. g (drawImage img 0 0 nil))
(. bg (dispose))
))
(def panel (doto (proxy [JPanel] []
(paint [g] (render g)))
(.setPreferredSize (new Dimension
width
height))))
(def frame (doto (new JFrame) (.add panel) .pack .show))
(def animator (agent nil))
(defn animation
[x]
(send-off *agent* #'animation)
(. panel (repaint))
(. Thread (sleep 100)))
(send-off animator animation)
In the animation function - why is #' used before animation in send-off?
Why does send-off at the start of animation function work? Shouldn't it just go the start of animation function again and never execute the repaint and sleep methods?
Is there any disadvantage, as compared to the original, in writing the animation function as:
(defn animation
[x]
(. panel (repaint))
(. Thread (sleep 100))
(send-off *agent* animation))
In the animation function - why is #' used before animation in send-off?
To demonstrate Clojure's dynamic nature.
The form #'animation is a Var, one of Clojure's mutable reference types. The defn macro creates a Var. For convenience, invoking a Var which refers to a function is the same as invoking the function itself. But a Var, unlike a function, can change! We could redefine #'animation at the Clojure REPL and immediately see the effects.
Using (send-off *agent* #'animation) forces Clojure to look up of the current value of the #'animation Var every time. If the code had used (send-off *agent* animation) instead, then Clojure would look up the value only once, and it would not be possible to change the animation function without stopping the loop.
1. This is a little unclear to me as well but seems to be a design decision by Rich. If you notice:
user=> (defn x [y] (+ y 2))
#'user/x
user=> ((var x) 3)
5
If a var is in the function/macro location, it will eventually resolve to the function or macro.
2. One important thing to understand here is the agent model. Agents can be thought of as a worker that operates on a single mutable cell. There is a queue of work (a queue of functions) for that agent to do. send-off and send add work to that queue. Since send-off is only adding work to the queue, it immediately returns. Since the agent only executes the functions serially, the first animation call must finish before executing the next one. Therefore, you achieve basically the same thing regardless of putting send-off first or last.
3. There should be no noticeable difference between the two.

i need the steps to run a code in clojure language contains GUI in java

i have a big problem my doctor want form me to make calculator using new language(clojure)but i don't know anything about it i read some information from www.clojure.org but i still have a problem how to save the code in a file to run it another time and i need the path how to connect java to clojure i found this code :
(ns rayne.main
(:gen-class)
(:import (javax.swing JFrame JTextField JButton JOptionPane)
(java.awt.event ActionListener)
(java.awt GridLayout)))
(def numbers (ref []))
(def times-clicked (ref 0))
(defn calc [nseq op]
(let [n1 (first nseq)
n2 (last nseq)]
(cond
(= op "+") (+ n1 n2)
(= op "*") (* n1 n2)
(= op "-") (- n2 n1)
(= op "/") (/ n1 n2))))
(defn add-op-button [op text button]
(.addActionListener button
(proxy [ActionListener] []
(actionPerformed [e]
(dosync
(ref-set times-clicked (inc #times-clicked))
(if (= #times-clicked 2)
(do
(let [result (.toString (calc #numbers op))
result2 (read-string result)]
(.setText text result)
(ref-set numbers [])
(ref-set times-clicked 0)))
(do
(ref-set numbers (conj #numbers (read-string (.getText text))))
(.setText text ""))))))))
(defn -main []
(let [frame (JFrame. "Calculator")
add-button (JButton. "+")
sub-button (JButton. "-")
mul-button (JButton. "*")
div-button (JButton. "/")
clr-button (JButton. "Clear")
text-field (JTextField.)]
(add-op-button "+" text-field add-button)
(add-op-button "-" text-field sub-button)
(add-op-button "*" text-field mul-button)
(add-op-button "/" text-field div-button)
(doto frame
(.setLayout (GridLayout. 1 5))
(.add text-field)
(.add add-button)
(.add sub-button)
(.add mul-button)
(.add div-button)
(.setSize 500 100)
(.setVisible true))))
so when i try to test it i don't know how it work .
please i need some one to help me in this problem and send me a link to install a clojure program to execute such a file.
thank's for all
Sounds like a great reason to lean a fun new language.
for getting started with new clojure pojects the leiningen tool can get you to the point of compiling and running code very quickly. (i'm assuming mac or linux here)
install leiningen
lein new project-name
put your code in the project-name/src/ ... /core.clj file
lein uberjar
java -jar name-of-jar-file
repeat, hack, and have some fun!
Leiningen can also start a repl for you which will speed up you iterations and integrates well (through slime/swank) with emacs.
here is a good tutorial on leiningen
Clojure.org has a nice section called Getting Started that is about ... getting started. From getting the clojure zip file to debugging and profiling. Very, very basic.
Also has links to more advanced resources.