! Copyright (C) 2024 CapitalEx. ! See https://factorcode.org/license.txt for BSD license. USING: accessors kernel literals math math.vectors namespaces random ranges raylib sequences ; IN: flappy-bird SYMBOL: :delta-time CONSTANT: ZOOMED $[ \ Camera2D new [ drop 2.0 ] change-zoom ] : with-draw ( q -- ) begin-drawing SKYBLUE clear-background ZOOMED begin-mode-2d call end-mode-2d end-drawing ; inline : with-dt ( q -- ) get-frame-time :delta-time rot with-variable ; inline : tick-game ( update draw -- ) '[ @ _ with-draw ] with-dt ; inline SYMBOL: :player SYMBOL: :pipes SYMBOL: :timer TUPLE: pipe position flip-sprite ; CONSTANT: PIPE-BOUNDS $[ 124 276 [a..b] ] : spawn-pipe ( -- ) :pipes get-global 325 PIPE-BOUNDS random tuck f \ pipe boa suffix! swap { 0 396 } v- t \ pipe boa suffix! drop ; TUPLE: player position velocity ; : off-screen? ( -- ? ) :player get-global position>> y>> 300.0 > ; : hit-pipe? ( -- ? ) :player get-global position>> first2 24 24 \ Rectangle boa :pipes get-global [ position>> first2 48 300 \ Rectangle boa check-collision-recs ] with any? ; : fall ( player -- player ) [ { 0 900 } get-frame-time v*n v+ ] change-velocity ; : accelerate ( player -- player ) dup velocity>> '[ _ get-frame-time v*n v+ ] change-position ; : flap ( player -- player ) [ drop 0 -250 ] change-velocity ; : create-player ( -- ) 24 138 0 0 \ player boa :player set-global ; : create-pipes ( -- ) V{ } clone :pipes set-global ; : create-timer ( -- ) 0 :timer set-global ; : reset ( -- ) create-player create-pipes create-timer ; : draw ( -- ) :player get-global position>> first2 24 24 YELLOW draw-rectangle :pipes get-global [ position>> first2 48 300 GREEN draw-rectangle ] each ; : update ( -- ) :player get-global KEY_UP is-key-down [ flap ] [ fall ] if accelerate drop :pipes get-global [ [ { -100 0 } get-frame-time v*n v+ ] change-position drop ] each :timer get-global get-frame-time + dup 1.5 > [ drop 0 spawn-pipe ] when :timer set-global off-screen? hit-pipe? or [ reset ] when ; : main ( -- ) 800 600 "Flappy Bird" init-window reset [ window-should-close ] [ [ update ] [ draw ] tick-game ] until close-window ; MAIN: main