main.lua
Code: Select all
Class = require 'class'
push = require 'push'
require 'Util'
player =require 'Player'
require 'Enemy1'
wf = require 'windfield_master/windfield'
TILE_EMPTY = -1
-- Tree tiles
TILE_TREE = 4
-- Top wall tiles
TILE_WALL = 2
SECRET_WALL = 6
TILE_HEART = 1
RED_OCTO_1 = 9
RED_OCTO_2 = 10
RED_OCTO_3 = 11
RED_OCTO_4 = 12
RED_OCTO_5 = 13
RED_OCTO_6 = 14
RED_OCTO_7 = 15
RED_OCTO_8 = 16
-- close resolution to NES but 16:9
VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243
-- actual window resolution
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
local SCROLL_SPEED = 65
love.graphics.setDefaultFilter('nearest', 'nearest')
local tileWidth = 16
local tileHeight = 16
local mapWidth = 30
local mapHeight = 28
local xOffset = 8
local yOffset = 10
local tiles = {}
function love.load()
world = wf.newWorld(0, 0, true)
push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
fullscreen = false,
resizable = true
})
spritesheet = love.graphics.newImage('hearts_tree_walls.png')
-- camera offsets
camX = 0
camY = -3
sprites = generateQuads(spritesheet, 16, 16)
-- cache width and height of map in pixels
mapWidthPixels = mapWidth * tileWidth
mapHeightPixels = mapHeight * tileHeight
-- sets a tile at a given x-y coordinate to an integer value
-- first, fill map with empty tiles
for y = 1, mapHeight do
for x = 1, mapWidth do
-- support for multiple sheets per tile; storing tiles as tables
setTile(x, y, TILE_EMPTY)
end
end
-- create wall tiles on the bottom of the screen
for y = mapHeight / 2 + 1, mapHeight / 2 + 1 do
for x = 0, 25 do
setTile(x, y, TILE_WALL)
end
end
-- Secret wall
for y = mapHeight / 2 + 1, mapHeight / 2 + 1 do
for x = 26, 26 do
setTile(x, y, SECRET_WALL)
end
end
--left hand side tile
for y = 0, 25 do
for x = 1, 1 do
setTile(x, y, TILE_WALL)
end
end
-- Upper right hand side tiles
for y = 0, 25 do
for x = 27, 27 do
setTile(x, y, TILE_WALL)
end
end
--Top screen tiles
for y = 1, 1 do
for x = 0, 26 do
setTile(x, y, TILE_WALL)
end
end
-- tree top left
for y = 5, 5 do
for x = 5, 15 do
setTile(x, y, TILE_TREE)
end
end
-- tree bottom-left
for y = 9, 9 do
for x = 5, 15 do
setTile(x, y, TILE_TREE)
end
end
-- tree right
for y = mapHeight / 2 - 10, mapHeight / 2 - 4 do
for x = 22, 22 do
setTile(x, y, TILE_TREE)
end
end
for y = mapHeight / 2 - 12, mapHeight / 2 - 12 do
for x = 26, 26 do
setTile(x, y, TILE_HEART)
end
end
love.window.setTitle('Legend of Zelda')
love.keyboard.keysPressed = {}
love.keyboard.keysReleased = {}
end
function setTile(x, y, id)
tiles[(y - 1) * mapWidth + x] = id
end
-- gets the tile type at a given pixel coordinate
function tileAt(x, y)
return {
x = math.floor(x / tileWidth) + 1,
y = math.floor(y / tileHeight) + 1,
id = getTile(math.floor(x / tileWidth) + 1, math.floor(y / tileHeight) + 1)
}
end
-- returns an integer value for the tile at a given x-y coordinate
function getTile(x, y)
return tiles[(y - 1) * mapWidth + x]
end
function love.resize(w,h)
push:resize(w,h)
end
function love.keyboard.wasReleased(key)
if (love.keyboard.keysReleased[key]) then
return true
else
return false
end
end
function love.keypressed(key)
if key == 'escape' then
love.event.quit()
end
love.keyboard.keysPressed[key] = true
player.collider:setPosition(0, 0)
player.collider:setLinearVelocity(0, 0)
end
function love.keyreleased(key)
love.keyboard.keysReleased[key] = true
end
function love.update(dt)
if love.keyboard.isDown('w') then
camY = math.max(0,camY - dt * SCROLL_SPEED)
elseif love.keyboard.isDown('s') then
camY = math.min(camY + dt * SCROLL_SPEED, mapHeightPixels - VIRTUAL_HEIGHT)
end
world:update(dt)
player:update(dt)
enemy1:update(dt)
enemy2:update(dt)
enemy3:update(dt)
-- reset all keys pressed and released this frame
love.keyboard.keysPressed = {}
love.keyboard.keysReleased = {}
end
function love.draw()
push:apply('start')
world:draw()
love.graphics.clear(252/255, 216/255, 169/255, 1)
local scaleX = -1
for y = 1, mapHeight do
for x = 1, mapWidth do
local tile = getTile(x, y)
if tile ~= TILE_EMPTY then
love.graphics.draw(spritesheet, sprites[tile],
(x - 1) * tileWidth, (y - 1) * tileHeight)
end
end
end
player:render()
enemy:render()
push:apply('end')
end
Player.lua
Code: Select all
--[[
Represents our player in the game, with its own sprit
]]
Player = {}
require 'Animation'
local WALKING_SPEED = 140
local MOVE_SPEED = 80
local tileWidth = 16
local tileHeight = 16
local mapWidth = 30
local mapHeight = 28
local xOffset = 8
local yOffset = 10
WALKING_RIGHT_1 = 3
WALKING_RIGHT_2 = 4
WALKING_LEFT_1 = 7
WALKING_LEFT_2 = 8
WALKING_UP_1 = 5
WALKING_UP_2 = 6
WALKING_DOWN_1 = 1
WALKING_DOWN_2 = 2
function Player:init(main)
-- player physics collision
--player.collider = world:newRectangleCollider(16,16,16,16)
--player.collider:setCollisionClass("player")
self.width = 16
player.height = 16
-- offset refrence point from top left corner to center of sprite for X axis
player.xOffset = 8
player.yOffset = 16
-- offset refrence point from top left corner to center of sprite for Y axis
player.xOffset2 = 16
player.yOffset2 = 8
player.x = tileWidth * 10
player.y = tileHeight * (mapHeight / 2 - 1) - player.height
player.dx = 0
player.dy =0
player.direction = nil
player.map = map
player.currentFrame = nil
player.texture = love.graphics.newImage('Link_movement.png')
player.frames = {}
player.state = 'idle_down'
player.animations = {
['idle_right'] = Animation {
texture = player.texture,
frames = {
love.graphics.newQuad(48,0,16,16,player.texture:getDimensions())
},
interval = 1
},
['idle_left'] = Animation {
texture = player.texture,
frames = {
love.graphics.newQuad(48,16,16,16,player.texture:getDimensions())
},
interval = 1
},
['idle_up'] = Animation {
texture = player.texture,
frames = {
love.graphics.newQuad(0,16,16,16,player.texture:getDimensions())
},
interval = 1
},
['idle_down'] = Animation {
texture = player.texture,
frames = {
love.graphics.newQuad(0,0,16,16,player.texture:getDimensions())
},
interval = 1
},
['walking_right'] = Animation {
texture = player.texture,
frames = {
--4 and 3
love.graphics.newQuad(48,0,16,16,player.texture:getDimensions()),
love.graphics.newQuad(32,0,16,16,player.texture:getDimensions())
},
interval = 0.15
},
['walking_left'] = Animation {
texture = player.texture,
frames = {
-- 7 and 8
love.graphics.newQuad(32,16,16,16,player.texture:getDimensions()),
love.graphics.newQuad(48,16,16,16,player.texture:getDimensions())
},
interval = 0.15
},
['walking_up'] = Animation {
texture = player.texture,
frames = {
--6 and 5
love.graphics.newQuad(16,16,16,16,player.texture:getDimensions()),
love.graphics.newQuad(0,16,16,16,player.texture:getDimensions())
},
interval = 0.15
},
['walking_down'] = Animation {
texture = player.texture,
frames = {
-- 2 and 1
love.graphics.newQuad(16,0,16,16,player.texture:getDimensions()),
love.graphics.newQuad(0,0,16,16,player.texture:getDimensions())
},
interval = 0.15
},
['sword_up'] = Animation {
texture = player.texture,
frames = {
-- 10 and 14
love.graphics.newQuad(16,64,16,-32,player.texture:getDimensions())
},
interval = 1
},
['sword_down'] = Animation {
texture = player.texture,
frames = {
-- 9 adn 13 FLIP FOR UP
love.graphics.newQuad(0,32,16,32,player.texture:getDimensions())
},
interval = 1
},
['sword_left'] = Animation {
texture = player.texture,
frames = {
-- 15,16
love.graphics.newQuad(32,48,32,16,player.texture:getDimensions())
},
interval = 1
},
['sword_right'] = Animation {
texture = player.texture,
frames = {
-- 11 and 12 FLIP FOR LEFT
love.graphics.newQuad(32,32,32,16,player.texture:getDimensions())
},
interval = 1
}
}
player.behaviors = {
['idle_down'] = function(dt)
if love.keyboard.isDown('up') then
player.y = player.y -MOVE_SPEED * dt
player.animation = player.animations['walking_up']
player.state = 'idle_up'
elseif love.keyboard.isDown('down') then
player.y = player.y + MOVE_SPEED * dt
player.animation = player.animations['walking_down']
player.state = 'idle_down'
elseif love.keyboard.isDown('left') then
player.x = player.x -MOVE_SPEED * dt
player.animation = player.animations['walking_left']
player.state = 'idle_left'
elseif love.keyboard.isDown('right') then
player.x = player.x + MOVE_SPEED * dt
player.animation = player.animations['walking_right']
player.state = 'idle_right'
elseif love.keyboard.isDown('space') then
player.animation = player.animations['sword_down']
else
player.animation = player.animations['idle_down']
end
end,
['idle_up'] = function (dt)
if love.keyboard.isDown('up') then
player.y = player.y -MOVE_SPEED * dt
player.animation = player.animations['walking_up']
player.state = 'idle_up'
elseif love.keyboard.isDown('down') then
player.y = player.y + MOVE_SPEED * dt
player.animation = player.animations['walking_down']
player.state = 'idle_down'
elseif love.keyboard.isDown('left') then
player.x = player.x -MOVE_SPEED * dt
player.animation = player.animations['walking_left']
player.state = 'idle_left'
elseif love.keyboard.isDown('right') then
player.x = player.x + MOVE_SPEED * dt
player.animation = player.animations['walking_right']
player.state = 'idle_right'
elseif love.keyboard.isDown('space') then
player.direction = 'up'
player.animation = player.animations['sword_down']
else
player.animation = player.animations['idle_up']
end
end,
['idle_right'] = function (dt)
if love.keyboard.isDown('up') then
player.y = player.y -MOVE_SPEED * dt
player.animation = player.animations['walking_up']
player.state = 'idle_up'
elseif love.keyboard.isDown('down') then
player.y = player.y + MOVE_SPEED * dt
player.animation = player.animations['walking_down']
player.state = 'idle_down'
elseif love.keyboard.isDown('left') then
player.x = player.x -MOVE_SPEED * dt
player.animation = player.animations['walking_left']
player.state = 'idle_left'
elseif love.keyboard.isDown('right') then
player.x = player.x + MOVE_SPEED * dt
player.animation = player.animations['walking_right']
player.state = 'idle_right'
elseif love.keyboard.isDown('space') then
player.animation = player.animations['sword_right']
else
player.animation = player.animations['idle_right']
end
end,
['idle_left'] = function (dt)
if love.keyboard.isDown('up') then
player.y = player.y -MOVE_SPEED * dt
player.animation = player.animations['walking_up']
player.state = 'idle_up'
elseif love.keyboard.isDown('down') then
player.y = player.y + MOVE_SPEED * dt
player.animation = player.animations['walking_down']
player.state = 'idle_down'
elseif love.keyboard.isDown('left') then
player.x = player.x -MOVE_SPEED * dt
player.animation = player.animations['walking_left']
player.state = 'idle_left'
elseif love.keyboard.isDown('right') then
player.x = player.x + MOVE_SPEED * dt
player.animation = player.animations['walking_right']
player.state = 'idle_right'
elseif love.keyboard.isDown('space') then
player.direction = 'left'
player.animation = player.animations['sword_right']
else
player.animation = player.animations['idle_left']
end
end
}
function Player:update(dt)
-- Update behaviors, animations, and frames
player.behaviors[player.state](dt)
player.animation:update(dt)
player.currentFrame = player.animation:getCurrentFrame()
end
function Player:render()
-- Define scale variables
local scaleX
local scaleY
-- If space is pressed and the state is left then it will take that current frame (sword_right) and flip it horizontally
-- This was done since everything is drawn to its upper left corner and to keep consistency
if love.keyboard.isDown('space') and player.state == 'idle_left' then
--Flips 180 degrees
scaleX = -1
else
-- No flip
scaleX = 1
end
-- If space is pressed and the state is up then it will take that current frame and flip it vertically
if love.keyboard.isDown('space') and player.state == 'idle_up' then
scaleY = -1
else
scaleY = 1
end
-- Change reference point from top left corner to the center so it can flip within the same position for both x and y axis flips
if love.keyboard.isDown('space') and player.state == 'idle_left' then
love.graphics.draw(player.texture, player.currentFrame, math.floor(player.x + player.xOffset),math.floor(player.y + player.yOffset),
0,scaleX,1,player.xOffset,player.yOffset)
elseif love.keyboard.isDown('space') and player.state == 'idle_up' then
love.graphics.draw(player.texture, player.currentFrame, math.floor(player.x + player.xOffset2),math.floor(player.y + player.yOffset2),
0,1,scaleY,player.xOffset2,player.yOffset2)
else
-- If the first two conditions does not appy, just render the current frames without any scaling or rotation
love.graphics.draw(player.texture, player.currentFrame, math.floor(player.x),math.floor(player.y))
end
end
end