diff --git a/desktop/resources/castle-gate/Untitled.png b/desktop/resources/castle-gate/Untitled.png new file mode 100644 index 00000000..d0f85471 Binary files /dev/null and b/desktop/resources/castle-gate/Untitled.png differ diff --git a/desktop/resources/castle-gate/coinflip.png b/desktop/resources/castle-gate/coinflip.png new file mode 100644 index 00000000..4b599fbe Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.png differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/0.pxi b/desktop/resources/castle-gate/coinflip.pxa/0.pxi new file mode 100644 index 00000000..a9c4c3a5 Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.pxa/0.pxi differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/1.pxi b/desktop/resources/castle-gate/coinflip.pxa/1.pxi new file mode 100644 index 00000000..b9092d95 Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.pxa/1.pxi differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/2.pxi b/desktop/resources/castle-gate/coinflip.pxa/2.pxi new file mode 100644 index 00000000..035f9967 Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.pxa/2.pxi differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/3.pxi b/desktop/resources/castle-gate/coinflip.pxa/3.pxi new file mode 100644 index 00000000..8a0498b2 Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.pxa/3.pxi differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/4.pxi b/desktop/resources/castle-gate/coinflip.pxa/4.pxi new file mode 100644 index 00000000..fb97c25b Binary files /dev/null and b/desktop/resources/castle-gate/coinflip.pxa/4.pxi differ diff --git a/desktop/resources/castle-gate/coinflip.pxa/CelData.plist b/desktop/resources/castle-gate/coinflip.pxa/CelData.plist new file mode 100644 index 00000000..36027d67 --- /dev/null +++ b/desktop/resources/castle-gate/coinflip.pxa/CelData.plist @@ -0,0 +1,26 @@ + + + + + + duration + 0.004999999888241291 + + + duration + 0.004999999888241291 + + + duration + 0.004999999888241291 + + + duration + 0.004999999888241291 + + + duration + 0.004999999888241291 + + + diff --git a/desktop/resources/castle-gate/goon-2-flip.png b/desktop/resources/castle-gate/goon-2-flip.png new file mode 100644 index 00000000..000a3386 Binary files /dev/null and b/desktop/resources/castle-gate/goon-2-flip.png differ diff --git a/desktop/resources/castle-gate/goon-2-flip.pxa/0.pxi b/desktop/resources/castle-gate/goon-2-flip.pxa/0.pxi new file mode 100644 index 00000000..ecf5f3d7 Binary files /dev/null and b/desktop/resources/castle-gate/goon-2-flip.pxa/0.pxi differ diff --git a/desktop/resources/castle-gate/goon-2-flip.pxa/1.pxi b/desktop/resources/castle-gate/goon-2-flip.pxa/1.pxi new file mode 100644 index 00000000..5c056cc3 Binary files /dev/null and b/desktop/resources/castle-gate/goon-2-flip.pxa/1.pxi differ diff --git a/desktop/resources/castle-gate/goon-2-flip.pxa/2.pxi b/desktop/resources/castle-gate/goon-2-flip.pxa/2.pxi new file mode 100644 index 00000000..1161aba7 Binary files /dev/null and b/desktop/resources/castle-gate/goon-2-flip.pxa/2.pxi differ diff --git a/desktop/resources/castle-gate/goon-2-flip.pxa/3.pxi b/desktop/resources/castle-gate/goon-2-flip.pxa/3.pxi new file mode 100644 index 00000000..ec57a35a Binary files /dev/null and b/desktop/resources/castle-gate/goon-2-flip.pxa/3.pxi differ diff --git a/desktop/resources/castle-gate/goon-2-flip.pxa/CelData.plist b/desktop/resources/castle-gate/goon-2-flip.pxa/CelData.plist new file mode 100644 index 00000000..f0b74d60 --- /dev/null +++ b/desktop/resources/castle-gate/goon-2-flip.pxa/CelData.plist @@ -0,0 +1,22 @@ + + + + + + duration + 1 + + + duration + 1 + + + duration + 1 + + + duration + 1 + + + diff --git a/desktop/resources/castle-gate/goon-2.pxa/0.pxi b/desktop/resources/castle-gate/goon-2.pxa/0.pxi index 8c2c348c..3d95b968 100644 Binary files a/desktop/resources/castle-gate/goon-2.pxa/0.pxi and b/desktop/resources/castle-gate/goon-2.pxa/0.pxi differ diff --git a/desktop/resources/castle-gate/goon-2.pxa/1.pxi b/desktop/resources/castle-gate/goon-2.pxa/1.pxi index 76f3ccae..4b4fa12c 100644 Binary files a/desktop/resources/castle-gate/goon-2.pxa/1.pxi and b/desktop/resources/castle-gate/goon-2.pxa/1.pxi differ diff --git a/desktop/src-common/advent/#utils.clj# b/desktop/src-common/advent/#utils.clj# new file mode 100644 index 00000000..bb42ba11 --- /dev/null +++ b/desktop/src-common/advent/#utils.clj# @@ -0,0 +1,272 @@ +(ns advent.utils + (:refer-clojure :exclude [load]) + (:require [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.math :refer :all] + [play-clj.g2d :refer :all] + [clojure.java.io :as io] + [clojure.edn :as edn]) + (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter] + [com.badlogic.gdx.graphics.g2d TextureRegion] + [com.badlogic.gdx.utils.viewport FitViewport] + [com.badlogic.gdx.scenes.scene2d Actor Stage] + [java.lang Object])) + +(defn log-coords [screen entities] + (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] + (println (:input-x screen) (:input-y screen) "->" x y))) + +(def +all-cursors+ [:main :wool :mushrooms :carrot :right :down :left :up :flask :flask-with-contents :trophy :ladder :stick :cat-toy :balloon :frog-legs :teddy :portrait :recipe :glass-eye :motivational-tapes :used-earplugs :grass :slobber :flask-with-strength :medal :kiss :sword :hourglass :mandrake :ball-n-chain :key :rope :crowbar :note-1 :ash :sack-lunch :flies :spear :monocle :feather :spell-component :money :watch :broken-clock :slingshot :camera :walkie-talkies :alarm-clock :walkie-talkie :flask-water :flask-water-stuff :flask-water-stuff-2 :note-2 :magic-slingshot :active-main :shovel :broom]) + +(def settings (atom {:music-volume 50.0 + :sound-volume 75.0})) + +(defn current-music-volume [& [factor]] + (* (Math/pow (/ (:music-volume @settings) 100.0) 2) + 0.25 + (or factor 1.0))) + +(defn current-sound-volume [& [factor]] + (* (Math/pow (/ (:sound-volume @settings) 100.0) 2) + 0.5 + (or factor 1.0))) + +(defn cursor [filename which] + (let [scale 2 + base-cursor (pixmap filename) + target-width (* 16 scale) + target-height (* 16 scale) + resized (Pixmap. target-width target-height (.getFormat base-cursor)) + index (.indexOf +all-cursors+ which)] + #_(Pixmap/setFilter Pixmap$Filter/NearestNeighbour) + (pixmap! resized :draw-pixmap base-cursor (* index 16) 0 16 16 + 0 0 target-width target-height) + resized )) + +(defn save [entities] + (spit "save.edn" (entities :state))) + +(defn load [] + (assoc (edn/read-string (slurp "save.edn")) :active? true)) + +(defn load-settings! [] + (when (.exists (io/file "settings.edn")) + (reset! settings (edn/read-string (slurp "settings.edn"))))) + +(defn save-settings! [] + (spit "settings.edn" @settings)) + +(defn get-font [filename] + (let [font (bitmap-font filename) + tr (bitmap-font! font :get-region) + tx (.getTexture tr)] + (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear) + font)) + +(def +screen-width+ 320) +(def +screen-height+ 240) + +(defn scaler-fn-with-baseline [baseline minimum-size & [maximum-size]] + (let [maximum-size (or maximum-size 1.0)] + (fn [[_ y]] + (if (< y baseline) maximum-size + (let [percent-complete (- 1.0 (/ (- y baseline) (- +screen-height+ baseline))) + range (+ (* percent-complete (- maximum-size minimum-size)) minimum-size)] + range))))) + +(defn get-scale-value [image x y] + (let [base-y (Math/floor (- 240 y)) + other-y (Math/ceil (- 240 y)) + base-amount (- y (Math/floor y)) + other-amount (- 1.0 base-amount) + base-v (-> image + (pixmap! :get-pixel x base-y) + color + (.r)) + other-v (-> image + (pixmap! :get-pixel x other-y) + color + (.r))] + (+ (* base-v base-amount) + (* other-v other-amount)))) + +(defn scaler-fn-from-image [image minimum-size maximum-size] + (let [image (pixmap image) + maximum-size (or maximum-size 1.0)] + (fn [[x y]] + (let [percent-complete (get-scale-value image x y)] + (if (< y 0) + maximum-size + (+ (* percent-complete (- maximum-size minimum-size)) minimum-size)))))) + +(defn dist [x1 y1 x2 y2 & {:keys [y-sign x-sign]}] + (let [y-sign (or y-sign 1.0) + x-sign (or x-sign 1.0) + dx (* (- x1 x2) x-sign) + dy (* y-sign (- y1 y2))] + (Math/sqrt (+ (* dx dx) (* dy dy))))) + + +(defn flip [anim] + (animation (animation! anim :get-frame-duration) + (for [src-frame (animation! anim :get-key-frames) + :let [frame (texture (texture! src-frame :get-texture))]] + (do + (texture! frame :set-region src-frame) + (texture! frame :flip true false) + frame)))) + +(defn split-texture [file [w h] frames] + (let [sheet (texture! (texture file) :split w h)] + (for [i frames] + (aget sheet 0 i)))) + +(defn make-anim [file [w h] speed frames] + (animation speed (split-texture file [w h] frames))) + + +(defn make-bird [screen p] + (let [bird-sheet (texture! (texture "outside-castle/bird.png") :split 1 2) + bird-stand (animation 0.15 (for [i [0 1]] + (aget bird-sheet 0 i)))] + (assoc (animation->texture screen bird-stand) + :x 0 + :y 0 + :baseline 21 + :anim bird-stand + :anim-start 0 + :path (catmull-rom-spline (map #(apply vector-2* %) p) true) + :update-fn (fn [screen entities entity] + (let [speed 0.05 + pos-f (- (* (:total-time screen) speed) (int (* (:total-time screen) speed))) + v (vector-2 0 0) + a (catmull-rom-spline! (:path entity) :value-at v pos-f)] + (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))))) + +(defn path-point [speed screen entities entity] + (* (- (:total-time screen) (:path-start-time entity 0.0)) speed)) + +(defn update-path-location [speed screen entities entity] + (let [pos-in-path (or (:pos-in-path entity) 0.1) + _ (println pos-in-path) + pos-in-path (min pos-in-path 1.0) + v (vector-2 0 0) + a (catmull-rom-spline! (:path entity) :derivative-at v pos-in-path) + pos-in-path (+ pos-in-path (/ (* (:delta-time screen) speed) (.len v)) ) + a (catmull-rom-spline! (:path entity) :value-at v pos-in-path) + ] + + (assoc entity :x (vector-2! v :x) :y (vector-2! v :y) :pos-in-path pos-in-path))) + +(defn find-override [entities [x y]] + (first (concat (filter #(and ((:mouse-in? %) entities x y) + + (:override %)) + (get-in entities [:room :interactions])) + (filter #(and (:mouse-in? %) + ((:mouse-in? %) entities x y) + (not= "ego" (:id %)) + (:script %)) + (vals (get-in entities [:room :entities]))) + (filter #(and ((:mouse-in? %) entities x y) + (:script %)) + (get-in entities [:room :interactions]))))) + + + +(defn remove-interaction [entities id] + (update-in entities [:room :interactions] (fn [i] (remove #(= id (:id %)) i)))) + + +(defn play-sound [snd] + (music! snd :play)) + +(defn stop-sound [snd] + (music! snd :stop)) + +(defn make-music [r] + (doto (music r) (music! :set-looping true))) + + + +(defn apply-tweens [screen entities tweens] + (reduce (fn [e f] + (f e (:total-time screen))) + entities + (vals tweens))) + +(defn intersects? [e [x y]] + (and (:object e) + (< (:x e) x (+ (:x e) (or (:width e) (.getWidth (:object e))))) + (< (:y e) y (+ (:y e) (or (:height e) (.getHeight (:object e))))))) + +(defn get-current-music [entities] + (let [time (get-in entities [:state :time]) + musics (:musics entities) + override-music (musics (get-in entities [:music-override :value])) + current-music (musics (get-in entities [:room :music])) + current-time-music (musics (get-in entities [:room :music time]))] + (or override-music current-music current-time-music))) + + +(defn setup-viewport [screen width height] + (let [cam (orthographic) + viewport (FitViewport. width height cam) + stage (Stage. viewport)] + (update! screen :renderer stage :viewport viewport :camera cam) + (.apply viewport) + [cam viewport stage])) + +(defn unproject + ([screen] + (unproject screen [(:input-x screen) (:input-y screen)]) ) + ([screen [x y]] + (let [pj (.unproject ^FitViewport (:viewport screen) (vector-2 x y)) + x (.x pj) + y (.y pj)] + [x y]))) + +(defn project + ([screen [x y]] + (let [pj (.project ^FitViewport (:viewport screen) (vector-2 x y)) + x (.x pj) + y (.y pj)] + [x y]))) + +(defn contains-point? [x1 y1 width height x y] + (and (< x1 x (+ x1 width)) + (< y1 y (+ y1 height)))) + +(defn update-override [screen entities] + (let [last-pos (unproject screen (get-in entities [:cursor :last-pos]))] + (if (get-in entities [:state :active?]) + (if-let [mouse-override (find-override entities last-pos)] + (assoc-in entities [:cursor :override] (or (:cursor mouse-override) (when (#{:main :active-main} (get-in entities [:cursor :last])) :active-main))) + (assoc-in entities [:cursor :override] nil)) + entities))) + +(def default-night-merge {:r 0.08 :g 0.1 :b 0.36 :multiply-amount 1.0 :hue-amount 1.0}) +(def default-night-merge-sprite {:r 0.08 :g 0.1 :b 0.36 :multiply-amount 0.3 :hue-amount 0.4}) + +(defn clamp-volume [vol] + (max vol 0.005)) + +(defn proximity-volume [entities [x y] & {:keys [scale]}] + (-> (max 0.0 + (- 1.0 (/ (dist x y + (get-in entities [:room :entities :ego :x]) + (get-in entities [:room :entities :ego :y]) + :y-sign 2.0 + :x-sign (/ 1.0 (get-in entities [:room :entities :ego :scale-x]))) + 175.0))) + (* (or scale 1.0)) + (clamp-volume))) + +(defn fast-forward-particle [p] + (particle-effect! p :reset) + (particle-effect! p :start) + + (particle-effect! p :update 10.0) + (dotimes [_ 160] + (particle-effect! p :update 0.2))) diff --git a/desktop/src-common/advent/screens/rooms/castle_gate.clj b/desktop/src-common/advent/screens/rooms/castle_gate.clj index 68617f69..f5edbb18 100644 --- a/desktop/src-common/advent/screens/rooms/castle_gate.clj +++ b/desktop/src-common/advent/screens/rooms/castle_gate.clj @@ -4,9 +4,13 @@ [advent.screens.items :as items] [advent.screens.rooms.common :as common] [advent.utils :as utils] + + [advent.tween :as tween] [clojure.zip :as zip] [play-clj.core :refer :all] [play-clj.ui :refer :all] + + [play-clj.math :refer :all] [play-clj.utils :refer :all] [play-clj.g2d :refer :all])) @@ -94,6 +98,21 @@ :scripts {:walkie-talkies (actions/get-script entities (actions/do-dialogue entities :frankie "Tin cans? What do I need walkie talkies for?"))}))) +(defn make-coin-flip [screen] + (let [coin-flip (utils/make-anim "castle-gate/coinflip.png" [10 10] 0.05 (range 5))] + (assoc (animation->texture screen coin-flip) + :x 212 :y 114 :baseline 240 + :opacity 0.0 + :origin-x 5 + :origin-y 5 + :night-profile :none + :coinflip coin-flip + + + #_#_:anim coin-flip + #_#_:anim-start 0 + #_#_:stand coin-flip))) + (defn make-goon-1 [screen] (let [stand (utils/make-anim "castle-gate/goon-1.png" [12 33] 0.21 [0 0 0 0 0 0 0 0 0 1])] (assoc (animation->texture screen stand) @@ -106,12 +125,21 @@ :stand stand))) (defn make-goon-2 [screen] - (let [stand (utils/make-anim "castle-gate/goon-2.png" [12 32] 0.175 [0 0 0 0 0 0 0 0 0 0 0 0 0 1])] + (let [stand (utils/make-anim "castle-gate/goon-2.png" [12 32] 0.175 [0 0 0 0 0 0 0 0 0 0 0 0 0 1]) + flip (utils/make-anim "castle-gate/goon-2-flip.png" [12 32] 0.05 [1 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ])] (assoc (animation->texture screen stand) :x 208 :y 102 :baseline 138 :scale-x 1.4 :scale-y 1.4 :anim stand + :flip flip + :update-fn (fn [s es e] + (if (and (= (:flip e) (:anim e)) + (animation! (:flip e) + :is-animation-finished + (- (:total-time s) (:anim-start e)))) + (actions/start-animation s e :stand) + e)) :night-profile :sprite :anim-start 0 :stand stand))) @@ -122,12 +150,24 @@ (actions/transition-background entities :inside-castle [280 145]) (actions/walk-to entities :ego [245 90])) +(defn flip-coin [screen entities] + (-> entities + (update-in [:room :entities :coin-flip] (fn [cf] (-> (actions/start-animation screen cf :coinflip) + (assoc :opacity 1.0)))) + (assoc-in [:tweens :coin-y] (tween/tween :coin-y screen [:room :entities :coin-flip :y] 112 175 0.5 :ease tween/ease-out-cubic + :finish (fn [e] + (assoc-in e [:tweens :coin-y-2] (tween/tween :coin-y-2 (assoc screen :total-time (+ 0.5 (:total-time screen))) [:room :entities :coin-flip :y] 174 112 0.5 :ease tween/ease-in-cubic + :finish (fn [e] + (assoc-in e [:room :entities :coin-flip :opacity] 0.0))))))) + (update-in [:room :entities :goon-2] (fn [g] (-> (actions/start-animation screen g :flip)))))) + (defn make [screen] (let [throw-walkie (utils/make-anim "castle-gate/throw-walkie.png" [205 136] 0.1 (flatten [(repeat 55 0) (range 9) (repeat 55 8)])) walkie-visible (animation 1.0 [(last (utils/split-texture "castle-gate/throw-walkie.png" [205 136] (range 9)))]) walkie-invisible (animation 1.0 [(first (utils/split-texture "castle-gate/throw-walkie.png" [205 136] (range 9)))])] (rooms/make :music {:day :town-2 :night :night} + :timers {:taunt [4.0 8.0 flip-coin]} :interactions {:right-dir {:box [300 40 320 83] :script (actions/get-script entities (actions/walk-to entities :ego [301 46] :face :right) @@ -163,6 +203,7 @@ :goon-1 (make-goon-1 screen) :goon-2 (make-goon-2 screen) :outside-particles (common/make-outside-particles) + :coin-flip (make-coin-flip screen) } :walkie-talkies (rooms/make-entity :walkie-talkies (assoc (animation->texture screen walkie-visible) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 38bcbc3a..3ae72383 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -750,6 +750,7 @@ void main() :on-timer (fn [screen [entities]] (when-let [timer-fn (get-in entities [:room :timers (:id screen) 2])] + (println "here") (timer-fn screen entities))) :on-show diff --git a/desktop/src-common/advent/utils.clj b/desktop/src-common/advent/utils.clj index 598ea935..38c2c7db 100644 --- a/desktop/src-common/advent/utils.clj +++ b/desktop/src-common/advent/utils.clj @@ -144,8 +144,12 @@ a (catmull-rom-spline! (:path entity) :value-at v pos-f)] (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))))) +(defn path-point [speed screen entities entity] + (* (- (:total-time screen) (:path-start-time entity 0.0)) speed) + ) + (defn update-path-location [speed screen entities entity] - (let [pos-f (- (* (- (:total-time screen) (:path-start-time entity 0.0)) speed) (int (* (- (:total-time screen) (:path-start-time entity 0.0)) speed))) + (let [pos-f (- (path-point speed screen entities entity) (int (* (- (:total-time screen) (:path-start-time entity 0.0)) speed))) v (vector-2 0 0) a (catmull-rom-spline! (:path entity) :value-at v pos-f)] (assoc entity :x (vector-2! v :x) :y (vector-2! v :y))))