diff options
| -rw-r--r-- | game.fnl | 4 | ||||
| -rw-r--r-- | player.fnl | 66 | ||||
| -rw-r--r-- | world.fnl | 9 |
3 files changed, 57 insertions, 22 deletions
@@ -166,13 +166,15 @@ (fn update [dt set-mode] (: current-world :update dt) + (: current-player :update dt) (let [(camera-x camera-y) (: current-camera :focus-on-object current-player dt)] (tset current-camera :x-pos camera-x) (tset current-camera :y-pos camera-y))) (fn keypressed [key set-mode] (let [method (if (= key "right") :move-right - (= key "left") :move-left)] + (= key "left") :move-left + (= key "z") :jump)] (when method (: current-player method)))) @@ -46,15 +46,6 @@ grounded 0 :else (+ (. player :y-vel) (* gravity dt))))) -(fn impact-bottom [player] - (tset player :grounded true)) - -(fn impact-top [player]) - -(fn impact-left [player]) - -(fn impact-right [player]) - (fn move-right [player] (tset player :orientation :right) (tset player :action :right true) @@ -75,6 +66,11 @@ (tset player :action :left false) (tset player :x-vel (/ (. player :x-vel) 2))) +(fn jump [player] + (tset player :action :jump true) + (when (> 10 (math.abs (. player :y-vel))) + (tset player :y-vel (- (. player :goal-y-vel))))) + (local player-sheet {:img (love.graphics.newImage "art/swanky.png") :orientation-offset 128 @@ -82,8 +78,46 @@ :padding-x 8 :padding-y 10}) (fn draw-player [player x y] - (let [x-offset (if (= (. player :orientation) :left) 4 0)] - (draw.tile x y player-sheet x-offset 0))) + (let [x-offset (if (= (. player :orientation) :left) 4 0) + x-offset (+ x-offset (. player :animation-x-offset)) + y-offset (. player :animation-y-offset)] + (draw.tile x y player-sheet x-offset y-offset))) + +(fn next-frame [frame timer] + (if (> 0 timer) + (if (>= (+ 1 frame) 4) 0 (+ 1 frame)) + frame)) + +(fn next-player-animation-x-offset [player] + (let [timer (. player :animation-timer) + frame (. player :animation-x-offset) + jumping (. player :action :jump) + moving (or (. player :action :right) (. player :action :left)) + grounded (> 10 (math.abs (. player :y-vel))) + walking (and moving grounded)] + (if jumping (if (> 3 frame) (next-frame frame timer) 3) + walking (next-frame frame timer) + :else 0))) + +(fn next-player-animation-y-offset [player] + (let [jumping (. player :action :jump) + moving (or (. player :action :right) (. player :action :left)) + grounded (> 10 (math.abs (. player :y-vel))) + walking (and moving grounded)] + (if jumping 2 + walking 1 + :else 0))) + +(fn update-player-animations [player dt] + (when (> 10 (math.abs (. player :y-vel))) + (tset player :action :jump false)) + (let [timer (. player :animation-timer)] + (tset player :animation-timer (- timer dt))) + (tset player :animation-x-offset (next-player-animation-x-offset player)) + (tset player :animation-y-offset (next-player-animation-y-offset player)) + (when (> 0 (. player :animation-timer)) + (tset player :animation-timer 0.1))) + ;; Returns a new player object. (fn new-player [] @@ -100,9 +134,9 @@ :y-vel 0 :orientation :right - ;; :frame 0 - ;; :frame-delay 4 - ;; :frame-timer 4 + :animation-x-offset 0 + :animation-y-offset 0 + :animation-timer 0 :grounded false @@ -121,7 +155,9 @@ :stop-right stop-right :move-left move-left :stop-left stop-left + :jump jump - :draw draw-player}) + :draw draw-player + :update update-player-animations}) {:new new-player} @@ -261,30 +261,27 @@ (tset player :x-pos x) (tset player :y-pos y) + (tset player :grounded false) (each [_ collision (ipairs collisions)] ;; Touching top of surface. (when (> 0 (. collision :normal :y)) - (: player :impact-bottom) + (tset player :grounded true) (slime-tile world (. collision :other) :top)) ;; Touching bottom of surface. (when (< 0 (. collision :normal :y)) - (: player :impact-top) (slime-tile world (. collision :other) :bottom)) ;; Touching left of surface. (when (> 0 (. collision :normal :x)) - (: player :impact-right) (slime-tile world (. collision :other) :left)) ;; Touching right of surface. (when (< 0 (. collision :normal :x)) - (: player :impact-left) (slime-tile world (. collision :other) :right))) (tset player :x-vel (: player :next-x-vel dt)) - (tset player :y-vel (: player :next-y-vel dt)) - (tset player :grounded false))) + (tset player :y-vel (: player :next-y-vel dt)))) ;; Loads the map of the given name into a new world containing `player'. Will ;; error out if either 'maps/${name}.png' or 'maps/${name}.fnl' do not exist. |