diff --git a/actual game/Agent1.png b/actual game/Agent1.png new file mode 100644 index 0000000..5272f80 Binary files /dev/null and b/actual game/Agent1.png differ diff --git a/actual game/Agent2.png b/actual game/Agent2.png new file mode 100644 index 0000000..d41ad88 Binary files /dev/null and b/actual game/Agent2.png differ diff --git a/actual game/Agent3.png b/actual game/Agent3.png new file mode 100644 index 0000000..1bd4c8b Binary files /dev/null and b/actual game/Agent3.png differ diff --git a/actual game/libs/anim8.lua b/actual game/libs/anim8.lua new file mode 100644 index 0000000..b7a6819 --- /dev/null +++ b/actual game/libs/anim8.lua @@ -0,0 +1,302 @@ +local anim8 = { + _VERSION = 'anim8 v2.3.1', + _DESCRIPTION = 'An animation library for LÖVE', + _URL = 'https://github.com/kikito/anim8', + _LICENSE = [[ + MIT LICENSE + + Copyright (c) 2011 Enrique García Cota + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ]] +} + +local Grid = {} + +local _frames = {} + +local function assertPositiveInteger(value, name) + if type(value) ~= 'number' then error(("%s should be a number, was %q"):format(name, tostring(value))) end + if value < 1 then error(("%s should be a positive number, was %d"):format(name, value)) end + if value ~= math.floor(value) then error(("%s should be an integer, was %f"):format(name, value)) end +end + +local function createFrame(self, x, y) + local fw, fh = self.frameWidth, self.frameHeight + return love.graphics.newQuad( + self.left + (x-1) * fw + x * self.border, + self.top + (y-1) * fh + y * self.border, + fw, + fh, + self.imageWidth, + self.imageHeight + ) +end + +local function getGridKey(...) + return table.concat( {...} ,'-' ) +end + +local function getOrCreateFrame(self, x, y) + if x < 1 or x > self.width or y < 1 or y > self.height then + error(("There is no frame for x=%d, y=%d"):format(x, y)) + end + local key = self._key + _frames[key] = _frames[key] or {} + _frames[key][x] = _frames[key][x] or {} + _frames[key][x][y] = _frames[key][x][y] or createFrame(self, x, y) + return _frames[key][x][y] +end + +local function parseInterval(str) + if type(str) == "number" then return str,str,1 end + str = str:gsub('%s', '') -- remove spaces + local min, max = str:match("^(%d+)-(%d+)$") + assert(min and max, ("Could not parse interval from %q"):format(str)) + min, max = tonumber(min), tonumber(max) + local step = min <= max and 1 or -1 + return min, max, step +end + +function Grid:getFrames(...) + local result, args = {}, {...} + local minx, maxx, stepx, miny, maxy, stepy + + for i=1, #args, 2 do + minx, maxx, stepx = parseInterval(args[i]) + miny, maxy, stepy = parseInterval(args[i+1]) + for y = miny, maxy, stepy do + for x = minx, maxx, stepx do + result[#result+1] = getOrCreateFrame(self,x,y) + end + end + end + + return result +end + +local Gridmt = { + __index = Grid, + __call = Grid.getFrames +} + +local function newGrid(frameWidth, frameHeight, imageWidth, imageHeight, left, top, border) + assertPositiveInteger(frameWidth, "frameWidth") + assertPositiveInteger(frameHeight, "frameHeight") + assertPositiveInteger(imageWidth, "imageWidth") + assertPositiveInteger(imageHeight, "imageHeight") + + left = left or 0 + top = top or 0 + border = border or 0 + + local key = getGridKey(frameWidth, frameHeight, imageWidth, imageHeight, left, top, border) + + local grid = setmetatable( + { frameWidth = frameWidth, + frameHeight = frameHeight, + imageWidth = imageWidth, + imageHeight = imageHeight, + left = left, + top = top, + border = border, + width = math.floor(imageWidth/frameWidth), + height = math.floor(imageHeight/frameHeight), + _key = key + }, + Gridmt + ) + return grid +end + +----------------------------------------------------------- + +local Animation = {} + +local function cloneArray(arr) + local result = {} + for i=1,#arr do result[i] = arr[i] end + return result +end + +local function parseDurations(durations, frameCount) + local result = {} + if type(durations) == 'number' then + for i=1,frameCount do result[i] = durations end + else + local min, max, step + for key,duration in pairs(durations) do + assert(type(duration) == 'number', "The value [" .. tostring(duration) .. "] should be a number") + min, max, step = parseInterval(key) + for i = min,max,step do result[i] = duration end + end + end + + if #result < frameCount then + error("The durations table has length of " .. tostring(#result) .. ", but it should be >= " .. tostring(frameCount)) + end + + return result +end + +local function parseIntervals(durations) + local result, time = {0},0 + for i=1,#durations do + time = time + durations[i] + result[i+1] = time + end + return result, time +end + +local Animationmt = { __index = Animation } +local nop = function() end + +local function newAnimation(frames, durations, onLoop) + local td = type(durations); + if (td ~= 'number' or durations <= 0) and td ~= 'table' then + error("durations must be a positive number. Was " .. tostring(durations) ) + end + onLoop = onLoop or nop + durations = parseDurations(durations, #frames) + local intervals, totalDuration = parseIntervals(durations) + return setmetatable({ + frames = cloneArray(frames), + durations = durations, + intervals = intervals, + totalDuration = totalDuration, + onLoop = onLoop, + timer = 0, + position = 1, + status = "playing", + flippedH = false, + flippedV = false + }, + Animationmt + ) +end + +function Animation:clone() + local newAnim = newAnimation(self.frames, self.durations, self.onLoop) + newAnim.flippedH, newAnim.flippedV = self.flippedH, self.flippedV + return newAnim +end + +function Animation:flipH() + self.flippedH = not self.flippedH + return self +end + +function Animation:flipV() + self.flippedV = not self.flippedV + return self +end + +local function seekFrameIndex(intervals, timer) + local high, low, i = #intervals-1, 1, 1 + + while(low <= high) do + i = math.floor((low + high) / 2) + if timer >= intervals[i+1] then low = i + 1 + elseif timer < intervals[i] then high = i - 1 + else + return i + end + end + + return i +end + +function Animation:update(dt) + if self.status ~= "playing" then return end + + self.timer = self.timer + dt + local loops = math.floor(self.timer / self.totalDuration) + if loops ~= 0 then + self.timer = self.timer - self.totalDuration * loops + local f = type(self.onLoop) == 'function' and self.onLoop or self[self.onLoop] + f(self, loops) + end + + self.position = seekFrameIndex(self.intervals, self.timer) +end + +function Animation:pause() + self.status = "paused" +end + +function Animation:gotoFrame(position) + self.position = position + self.timer = self.intervals[self.position] +end + +function Animation:pauseAtEnd() + self.position = #self.frames + self.timer = self.totalDuration + self:pause() +end + +function Animation:pauseAtStart() + self.position = 1 + self.timer = 0 + self:pause() +end + +function Animation:resume() + self.status = "playing" +end + +function Animation:draw(image, x, y, r, sx, sy, ox, oy, kx, ky) + love.graphics.draw(image, self:getFrameInfo(x, y, r, sx, sy, ox, oy, kx, ky)) +end + +function Animation:getFrameInfo(x, y, r, sx, sy, ox, oy, kx, ky) + local frame = self.frames[self.position] + if self.flippedH or self.flippedV then + r,sx,sy,ox,oy,kx,ky = r or 0, sx or 1, sy or 1, ox or 0, oy or 0, kx or 0, ky or 0 + local _,_,w,h = frame:getViewport() + + if self.flippedH then + sx = sx * -1 + ox = w - ox + kx = kx * -1 + ky = ky * -1 + end + + if self.flippedV then + sy = sy * -1 + oy = h - oy + kx = kx * -1 + ky = ky * -1 + end + end + return frame, x, y, r, sx, sy, ox, oy, kx, ky +end + +function Animation:getDimensions() + local _,_,w,h = self.frames[self.position]:getViewport() + return w,h +end + +----------------------------------------------------------- + +anim8.newGrid = newGrid +anim8.newAnimation = newAnimation + +return anim8 diff --git a/actual game/main.lua b/actual game/main.lua new file mode 100644 index 0000000..c2abc2b --- /dev/null +++ b/actual game/main.lua @@ -0,0 +1,117 @@ +-- Load some default values for our agent. +local r, g, b = love.math.colorFromBytes(132, 193, 238) +love.graphics.setBackgroundColor(r, g, b) +local timer = 0 +local int = math.ceil(timer) + +function love.load() + anim8 = require 'libs/anim8' + love.graphics.setDefaultFilter("nearest", "nearest") + checker = 0 + agent = {} + agent.vx = 0 + agent.vy = 0 + agent.x = 0 + agent.y = 0 + agent.speed = 300 + agent.spriteSheet = love.graphics.newImage('sprites/spritesheet3.png') + agent.grid = anim8.newGrid( 64, 64, agent.spriteSheet:getWidth(), agent.spriteSheet:getHeight() ) + agent.animations = {} + agent.animations.right = anim8.newAnimation( agent.grid('1-3', 1),0.15) + agent.animations.left = anim8.newAnimation( agent.grid('1-3', 2),0.15) + + agent.anim = agent.animations.right + + isMouseDown = false + mouseX, mouseY = 0, 0 +end + +function love.update(dt) + timer = timer + dt + local distance + local isMoving = false + if love.keyboard.isDown("right") then + agent.anim = agent.animations.right + agent.x = agent.x + 2 + isMoving = true + end + + if love.keyboard.isDown("left") then + isMoving = true + agent.x = agent.x - 2 + agent.anim = agent.animations.left + end + + agent.anim:update(dt) + + if isMoving == false then + agent.anim:gotoFrame(1) + + end + + agent.x = agent.x + agent.vx * dt + agent.y = agent.y + agent.vy * dt + + if love.mouse.isDown(1) then + isMouseDown = true + mouseX, mouseY = love.mouse.getPosition() + else + + if isMouseDown then + local dx = mouseX - agent.x + local dy = mouseY - agent.y + local distance = math.sqrt(dx * dx + dy * dy) + + agent.vx = (dx / distance) * agent.speed + agent.vy = (dy / distance) * agent.speed + end + isMouseDown = false + end + + + local damping = 0.98 + local stopThreshold = 10 + + agent.x = agent.x + agent.vx * dt + agent.y = agent.y + agent.vy * dt + + + agent.vx = agent.vx * damping + agent.vy = agent.vy * damping + + + if math.abs(agent.vx) < stopThreshold and math.abs(agent.vy) < stopThreshold then + agent.vx = 0 + agent.vy = 0 + end + + + +end + + + +-- Draw a coloured rectangle. +function love.draw() + -- In versions prior to 11.0, color component values are (0, 102, 102) + love.graphics.print(agent.x, 10, 210) + love.graphics.print(int, 350, 0) + agent.anim:draw(agent.spriteSheet, agent.x, agent.y, nil, 1) + + if isMouseDown then + drawDottedArc(agent.x, agent.y, mouseX, mouseY) + end + +end + +function drawDottedArc(x1, y1, x2, y2) + local numDots = 20 + local distance = math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) + + for i = 1, numDots do + local t = i / numDots + local cx = x1 + (x2 - x1) * t + local cy = y1 + (y2 - y1) * t + love.graphics.circle("fill", cx, cy, 2) + end +end diff --git a/actual game/sprites/spritesheet.png b/actual game/sprites/spritesheet.png new file mode 100644 index 0000000..4dd5075 Binary files /dev/null and b/actual game/sprites/spritesheet.png differ diff --git a/actual game/sprites/spritesheet2.png b/actual game/sprites/spritesheet2.png new file mode 100644 index 0000000..9ebd1a3 Binary files /dev/null and b/actual game/sprites/spritesheet2.png differ diff --git a/actual game/sprites/spritesheet3.png b/actual game/sprites/spritesheet3.png new file mode 100644 index 0000000..88544c4 Binary files /dev/null and b/actual game/sprites/spritesheet3.png differ diff --git a/actual game/spritesheet.png b/actual game/spritesheet.png new file mode 100644 index 0000000..4dd5075 Binary files /dev/null and b/actual game/spritesheet.png differ