Two-layer tiles; tiles loaded from Lua; basic interaction
Getty Ritter
7 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