small refactorings, indentation style

master
Josha von Gizycki 7 years ago
parent 9be3f6b848
commit 25adfdb6fc

@ -1,50 +1,40 @@
(ns topdown2d.core
(:require
[topdown2d.demoscene :as demoscene]
[topdown2d.input :as input]))
[topdown2d.demoscene :as demoscene]
[topdown2d.input :as input]))
(enable-console-print!)
(def gamestate {
:canvas (.getElementById js/document "gamecanvas")
:ctx (.getContext (.getElementById js/document "gamecanvas") "2d")
:target-fps 40
:timing {
; msecs of previous frame
:prev 0
; msecs of current frame
:now 0
; fps resulting of prev and now
:fps 0
; difference between prev and now in seconds
:elapsed 0
}
; width and height of the canvas
:dimensions {
:w 600
:h 400
}
:input {
:dir :?
}
; currently active scene
:scene :demo
:scenes {
:demo {
:update demoscene/update-scene
:draw demoscene/draw-scene
:init demoscene/init
:data {}
}
}
})
(def gamestate
{:canvas (.getElementById js/document "gamecanvas")
:ctx (.getContext (.getElementById js/document "gamecanvas") "2d")
:target-fps 40
:timing {;; msecs of previous frame
:prev 0
;; msecs of current frame
:now 0
;; fps resulting of prev and now
:fps 0
;; difference between prev and now in seconds
:elapsed 0}
;; width and height of the canvas
:dimensions {:w 600
:h 400}
:input {:dir :?}
;; currently active scene
:scene :demo
:scenes {:demo {:update demoscene/update-scene
:draw demoscene/draw-scene
:init demoscene/init
:data {}}}})
(defn set-timing
"sets the current time at the given key"
[state timingkey]
(assoc-in state
[:timing timingkey]
(.now js/performance)))
(assoc-in
state
[:timing timingkey]
(.now js/performance)))
(defn set-fps
"calculates the current fps using the elapsed time"
@ -56,11 +46,10 @@
(defn set-elapsed-seconds
"calculates and writes the elapsed seconds since the last frame"
[gamestate]
(assoc-in gamestate
[:timing :elapsed]
(/
(-
(get-in gamestate [:timing :now])
(assoc-in
gamestate
[:timing :elapsed]
(/ (-(get-in gamestate [:timing :now])
(get-in gamestate [:timing :prev]))
1000)))
@ -77,12 +66,12 @@
"updates timing information and the current scene"
[gamestate]
(-> gamestate
(assoc-in [:input :dir] (input/dir))
(set-timing :now)
(set-elapsed-seconds)
(set-fps)
(update-scene)
(set-timing :prev)))
(assoc-in [:input :dir] (input/dir))
(set-timing :now)
(set-elapsed-seconds)
(set-fps)
(update-scene)
(set-timing :prev)))
(defn draw-fps
"draws the current fps"
@ -90,22 +79,22 @@
(let [ctx (:ctx gamestate)]
(aset ctx "fillStyle" "white")
(.fillRect
ctx
0 0 13 13)
ctx
0 0 13 13)
(aset ctx "fillStyle" "black")
(aset ctx "font" "10px monospace")
(.fillText
(:ctx gamestate)
(int (get-in gamestate [:timing :fps]))
0 10)))
(:ctx gamestate)
(int (get-in gamestate [:timing :fps]))
0 10)))
(defn draw-step
"clears the canvas, draws fps and invokes the scene draw function"
[gamestate]
(.clearRect (:ctx gamestate)
0 0
(get-in gamestate [:dimensions :w])
(get-in gamestate [:dimensions :h]))
0 0
(get-in gamestate [:dimensions :w])
(get-in gamestate [:dimensions :h]))
(let [scenekey (:scene gamestate)
scene (scenekey (:scenes gamestate))
drawfunc (:draw scene)]
@ -119,32 +108,34 @@
[gamestate]
(let [newstate (update-step gamestate)]
(draw-step newstate)
; calculate the duration of update-step and draw-step
; substract that from the wait time to reach target-fps
; more accurately
;; calculate the duration of update-step and draw-step
;; substract that from the wait time to reach target-fps
;; more accurately
(let [now (get-in newstate [:timing :now])
duration (- (.now js/performance) now)]
(.setTimeout js/window
(fn []
(.requestAnimationFrame js/window
#(mainloop newstate)))
(/
(- 1000 duration)
(:target-fps gamestate))))))
(fn []
(.requestAnimationFrame
js/window
#(mainloop newstate)))
(/
(- 1000 duration)
(:target-fps gamestate))))))
(defn init-scenes
"initiates the scene data maps using their respective init functions"
[]
(assoc
gamestate
:scenes
(reduce
(fn [scenes [scenekey scenedata]]
(let [initfunc (:init scenedata)
newdata (initfunc gamestate scenedata)]
(assoc scenes
scenekey newdata)))
{}
(:scenes gamestate))))
gamestate
:scenes
(reduce
(fn [scenes [scenekey scenedata]]
(let [initfunc (:init scenedata)
newdata (initfunc gamestate scenedata)]
(assoc
scenes
scenekey newdata)))
{}
(:scenes gamestate))))
(mainloop (init-scenes))

@ -1,47 +1,38 @@
(ns topdown2d.demoscene
(:require
[topdown2d.collision :as collision]
[topdown2d.input :as input]
[topdown2d.sprites :as sprites]))
[topdown2d.collision :as collision]
[topdown2d.input :as input]
[topdown2d.sprites :as sprites]))
(defn init [gamestate scenedata]
(assoc scenedata
:data {
:player {
:x (- (/ (get-in gamestate [:dimensions :w]) 2) 32)
:y (- (/ (get-in gamestate [:dimensions :h]) 2) 32)
:w 64 :h 64
:d :s
:sprite {
:image (.getElementById js/document "demo-player")
:size 64
:rows {
:w 1 :e 3
:n 0 :s 2
:? 2
}
:cycle {
:pos 0
:from 1 :count 8
:last-cycle 0
; seconds per cycle
:spc 0.08
}
}
}
:viewport {
:image (.getElementById js/document "demo-background")
:keep-in {
:x 0 :y 0
:w 2239 :h 2235
}
:x 1 :y 1
:d :?
:pps 350
:w (get-in gamestate [:dimensions :w])
:h (get-in gamestate [:dimensions :h])
}
}))
(assoc
scenedata
:data
{:player {:x (- (/ (get-in gamestate [:dimensions :w]) 2) 32)
:y (- (/ (get-in gamestate [:dimensions :h]) 2) 32)
:w 64 :h 64
:d :s
:sprite
{:image (.getElementById js/document "demo-player")
:size 64
:rows {:w 1 :e 3
:n 0 :s 2
:? 2}
:cycle {:pos 0
:from 1
:count 8
:last-cycle 0
;; seconds per cycle
:spc 0.08}}}
:viewport {:image (.getElementById js/document "demo-background")
:keep-in {:x 0 :y 0
:w 2239 :h 2235}
:x 1 :y 1
:d :?
:pps 350
:w (get-in gamestate [:dimensions :w])
:h (get-in gamestate [:dimensions :h])
}}))
(defn update-player [gamestate player dir]
(let [old-dir (:d player)
@ -49,33 +40,33 @@
(as-> player p
(assoc p :d new-dir)
(if (= :? dir)
(sprites/reset-cycle player)
(sprites/proc-cycle gamestate p)))))
(sprites/reset player)
(sprites/proc gamestate p)))))
(defn update-viewport [gamestate viewport dir]
(collision/move-inside
(assoc viewport :d dir)
(:keep-in viewport)
(collision/pps->px gamestate viewport)))
(assoc viewport :d dir)
(:keep-in viewport)
(collision/pps->px gamestate viewport)))
(defn update-scene [gamestate scenedata]
(let [player (get-in scenedata [:data :player])
viewport (get-in scenedata [:data :viewport])
dir (get-in gamestate [:input :dir])]
(-> scenedata
(assoc-in [:data :player]
(update-player gamestate player dir))
(assoc-in [:data :viewport]
(update-viewport gamestate viewport dir)))))
(assoc-in [:data :player]
(update-player gamestate player dir))
(assoc-in [:data :viewport]
(update-viewport gamestate viewport dir)))))
(defn draw-scene [gamestate scenedata]
(let [viewport (get-in scenedata [:data :viewport])
{:keys [x y w h background]} viewport]
(.drawImage
(:ctx gamestate)
(:image viewport)
x y w h
0 0 w h))
(:ctx gamestate)
(:image viewport)
x y w h
0 0 w h))
(sprites/draw
(:ctx gamestate)
(get-in scenedata [:data :player])))
(:ctx gamestate)
(get-in scenedata [:data :player])))

@ -5,18 +5,20 @@
(defn keydown? [code]
(get @keysdown (name code) false))
(.addEventListener js/document
"keydown"
(fn [event]
(swap! keysdown #(assoc % (.-code event) true))
false))
(.addEventListener
js/document
"keydown"
(fn [event]
(swap! keysdown #(assoc % (.-code event) true))
false))
(.addEventListener js/document
"keyup"
(fn [event]
(swap! keysdown
#(assoc % (.-code event) false))
false))
(.addEventListener
js/document
"keyup"
(fn [event]
(swap! keysdown
#(assoc % (.-code event) false))
false))
(defn dir []
(cond

@ -1,35 +1,42 @@
(ns topdown2d.sprites)
(defn proc-cycle [gamestate obj]
(defn- reset-cycle [obj]
(let [cycle (get-in obj [:sprite :cycle])
{:keys [pos from] maxpos :count} cycle
reset-position? (> (inc pos) maxpos)]
(-> obj
;; set position
(assoc-in
[:sprite :cycle :pos]
(if reset-position?
from
(inc pos)))
;; timestamp of last cycle is 0
(assoc-in
[:sprite :cycle :last-cycle]
0))))
(defn proc [gamestate obj]
(let [sprite (:sprite obj)
sprite-cycle (:cycle sprite)
from (:from sprite-cycle)
maxpos (:count sprite-cycle)
{:keys [pos spc last-cycle]} sprite-cycle
restart? (> (inc pos) maxpos)
{:keys [spc last-cycle]} sprite-cycle
elapsed (get-in gamestate [:timing :elapsed])]
; new sprite frame?
;; new sprite frame?
(if (> (+ last-cycle elapsed) spc)
; start cycle from new?
; reset last-cycle
(-> obj
(assoc-in
[:sprite :cycle :pos]
(if restart? from (inc pos)))
(assoc-in
[:sprite :cycle :last-cycle]
0))
(update-in obj
[:sprite :cycle :last-cycle]
#(+ % elapsed)))))
(reset-cycle obj)
;; no new sprite, increase last-cycle
(update-in
obj
[:sprite :cycle :last-cycle]
#(+ % elapsed)))))
(defn reset-cycle [obj]
(defn reset [obj]
(assoc-in
obj
[:sprite :cycle :pos]
0))
obj
[:sprite :cycle :pos]
0))
(defn pos-in-sprite [sprite d]
(defn- pos-in-sprite [sprite d]
(let [{:keys [size rows]} sprite
pos (get-in sprite [:cycle :pos])
row (d rows)]
@ -41,7 +48,8 @@
sprite-size (:size sprite)
sprite-cycle (:cycle sprite)
pos (pos-in-sprite sprite d)]
(.drawImage ctx
image
(:x pos) (:y pos) sprite-size sprite-size
x y sprite-size sprite-size)))
(.drawImage
ctx
image
(:x pos) (:y pos) sprite-size sprite-size
x y sprite-size sprite-size)))

Loading…
Cancel
Save