# HG changeset patch # User Steve Losh # Date 1449935086 0 # Node ID dee99c486fc147a72fb9a48123392269d8369b9d Initial commit diff -r 000000000000 -r dee99c486fc1 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sat Dec 12 15:44:46 2015 +0000 @@ -0,0 +1,10 @@ +syntax:glob +target +classes +checkouts +pom.xml +pom.xml.asc +*.jar +*.class +.lein-* +.nrepl-port diff -r 000000000000 -r dee99c486fc1 README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Sat Dec 12 15:44:46 2015 +0000 @@ -0,0 +1,36 @@ +# silt + +FIXME: description + +## Installation + +Download from http://example.com/FIXME. + +## Usage + +FIXME: explanation + + $ java -jar silt-0.1.0-standalone.jar [args] + +## Options + +FIXME: listing of options this app accepts. + +## Examples + +... + +### Bugs + +... + +### Any Other Sections +### That You Think +### Might be Useful + +## License + +Copyright © 2015 FIXME + +Distributed under the Eclipse Public License either version 1.0 or (at +your option) any later version. diff -r 000000000000 -r dee99c486fc1 project.clj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project.clj Sat Dec 12 15:44:46 2015 +0000 @@ -0,0 +1,12 @@ +(defproject silt "0.1.0-SNAPSHOT" + :description "FIXME: write description" + :url "http://example.com/FIXME" + :license {:name "Eclipse Public License" + :url "http://www.eclipse.org/legal/epl-v10.html"} + :dependencies [[org.clojure/clojure "1.7.0"] + [clojure-lanterna "0.9.5"] + [roul "0.2.0"] + ] + :main ^:skip-aot silt.core + :target-path "target/%s" + :profiles {:uberjar {:aot :all}}) diff -r 000000000000 -r dee99c486fc1 src/silt/core.clj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/silt/core.clj Sat Dec 12 15:44:46 2015 +0000 @@ -0,0 +1,147 @@ +(ns silt.core + (:require [lanterna.screen :as s] + [roul.random :as rr] + [clojure.stacktrace :refer [print-stack-trace]]) + (:gen-class)) + + +; Data ------------------------------------------------------------------------ +(def fps 20) +(def world-width 600) +(def world-height 400) + +(def screen (s/get-screen :swing)) +(defonce running (atom true)) +(def window-loc (ref [0 0])) +(defonce last-timestamp (atom 0)) + +(defonce terrain (ref [])) +(def terrain-rate 1) +(def terrain-objects + [{:name :rock :glyph "*"} + {:name :shrub :glyph "%"}]) + +(def landmarks (ref + #{{:name :monolith :glyph "#" :loc [0 0] :styles {:fg :black :bg :yellow}} + {:name :colossus :glyph "@" :loc [200 100] :styles {:fg :black :bg :red}} + })) + + +; Utils ----------------------------------------------------------------------- +(defmacro while-let [binding-form & body] + `(loop [] + (when-let ~binding-form + ~@body + (recur)))) + + +; World Generation ------------------------------------------------------------ +(defn generate-terrain [] + (for [x (range world-width) + y (range world-height) + :when (rr/rand-bool terrain-rate)] + (assoc (rr/rand-nth terrain-objects) + :loc [x y]))) + +(defn reset-terrain! [] + (let [new-terrain (generate-terrain)] + (dosync + (ref-set terrain new-terrain)) + nil)) + + +; Drawing --------------------------------------------------------------------- +(defn normalize-coord [v limit] + (cond + (< v 0) (normalize-coord (+ limit v) limit) + (>= v limit) (normalize-coord (- v limit) limit) + :else v)) + +(defn normalize-world-coords [[wx wy]] + [(normalize-coord wx world-width) + (normalize-coord wy world-height)]) + +(defn calc-screen-coords [[wx wy]] + (let [[ox oy] @window-loc] + (normalize-world-coords [(- wx ox) (- wy oy)]))) + +(defn draw-terrain! [screen] + (let [[swidth sheight] (s/get-size screen)] + (doseq [{:keys [loc glyph]} @terrain + :let [[sx sy] (calc-screen-coords loc)] + :when (and (< -1 sx swidth) + (< -1 sy sheight))] + (s/put-string screen sx sy glyph)))) + +(defn draw-landmarks! [screen] + (let [[swidth sheight] (s/get-size screen)] + (doseq [{:keys [loc glyph styles]} @landmarks + :let [[sx sy] (calc-screen-coords loc)] + :when (and (< -1 sx swidth) + (< -1 sy sheight))] + (s/put-string screen sx sy glyph styles)))) + +(defn draw-screen! [screen] + (s/clear screen) + (draw-terrain! screen) + (draw-landmarks! screen) + (s/put-string screen (- (nth (s/get-size screen) 0) 7) 0 " SILT ") + (s/move-cursor screen (- (nth (s/get-size screen) 0) 6) 0) + (s/redraw screen)) + + +; Input ----------------------------------------------------------------------- +(defn move-window! [key] + (dosync + (commute window-loc + #(let [[x y] %1] + (case %2 + :up [x (dec y)] + :down [x (inc y)] + :left [(dec x) y] + :right [(inc x) y])) + key))) + +(defn handle-input! [screen] + (while-let [key (s/get-key screen)] + (case key + :escape (reset! running false) + (:up :down :left :right) (move-window! key) + nil))) + + +; Game loop ------------------------------------------------------------------- +(defn throttle! [] + (let [current (System/currentTimeMillis) + sofar (- current @last-timestamp) + desired (/ 1000 fps) + wait (- desired sofar)] + (reset! last-timestamp current) + (if (> wait 0) + (Thread/sleep wait)))) + +(defn main-loop [] + (s/in-screen + screen + (while @running + (draw-screen! screen) + (handle-input! screen) + (throttle!))) + (reset! running true)) + + +; Scratch --------------------------------------------------------------------- +(defn -main + "I don't do a whole lot ... yet." + [& args] + (println "Hello, World!")) + +(comment + (reset! running false) + (reset! running true) + + (reset-terrain!) + + (future (main-loop)) + + )