stuff
This commit is contained in:
@@ -3,13 +3,9 @@
|
|||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
["pixi.js" :as pixi]
|
["pixi.js" :as pixi]
|
||||||
[goog.dom :as dom]
|
[goog.dom :as dom]
|
||||||
[frontend.il.entity :as entity]))
|
[cljs.math :as math]
|
||||||
|
[frontend.il.entity :as entity]
|
||||||
(def app
|
[frontend.il.update :as update]))
|
||||||
(pixi/Application.))
|
|
||||||
|
|
||||||
(def stage
|
|
||||||
(.-stage app))
|
|
||||||
|
|
||||||
(def websocket (doto (js/WebSocket. (str "ws://" js/location.host "/ws"))
|
(def websocket (doto (js/WebSocket. (str "ws://" js/location.host "/ws"))
|
||||||
(.addEventListener "open" #(println "Websocket opened."))
|
(.addEventListener "open" #(println "Websocket opened."))
|
||||||
@@ -24,22 +20,30 @@
|
|||||||
:speed 10
|
:speed 10
|
||||||
:renderable nil})
|
:renderable nil})
|
||||||
|
|
||||||
(def world-layer
|
(defn add-entity [state entity-id entity]
|
||||||
(pixi/Container.))
|
|
||||||
|
|
||||||
(def entity-layer
|
|
||||||
(pixi/Container.))
|
|
||||||
|
|
||||||
(def entity-id (atom 1))
|
|
||||||
(def state (atom {:player {:movement {:x 0 :y 0} :keymap {:w 0 :a 0 :s 0 :d 0}}
|
|
||||||
:entities {}}))
|
|
||||||
|
|
||||||
(def lerp 0.1)
|
|
||||||
|
|
||||||
(defn add-entity [entity]
|
|
||||||
(let [id (swap! entity-id inc)]
|
(let [id (swap! entity-id inc)]
|
||||||
(swap! state update-in [:entities] conj {(-> id str keyword) entity})))
|
(swap! state update-in [:entities] conj {(-> id str keyword) entity})))
|
||||||
|
|
||||||
|
(defn on-shoot [state entity-id player-sprite e]
|
||||||
|
(.log js/console e)
|
||||||
|
(let [speed 15
|
||||||
|
image "/sprite/projectile.png"
|
||||||
|
start-x (.-x player-sprite)
|
||||||
|
start-y (.-y player-sprite)
|
||||||
|
target-x (.. e -global -x)
|
||||||
|
target-y (.. e -global -y)
|
||||||
|
dx (- start-x target-x)
|
||||||
|
dy (- start-y target-y)
|
||||||
|
h (js/Math.sqrt (+ (* dx dx) (* dy dy)))
|
||||||
|
vx (* (/ dx h) speed)
|
||||||
|
vy (* (/ dy h) speed)]
|
||||||
|
(.log js/console "tx " target-x " ty " target-y " dx " dx " dy " dy " h " h)
|
||||||
|
(add-entity state entity-id {:sprite image
|
||||||
|
:hyp h
|
||||||
|
:x start-x
|
||||||
|
:y start-y
|
||||||
|
:velocity {:x vx :y vy}})))
|
||||||
|
|
||||||
(defn- velocity-for-key-down [key]
|
(defn- velocity-for-key-down [key]
|
||||||
(case key
|
(case key
|
||||||
"w" -1
|
"w" -1
|
||||||
@@ -48,64 +52,81 @@
|
|||||||
"d" 1
|
"d" 1
|
||||||
{}))
|
{}))
|
||||||
|
|
||||||
(defn handle-key [func event]
|
(defn handle-key [state func event]
|
||||||
(let [key (-> event .-key str/lower-case)
|
(let [key (-> event .-key str/lower-case)
|
||||||
vel (func key)]
|
vel (func key)]
|
||||||
(swap! state update-in [:player :keymap] assoc (keyword key) vel)
|
(swap! state update-in [:player :keymap] assoc (keyword key) vel)
|
||||||
(print @state)
|
|
||||||
(let [{left :d
|
(let [{left :d
|
||||||
right :a
|
right :a
|
||||||
up :w
|
up :w
|
||||||
down :s} (get-in @state [:player :keymap])]
|
down :s} (get-in @state [:player :keymap])
|
||||||
(swap! state update-in [:player :movement] assoc :x (+ left right) :y (+ up down)))))
|
speed (get-in @state [:player :speed] 5)]
|
||||||
|
(swap! state update-in [:player :velocity] assoc
|
||||||
|
:x (* speed (+ left right))
|
||||||
|
:y (* speed (+ up down))))))
|
||||||
|
|
||||||
(defn init-input-handlers []
|
(defn init-input-handlers [state]
|
||||||
(js/window.addEventListener "keydown" (partial handle-key velocity-for-key-down))
|
(js/window.addEventListener "keydown" (partial handle-key state velocity-for-key-down))
|
||||||
(js/window.addEventListener "keyup" (partial handle-key (fn [_] 0))))
|
(js/window.addEventListener "keyup" (partial handle-key state (fn [_] 0))))
|
||||||
|
|
||||||
(defn ticker [t]
|
(defn ticker [app state layers t]
|
||||||
(let [dt (.-deltaTime t)
|
(let [dt (.-deltaTime t)
|
||||||
{entities :entities
|
{world-layer :world-layer} layers
|
||||||
player :player} @state]
|
{:keys [player entities]
|
||||||
(doseq [k (keys entities)]
|
:as latest-state} (-> @state
|
||||||
(let [{:keys [x y renderable]
|
(update/update-entities dt layers)
|
||||||
:as e} (entities k)]
|
(update/update-player dt layers)
|
||||||
(if-not (nil? renderable)
|
(->> (swap! state merge)))
|
||||||
(do
|
sx (- (/ (.. app -screen -width) 2) (player :x))
|
||||||
|
sy (- (/ (.. app -screen -height) 2) (player :y))
|
||||||
|
entity-renderables (->> (vals entities)
|
||||||
|
(remove #(nil? (% :renderable)))
|
||||||
|
(vector))
|
||||||
|
world-renderables (vector {:renderable world-layer :x sx :y sy})
|
||||||
|
player-renderables (vector player
|
||||||
|
(assoc player :renderable (:shootbox player)))
|
||||||
|
things-to-update (conj player-renderable entity-renderables world-renderables)]
|
||||||
|
(println latest-state)
|
||||||
|
(println @state)
|
||||||
|
(println (count things-to-update))
|
||||||
|
(doseq [thing things-to-update]
|
||||||
|
(let [{renderable :renderable
|
||||||
|
x :x
|
||||||
|
y :y} thing]
|
||||||
|
(println "Rendering thing " renderable x y)
|
||||||
(set! (.. renderable -x) x)
|
(set! (.. renderable -x) x)
|
||||||
(set! (.. renderable -y) y))
|
(set! (.. renderable -y) y)))))
|
||||||
(let [renderable (entity/render {:layer entity-layer} e)]
|
|
||||||
(swap! state update-in [:entities k] assoc :renderable renderable)))))
|
|
||||||
(when-not (nil? (:renderable player))
|
|
||||||
(let [{dx :x dy :y} (:movement player)
|
|
||||||
{renderable :renderable
|
|
||||||
speed :speed} player
|
|
||||||
new-x (+ (* dt speed dx) (.-x renderable))
|
|
||||||
new-y (+ (* dt speed dy) (.-y renderable))]
|
|
||||||
(set! (.. renderable -x) new-x)
|
|
||||||
(set! (.. renderable -y) new-y)
|
|
||||||
(swap! state update-in [:player] assoc :x new-x :y new-y)
|
|
||||||
(let [sx (- (/ (.. app -screen -width) 2) new-x)
|
|
||||||
sy (- (/ (.. app -screen -height) 2) new-y)]
|
|
||||||
(set! (.. world-layer -x) sx)
|
|
||||||
(set! (.. world-layer -y) sy))))))
|
|
||||||
|
|
||||||
(defn init []
|
(defn init []
|
||||||
(let [width (.-width js/window.screen)
|
(let [app (doto (pixi/Application.)
|
||||||
height (.-height js/window.screen)]
|
(.init {:resizeTo js/window :autoDensity true :resolution (.-devicePixelRatio js/window)}))
|
||||||
|
state (atom {:player {:velocity {:x 0 :y 0} :keymap {:w 0 :a 0 :s 0 :d 0}}
|
||||||
|
:entities {}})
|
||||||
|
entity-id (atom 1)
|
||||||
|
width (.-width js/window.screen)
|
||||||
|
height (.-height js/window.screen)
|
||||||
|
stage (.-stage app)
|
||||||
|
world-layer (pixi/Container.)
|
||||||
|
entity-layer (pixi/Container.)
|
||||||
|
ui-layer (pixi/Container.)
|
||||||
|
layers {:entity-layer entity-layer
|
||||||
|
:world-layer world-layer
|
||||||
|
:ui-layer ui-layer}]
|
||||||
(.. app
|
(.. app
|
||||||
(init #js {:width width :height height :backgroundColor 0x222})
|
(init #js {:width width :height height :backgroundColor 0x222})
|
||||||
(then (fn [_]
|
(then (fn [_]
|
||||||
(dom/appendChild (dom/getElement "app") (.-canvas app))
|
(dom/appendChild (dom/getElement "app") (.-canvas app))
|
||||||
(init-input-handlers)
|
(init-input-handlers state)
|
||||||
(add-entity {:x 500 :y 500 :sprite "https://pixijs.com/assets/bunny.png"})
|
(add-entity state entity-id {:x 500 :y 500 :sprite "https://pixijs.com/assets/bunny.png"})
|
||||||
(-> (.-stage app)
|
(-> stage
|
||||||
(.addChild world-layer)
|
(.addChild world-layer) ; Bottom of the layer stack
|
||||||
(.addChild entity-layer))
|
(.addChild entity-layer) ; Middle of the layer stack
|
||||||
|
(.addChild ui-layer)) ; Top of the layer stack
|
||||||
(let [e (merge {:x (-> width (/ 2) (int))
|
(let [e (merge {:x (-> width (/ 2) (int))
|
||||||
:y (-> height (/ 2) (int))}
|
:y (-> height (/ 2) (int))}
|
||||||
base-player)
|
base-player)
|
||||||
p (entity/render {:layer entity-layer} e)
|
p (entity/render entity-layer e)
|
||||||
player (assoc e :renderable p)]
|
sb (entity/player-shoot-box entity-layer (partial on-shoot state entity-id p))
|
||||||
|
player (assoc e :renderable p :shootbox sb)]
|
||||||
(swap! state update-in [:player] merge player)
|
(swap! state update-in [:player] merge player)
|
||||||
(.. app -ticker (add ticker))))))))
|
(.. app -ticker (add (partial ticker app state layers)))))))))
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
(ns frontend.il.entity
|
(ns frontend.il.entity
|
||||||
(:require ["pixi.js" :as pixi]))
|
(:require ["pixi.js" :as pixi]))
|
||||||
|
|
||||||
(defn render [render-info entity]
|
(defn render [layer entity]
|
||||||
(let [{x :x
|
(let [{x :x
|
||||||
y :y
|
y :y
|
||||||
sprite :sprite} entity
|
sprite :sprite} entity
|
||||||
{^js layer :layer} render-info
|
|
||||||
entity-sprite (pixi/Sprite.)]
|
entity-sprite (pixi/Sprite.)]
|
||||||
(print "Creating sprite: " sprite " for entity " entity)
|
(print "Creating sprite: " sprite " for entity " entity)
|
||||||
(.. pixi -Assets
|
(.. pixi -Assets
|
||||||
@@ -16,5 +15,16 @@
|
|||||||
(set! (.. entity-sprite -anchor -y) 0.5)
|
(set! (.. entity-sprite -anchor -y) 0.5)
|
||||||
(set! (.. entity-sprite -x) x)
|
(set! (.. entity-sprite -x) x)
|
||||||
(set! (.. entity-sprite -y) y)
|
(set! (.. entity-sprite -y) y)
|
||||||
(.. layer (addChild entity-sprite)))))
|
(.addChild layer entity-sprite))))
|
||||||
entity-sprite))
|
entity-sprite))
|
||||||
|
|
||||||
|
(defn player-shoot-box [layer callback]
|
||||||
|
(let [g (pixi/Graphics.)
|
||||||
|
width (- (.-width js/window.screen) 80)
|
||||||
|
height (- (.-height js/window.screen) 80)]
|
||||||
|
(set! (.-eventMode g) "static")
|
||||||
|
(-> g
|
||||||
|
(.on "pointertap" callback)
|
||||||
|
(.rect (/ (- width) 2) (/ (- height) 2) width height)
|
||||||
|
(.fill #js {:color "red" :alpha 0.1})
|
||||||
|
(->> (.addChild layer)))))
|
||||||
|
|||||||
33
src/frontend/il/update.cljs
Normal file
33
src/frontend/il/update.cljs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
(ns frontend.il.update
|
||||||
|
(:require
|
||||||
|
[frontend.il.entity :as entity]))
|
||||||
|
|
||||||
|
(defn apply-velocity [e dt]
|
||||||
|
(if (contains? e :velocity)
|
||||||
|
(let [{x :x y :y vel :velocity} e
|
||||||
|
{vx :x vy :y} vel
|
||||||
|
dtvx (* dt vx)
|
||||||
|
dtvy (* dt vy)]
|
||||||
|
(assoc e :x (+ x dtvx) :y (+ y dtvy)))
|
||||||
|
e))
|
||||||
|
|
||||||
|
(defn apply-renderable [e layers]
|
||||||
|
(if-not (contains? e :renderable)
|
||||||
|
(let [{entity-layer :entity-layer} layers
|
||||||
|
renderable (entity/render entity-layer e)]
|
||||||
|
(assoc e :renderable renderable))
|
||||||
|
e))
|
||||||
|
|
||||||
|
(defn update-entities [state dt layers]
|
||||||
|
(let [{entities :entities} state
|
||||||
|
new-entities (update-vals entities #(-> %
|
||||||
|
(apply-renderable layers)
|
||||||
|
(apply-velocity dt)))]
|
||||||
|
(assoc state :entities new-entities)))
|
||||||
|
|
||||||
|
(defn update-player [state dt layers]
|
||||||
|
(let [{player :player} state
|
||||||
|
updated-player (-> player
|
||||||
|
(apply-renderable layers)
|
||||||
|
(apply-velocity dt))]
|
||||||
|
(assoc state :player updated-player)))
|
||||||
Reference in New Issue
Block a user