Pacman movement! Basically.
This commit is contained in:
parent
ab69260091
commit
66fcd6a3cf
|
@ -2,7 +2,7 @@
|
|||
(local dim (require :game.dim))
|
||||
(local {: defmethod} (util.require :lib.multimethod))
|
||||
(local {: direct : draw : update} (util.require :game.entity))
|
||||
(local {: vec*} (util.require :game.helpers))
|
||||
(local {: vec* : vec+ : edge : edge-crosses} (util.require :game.helpers))
|
||||
(local map (require :game.tilemap))
|
||||
|
||||
(local pacman (util.hot-table ...))
|
||||
|
@ -37,13 +37,67 @@
|
|||
; their edges filed off!)
|
||||
; I think Bomberman actually does this too
|
||||
|
||||
(defmethod update :pacman (fn [entity dt rules]
|
||||
(fn tile-at [x y rules]
|
||||
(-?> [x y]
|
||||
(map.world-to-tile)
|
||||
(rules.tile-at)))
|
||||
|
||||
(fn collides? [[x y] rules]
|
||||
(let [tile (tile-at x y rules)]
|
||||
(and tile (or tile.bomb tile.wall))))
|
||||
|
||||
(fn horizontal [c copp] [c copp])
|
||||
(fn vertical [c copp] [copp c])
|
||||
(fn perp-move? [dprev doppnext] (and (not= dprev 0) (not= doppnext 0)))
|
||||
(fn try-perp-turn [entity d make-xy rules]
|
||||
(let [[c copp] (make-xy (table.unpack entity.pos))
|
||||
posperp (vec+ entity.pos (make-xy (if (> d 0) dim.tilesize (- dim.tilesize)) 0))
|
||||
[xcenter ycenter] (vec+ (vec* (map.world-to-tile posperp) dim.tilesize) dim.halftile)
|
||||
[ccenter coppcenter] (make-xy xcenter ycenter)
|
||||
turn-allowed? (and (> copp (- coppcenter (/ dim.tilesize 4)))
|
||||
(< copp (+ coppcenter (/ dim.tilesize 4))))]
|
||||
(when (and turn-allowed? (not (collides? posperp rules)))
|
||||
(set entity.vel (make-xy d 0))
|
||||
(set entity.opp-target coppcenter))))
|
||||
|
||||
(fn rev-move? [dprev dprevopp dnext]
|
||||
; currently moving on this axis or not moving at all
|
||||
(and (or (not= dprev 0) (and (= dprev 0) (= dprevopp 0)))
|
||||
; attempting to move in a new direction
|
||||
(not= dnext 0) (not= dprev dnext)))
|
||||
|
||||
(fn update-direction [entity rules]
|
||||
(let [[dx dy] entity.vel
|
||||
[dxkey dykey] (direct pacman.keymap (* dim.tilesize 4))
|
||||
turn-attempted (and (or (not= dxkey 0) (not= dykey 0))
|
||||
(or (not= dxkey dx) (not= dykey dy)))]
|
||||
(when turn-attempted
|
||||
(set entity.vel [dxkey dykey])))))
|
||||
[dxkey dykey] (direct pacman.keymap (* dim.tilesize 4))]
|
||||
; two possible movement cases:
|
||||
; 1. Pacman wants to change direction perpendicular to how he is currently moving
|
||||
; 2. Pacman wants to change direction on the axis he is currently moving on
|
||||
; Case 1 takes priority over case 2
|
||||
(if (perp-move? dy dxkey) (try-perp-turn entity dxkey horizontal rules)
|
||||
(perp-move? dx dykey) (try-perp-turn entity dykey vertical rules)
|
||||
(rev-move? dx dy dxkey) (set entity.vel [dxkey 0])
|
||||
(rev-move? dy dx dykey) (set entity.vel [0 dykey]))))
|
||||
|
||||
(fn move [entity dt rules]
|
||||
(let [[dx dy] (vec* entity.vel dt)
|
||||
make-xy (if (= dy 0) horizontal vertical)
|
||||
[c copp] (make-xy (table.unpack entity.pos))
|
||||
[dc _] (make-xy dx dy)
|
||||
(edge-prev edge-next) (edge c dc dim.halftile)
|
||||
(crosses? edge-snap) (edge-crosses edge-prev edge-next dim.tilesize)
|
||||
_ (print edge-prev edge-next edge-snap)
|
||||
cnext (if (and crosses? (collides? (make-xy edge-next copp) rules))
|
||||
(+ c (- edge-snap edge-prev))
|
||||
(+ c dc))
|
||||
dcopp (if (= entity.opp-target nil) 0
|
||||
(-> (- entity.opp-target copp)
|
||||
(math.min (* dt dim.tilesize 4))
|
||||
(math.max (* dt dim.tilesize -4))))]
|
||||
(set entity.pos (make-xy cnext (+ copp dcopp)))))
|
||||
|
||||
(defmethod update :pacman (fn [entity dt rules]
|
||||
(update-direction entity rules)
|
||||
(move entity dt rules)))
|
||||
|
||||
(fn pacman.new [pos]
|
||||
{: pos :vel [0 0] :entity :pacman})
|
||||
|
|
|
@ -39,8 +39,12 @@
|
|||
(values (+ c pos-offset) (+ c dc pos-offset))))
|
||||
|
||||
(fn edge-crosses [c1 c2 width]
|
||||
(if (= c1 c2) false
|
||||
(or (= (% c1 width) 0) (= (% c2 width) 0)) true
|
||||
(not= (math.floor (/ c1 width)) (math.floor (/ c2 width)))))
|
||||
(let [t1 (math.floor (/ c1 width))
|
||||
t2 (math.floor (/ c2 width))]
|
||||
(if (= c1 c2) false
|
||||
(= (% c1 width) 0) (values true c1)
|
||||
(= (% c2 width) 0) (values true c2)
|
||||
(not= t1 t2) (values true (* (math.max t1 t2) width))
|
||||
false)))
|
||||
|
||||
{: dir-from-key : vec* : vec+ : vec-op : all-coordinates : edge : edge-crosses}
|
||||
|
|
Loading…
Reference in a new issue