util = require "util" local player = require "classes.player" local Vector3 = require "types.vector3" local List = require "types.list" local Feed = require "classes.feed" ---@type List local feed = List() local Duck = require "classes.duck" ---@type List local ducks = List() local function create_feed(position, direction) local f = Feed.new(position, direction) feed:push(f) end local function delete_feed(f) feed:remove_value(f) end local function duck_seek_feed(duck) local eligible_feeds = feed:filter( function (f) return f.occupied == false end ) if eligible_feeds:is_empty() then return end duck:start_chase( eligible_feeds:sorted( function(a, b) return a.position:distance_squared_to(duck.position) < b.position:distance_squared_to(duck.position) end ):pop_front() ) end -- called every frame, with constant delta time function game_tick() -- ctx.initialization_needed is true first frame and every time dynamic reload is performed if ctx.initialization_needed then audio_play{audio = "music/bg1.xm", loops = true, channel = "music"} -- ctx.udata persists on reload ctx.udata = { capture = false, } player.ThrowPressed:connect(create_feed) -- spawn some ducks for i = 1, 5 do local duck = Duck.new(Vector3(0, 0, -math.random() * 10.0):rotated(Vector3.UP, util.random_float(-math.pi, math.pi))) ducks:push(duck) duck.AteFeed:connect(delete_feed) duck.SeekFeed:connect(duck_seek_feed) duck.index = i end end ctx.mouse_capture = ctx.udata.capture input_action{name = "toggle_mouse", control = "ESCAPE"} if input_action_just_pressed{name = "toggle_mouse"} then ctx.udata.capture = not ctx.udata.capture end for _, v in ipairs(feed) do v:tick(ctx) end for _, v in ipairs(ducks) do v:tick(ctx) end player:tick(ctx) local q = util.create_plane_quad(Vector3(0, 0, 0), Vector3.UP, 20) local params = { texture = "images/measure001a.png", texture_region = { x = 0, y = 0, w = 512, h = 512 }, } draw_quad(util.merge(q, params)) end