Two-layer tiles; tiles loaded from Lua; basic interaction
Getty Ritter
8 years ago
| 5 | 5 | Board.__index = Board |
| 6 | 6 | |
| 7 | 7 | function Board:new() |
| 8 |
local t = { |
|
| 8 | local t = { | |
| 9 | base = {}, | |
| 10 | entity = {}, | |
| 11 | } | |
| 9 | 12 | for x = 0, consts.boardWidth do |
| 10 | 13 | for y = 0, consts.boardHeight do |
| 11 |
t |
|
| 14 | t.base[x * consts.boardWidth + y] = tile.getTile('grass') | |
| 15 | t.entity[x * consts.boardWidth + y] = nil | |
| 12 | 16 | end |
| 13 | 17 | end |
| 14 | 18 | return setmetatable(t, Board) |
| 15 | 19 | end |
| 16 | 20 | |
| 17 | 21 | function Board:lookup(x, y) |
| 18 |
return self |
|
| 22 | return self.base[x * consts.boardWidth + y] | |
| 19 | 23 | end |
| 20 | 24 | |
| 21 | 25 | function Board:set(x, y, r) |
| 22 |
self |
|
| 26 | self.base[x * consts.boardWidth + y] = r | |
| 27 | end | |
| 28 | ||
| 29 | function Board:lookupEntity(x, y) | |
| 30 | return self.entity[x * consts.boardWidth + y] | |
| 31 | end | |
| 32 | ||
| 33 | function Board:setEntity(x, y, r) | |
| 34 | self.entity[x * consts.boardWidth + y] = r | |
| 35 | end | |
| 36 | ||
| 37 | function Board:passable(x, y) | |
| 38 | local t, e = self:lookup(x, y), self:lookupEntity(x, y) | |
| 39 | if e then | |
| 40 | return t and t.pass and e.pass | |
| 41 | else | |
| 42 | return t and t.pass | |
| 43 | end | |
| 23 | 44 | end |
| 24 | 45 | |
| 25 | 46 | return { |
| 11 | 11 | dx = 0, |
| 12 | 12 | dy = 0, |
| 13 | 13 | sprite = s, |
| 14 | direction = {0, 1}, | |
| 14 | 15 | } |
| 15 | 16 | return setmetatable(t, Entity) |
| 16 | 17 | end |
| 21 | 22 | local alignX = ((self.x + dx) % consts.tileSize) == 0 |
| 22 | 23 | local alignY = ((self.y + dy) % consts.tileSize) == 0 |
| 23 | 24 | |
| 24 | local a = self.board:lookup(bx, by) | |
| 25 | local b = self.board:lookup(bx + 1, by) | |
| 26 | local c = self.board:lookup(bx, by + 1) | |
| 27 | local d = self.board:lookup(bx + 1, by + 1) | |
| 25 | local a = self.board:passable(bx, by) | |
| 26 | local b = self.board:passable(bx + 1, by) | |
| 27 | local c = self.board:passable(bx, by + 1) | |
| 28 | local d = self.board:passable(bx + 1, by + 1) | |
| 28 | 29 | |
| 29 | 30 | if not (a and b and c and d) then return false end |
| 30 | 31 | |
| 31 | 32 | if alignX and alignY then |
| 32 |
return a |
|
| 33 | return a | |
| 33 | 34 | elseif alignX then |
| 34 |
return a |
|
| 35 | return a and c | |
| 35 | 36 | elseif alignY then |
| 36 |
return a |
|
| 37 | return a and b | |
| 37 | 38 | else |
| 38 |
return a |
|
| 39 | return a and b and c and d | |
| 39 | 40 | end |
| 40 | 41 | |
| 41 | 42 | end |
| 42 | 43 | |
| 44 | function Entity:getFocus(board) | |
| 45 | local bx = math.floor(self.x / consts.tileSize) | |
| 46 | local by = math.floor(self.y / consts.tileSize) | |
| 47 | ||
| 48 | return board:lookupEntity(bx + self.direction[1], by + self.direction[2]) | |
| 49 | end | |
| 50 | ||
| 43 | 51 | function Entity:move(board) |
| 44 | 52 | local movement = true |
| 53 | ||
| 54 | if self.dx > 0 then | |
| 55 | self.direction[1] = 2 | |
| 56 | elseif self.dx < 0 then | |
| 57 | self.direction[1] = -1 | |
| 58 | elseif self.dy ~= 0 then | |
| 59 | self.direction[1] = 0 | |
| 60 | end | |
| 61 | ||
| 62 | if self.dy > 0 then | |
| 63 | self.direction[2] = 2 | |
| 64 | elseif self.dy < 0 then | |
| 65 | self.direction[2] = -1 | |
| 66 | elseif self.dx ~= 0 then | |
| 67 | self.direction[2] = 0 | |
| 68 | end | |
| 69 | ||
| 45 | 70 | if self:checkCollision(self.dx, self.dy) then |
| 46 | 71 | self.x = self.x + self.dx |
| 47 | 72 | self.y = self.y + self.dy |
| 74 | 99 | end |
| 75 | 100 | end |
| 76 | 101 | end |
| 77 | print(self.x, self.y) | |
| 78 | 102 | end |
| 79 | 103 | |
| 80 | 104 | function Entity:draw() |
| 16 | 16 | function keys.released.s(s) s.char.dy = 0 end |
| 17 | 17 | function keys.released.d(s) s.char.dx = 0 end |
| 18 | 18 | |
| 19 | function keys.pressed.e(s) | |
| 20 | local tgt = s.char:getFocus(s.board) | |
| 21 | if tgt then | |
| 22 | tgt:action() | |
| 23 | end | |
| 24 | end | |
| 25 | ||
| 19 | 26 | return { |
| 20 | 27 | keys = keys |
| 21 | 28 | } |
| 6 | 6 | local state = {} |
| 7 | 7 | |
| 8 | 8 | local sprites = {} |
| 9 | ||
| 10 | function fromScreen(x, y) | |
| 11 | return math.floor(x / consts.tileSize), math.floor(y / consts.tileSize) | |
| 12 | end | |
| 9 | 13 | |
| 10 | 14 | function love.load() |
| 11 | 15 | state.t = 0 |
| 17 | 21 | state.board:set(2, 5, tile.getTile('water')) |
| 18 | 22 | |
| 19 | 23 | state.board:set(8, 3, tile.getTile('water')) |
| 24 | state.board:set(9, 3, tile.getTile('stonepath')) | |
| 20 | 25 | state.board:set(8, 4, tile.getTile('water')) |
| 21 | 26 | state.board:set(8, 5, tile.getTile('water')) |
| 27 | state.board:setEntity(9, 6, tile.getTile('sign')) | |
| 22 | 28 | end |
| 23 | 29 | |
| 24 | 30 | function love.update() |
| 25 | 31 | state.char:move() |
| 32 | end | |
| 33 | ||
| 34 | function love.mousepressed(x, y) | |
| 35 | local gx, gy = fromScreen(x, y) | |
| 36 | state.board:set(gx, gy, tile.getTile('stonepath')) | |
| 26 | 37 | end |
| 27 | 38 | |
| 28 | 39 | function love.keypressed(key) |
| 49 | 60 | end |
| 50 | 61 | end |
| 51 | 62 | |
| 63 | for x = 0, consts.boardWidth, 1 do | |
| 64 | for y = 0, consts.boardHeight, 1 do | |
| 65 | local e = state.board:lookupEntity(x, y) | |
| 66 | if e then e:draw(x, y) end | |
| 67 | end | |
| 68 | end | |
| 69 | ||
| 52 | 70 | state.char:draw() |
| 53 | 71 | end |
| 3 | 3 | local Tile = {} |
| 4 | 4 | Tile.__index = Tile |
| 5 | 5 | |
| 6 | local spritesheet | |
| 7 | ||
| 6 | 8 | function Tile:new(name) |
| 7 | local t = { | |
| 8 | name = name, | |
| 9 | sprite = love.graphics.newImage('tiles/' .. name .. '.png'), | |
| 10 | pass = name == 'grass' | |
| 11 |
|
|
| 9 | if not spritesheet then | |
| 10 | spritesheet = love.graphics.newImage('tiles/spritesheet.png') | |
| 11 | end | |
| 12 | ||
| 13 | local f = io.open('tiles/' .. name .. '.lua') | |
| 14 | local t | |
| 15 | if f then | |
| 16 | t = loadstring('return' .. f:read('*all'))() | |
| 17 | f:close() | |
| 18 | t.quad = love.graphics.newQuad( | |
| 19 | t.spriteX * consts.tileSize, | |
| 20 | t.spriteY * consts.tileSize, | |
| 21 | consts.tileSize, | |
| 22 | consts.tileSize, | |
| 23 | spritesheet:getDimensions()) | |
| 24 | else | |
| 25 | t = { | |
| 26 | name = name, | |
| 27 | sprite = love.graphics.newImage('tiles/' .. name .. '.png'), | |
| 28 | pass = name == 'grass', | |
| 29 | draw = function(self, x, y) | |
| 30 | love.graphics.draw(self.sprite, x * consts.tileSize, y * consts.tileSize) | |
| 31 | end | |
| 32 | } | |
| 33 | end | |
| 12 | 34 | return setmetatable(t, Tile) |
| 13 | 35 | end |
| 14 | 36 | |
| 16 | 38 | end |
| 17 | 39 | |
| 18 | 40 | function Tile:draw(x, y) |
| 19 |
love.graphics.draw(s |
|
| 41 | love.graphics.draw(spritesheet, | |
| 42 | self.quad, | |
| 20 | 43 | x * consts.tileSize, |
| 21 | 44 | y * consts.tileSize) |
| 22 | 45 | end |
| 1 | { | |
| 2 | pass = false, | |
| 3 | name = 'sign', | |
| 4 | spriteX = 3, | |
| 5 | spriteY = 0, | |
| 6 | action = function() print('A sign!') end, | |
| 7 | } |
Binary diff not shown
Binary diff not shown