It relates to the following files: main.lua, player.lua, frog.lua, damageobject.lua. The problem is quite complicated, I will try my best to explain it clearly. First, take a look at my code.
main.lua:
Code: Select all
function love.load()
Object = require"classic"
anim8 = require"anim8"
wf = require'windfield'
world = wf.newWorld(0, 0, true)
world:setGravity(0, 512)
world:addCollisionClass('Platform')
world:addCollisionClass('Frog')
world:addCollisionClass('DamageObject')
world:addCollisionClass('Player')
require"player"
player = Player()
require "wall"
listOfWall = {}
buildWall()
require "frog"
listOfFrog = {}
table.insert(listOfFrog, Frog(350, 400, 3))
table.insert(listOfFrog, Frog(450, 400, 3))
table.insert(listOfFrog, Frog(400, 400, 3))
table.insert(listOfFrog, Frog(445, 375, 3))
table.insert(listOfFrog, Frog(425, 390, 3))
table.insert(listOfFrog, Frog(350, 400, 3))
table.insert(listOfFrog, Frog(450, 400, 3))
table.insert(listOfFrog, Frog(400, 400, 3))
table.insert(listOfFrog, Frog(445, 375, 3))
table.insert(listOfFrog, Frog(425, 390, 3))
require"enemyexplosion"
listOfExplo = {}
require"damageobject"
listOfDamageObject = {}
Camera = require'Camera'
camera = Camera()
camera:setFollowLerp(0.2)
camera.scale = 2.5
end
function buildWall()
for i=1, 11 do
table.insert(listOfWall, Wall(200+i*48, 500))
end
table.insert(listOfWall, Wall(200-48, 500-48))
table.insert(listOfWall, Wall(200-48, 500-48-48))
table.insert(listOfWall, Wall(200-48-48, 500-48-48))
end
function love.update(dt)
player:update(dt)
world:update(dt)
local xx, yy = player.collider:getLinearVelocity()
-- camera effect made by myself
if math.abs(yy) > 230 then
if camera.scale > 1 then
camera.scale = camera.scale - 0.05
end
else
if camera.scale < 2.5 then
camera.scale = camera.scale + 0.05
end
end
--
camera:update(dt)
camera:follow(player.x, player.y)
for i, v in ipairs(listOfFrog) do
v:update(dt)
end
for exnum2, explonow2 in ipairs(listOfExplo) do
explonow2:update(dt)
end
for DONum, DONow in ipairs(listOfDamageObject) do
DONow:update(dt)
if DONow.lifetime <= 0 then
table.insert(listOfExplo, EnemyExplosion(DONow.collider:getX(), DONow.collider:getY(), "eneExplo", 35))
DONow:boom()
end
end
end
function love.draw()
camera:attach()
player:draw()
for i,v in ipairs(listOfWall) do
v:draw()
end
for fronum,frogg in ipairs(listOfFrog) do
frogg:draw()
end
for exnum, explonow in ipairs(listOfExplo) do
explonow:draw()
end
for DONum2, DONow2 in ipairs(listOfDamageObject) do
DONow2:draw()
end
world:draw()
camera:detach()
camera:draw()
end
Code: Select all
Player = Object:extend()
function Player:new()
self.width = 32
self.height = 32
self.x = 300
self.y = 300
self.speedX = 0
self.scaleX = 1
self.jumpupState = false
self.jumpdownState = false
self.idleState = true
self.runleftState = false
self.runrightState = false
self.hurtState = false
self.hurtReload = 50
self.ouchX = 25
self.cherryReload = 20
self.stompReload = 20
self.sprite = love.graphics.newImage('foxsheet.png')
self.grid = anim8.newGrid(self.width, self.height, 192, 192)
self.animations = {}
self.animations.idle = anim8.newAnimation(self.grid('1-4',5), 0.1)
self.animations.run = anim8.newAnimation(self.grid('1-6',1), 0.075)
self.animations.jumpup = anim8.newAnimation(self.grid(1,6), 0.35)
self.animations.jumpdown = anim8.newAnimation(self.grid(2,6), 0.35)
self.animations.crouch = anim8.newAnimation(self.grid('1-2',3), 0.1)
self.animations.hurt = anim8.newAnimation(self.grid('1-2',4), 0.1)
self.animations.climb = anim8.newAnimation(self.grid('1-3',2), 0.1)
self.anim = self.animations.idle
self.collider = world:newRectangleCollider(self.x, self.y, 15, 15)
--self.collider = world:newCircleCollider(self.x, self.y, 10)
self.collider:setCollisionClass('Player')
self.collider:setObject(self)
self.jumping = false
self.dir = "right"
end
function Player:update(dt)
self.anim:update(dt)
if self.collider:enter('Platform') or self.collider:enter('Frog') then
self.jumping = false
end
if self.collider:enter('Frog') then
local collision_data = self.collider:getEnterCollisionData('Frog')
local enemy = collision_data.collider:getObject()
if enemy.collider:getY() > self.collider:getY() then
self.collider:applyLinearImpulse(0, -50)
--print("ouch")
enemy.health = enemy.health - 1
else
if self.hurtState == false then
self.hurtState = true
if self.collider:getX() < enemy.collider:getX() then
self.ouchX = -25
else
self.ouchX = 25
end
self.collider:applyLinearImpulse(self.ouchX, -100)
end
end
end
if self.hurtState then
self.hurtReload = self.hurtReload - 1
end
if self.hurtReload <= 0 then
self.hurtState = false
self.hurtReload = 50
end
if love.keyboard.isDown("up") and not self.jumping then
self.collider:applyLinearImpulse(0, -100)
self.jumping = true
end
x,y = self.collider:getLinearVelocity()
if y>3 then
self.jumpdownState = true
self.jumpupState = false
elseif y<-3 then
self.jumpupState = true
self.jumpdownState = false
else
self.jumpupState = false
self.jumpdownState = false
end
if love.keyboard.isDown("right") then
self.speedX = 7
self.runrightState = true
self.dir = "right"
else
self.runrightState = false
end
if love.keyboard.isDown("left") then
self.speedX = -7
self.runleftState = true
self.dir = "left"
else
self.runleftState = false
end
if not love.keyboard.isDown("left") and not love.keyboard.isDown("right") then
self.speedX = 0
self.idleState = true
else
self.idleState = false
end
if (math.abs(self.collider:getLinearVelocity()) < 60) then
self.collider:applyLinearImpulse(self.speedX, 0)
end
--animations here
if self.hurtState then
self.anim = self.animations.hurt
else
if self.jumpupState then
self.anim = self.animations.jumpup
elseif self.jumpdownState then
self.anim = self.animations.jumpdown
else
if self.runrightState then
self.anim = self.animations.run
self.scaleX = 1
elseif self.runleftState then
self.anim = self.animations.run
self.scaleX = -1
else
self.anim = self.animations.idle
end
end
end
self.x = self.collider:getX()
self.y = self.collider:getY()
self.cherryReload = self.cherryReload - 1
self.stompReload = self.stompReload - 1
if love.keyboard.isDown("space") and self.cherryReload <=0 then
if self.dir == "right" then
table.insert(listOfDamageObject, DamageObject(self.x, self.y, 20, 20, 7, "cherrybomb", 100, 50))
else
table.insert(listOfDamageObject, DamageObject(self.x, self.y, 20, 20, 7, "cherrybomb", 100, -50))
end
self.cherryReload = 20
end
if love.keyboard.isDown("down") and self.stompReload <= 0 then
table.insert(listOfDamageObject, DamageObject(self.x-20, self.y, 40, 2, nil, "stomp", 30, 0))
self.stompReload = 20
end
end
function Player:draw()
self.anim:draw(self.sprite, self.x, self.y, nil, self.scaleX, 1, 16, 16)
end
Code: Select all
Frog = Object:extend()
function Frog:new(x, y, health)
self.x = x
self.y = x
self.width = 40
self.height = 40
self.speedX = 50
self.speedY = -100
self.scaleX = 1
self.moveto1 = x + 50
self.moveto2 = x - 50
self.phase1 = false
self.phase2 = false
self.dirX = -1
self.dead = false
self.sprite = love.graphics.newImage('frog.png')
self.grid = anim8.newGrid(35, 32, self.sprite:getWidth(), self.sprite:getHeight())
self.animations = {}
self.animations.idle = anim8.newAnimation(self.grid('1-4', 1), 0.2)
self.animations.jumpup = anim8.newAnimation(self.grid(6, 1), 0.2)
self.animations.jumpdown = anim8.newAnimation(self.grid(7, 1), 0.2)
self.anim = self.animations.idle
self.idleState = true
self.jumpupState = false
self.jumpdownState = false
self.collider = world:newRectangleCollider(self.x, self.y, 20, 18)
--self.collider = world:newCircleCollider(self.x, self.y, 10)
self.collider:setCollisionClass('Frog')
self.collider:setObject(self)
self.jumpingReload = 200
self.health = health
end
function Frog:update(dt)
self.anim:update(dt)
if self.jumpingReload > 0 then
self.jumpingReload = self.jumpingReload - 1
end
xVel,yVel = self.collider:getLinearVelocity()
if yVel > 4 then
self.jumpdownState = true
self.jumpupState = false
self.idle = false
elseif yVel < -4 then
self.jumpupState = true
self.jumpdownState = false
self.idle = false
else
self.jumpupState = false
self.jumpdownState = false
self.idle = true
end
--claim
self.x = self.collider:getX()
self.y = self.collider:getY()
if self.x < self.moveto2 then
self.phase1 = false
self.phase2 = true
elseif self.x > self.moveto1 then
self.phase1 = true
self.phase2 = false
end
if self.phase1 then
self.scaleX = 1
self.dirX = -1
elseif self.phase2 then
self.scaleX = -1
self.dirX = 1
end
if self.x == moveto2 then
self.phase1 = false
self.phase2 = true
elseif self.x == moveto1 then
self.phase1 = true
self.phase2 = false
end
if self.jumpingReload < 1 then
self.randX = love.math.random(1, 3)
self.randY = love.math.random(1, 3)
if self.randX == 1 then
self.speedX = 30
elseif self.randX == 2 then
self.speedX = 40
else
self.speedX = 50
end
if self.randY == 1 then
self.speedY = -100
elseif self.randY == 2 then
self.speedY = -125
else
self.speedY = -150
end
self.collider:applyLinearImpulse(self.speedX * self.dirX, self.speedY)
self.jumpingReload = 200
end
if self.jumpupState then
self.anim = self.animations.jumpup
elseif self.jumpdownState then
self.anim = self.animations.jumpdown
else
self.anim = self.animations.idle
end
if self.health <= 0 then
self:boom()
end
end
function Frog:boom()
for k, v in ipairs(listOfFrog) do
if v == self then
table.insert(listOfExplo, EnemyExplosion(self.collider:getX(), self.collider:getY(), "eneExplo", 35))
self.collider:destroy()
table.remove(listOfFrog, k)
break
end
end
--self.collider:destroy()
--listOfFrog:pullval(self)
end
function Frog:draw()
self.anim:draw(self.sprite, self.x, self.y, nil, self.scaleX, 1, 16, 17.5)
end
Code: Select all
DamageObject = Object:extend()
function DamageObject:new(x, y, width, height, radius, name, lifetime, bulletSpeedX)
self.x = x
self.y = y
self.width = width
self.height = height
self.radius = radius
self.name = name
self.typemove = typemove
self.lifetime = lifetime
self.bulletSpeedX = bulletSpeedX
if self.name == "cherrybomb" then
self.sprite = love.graphics.newImage('cherrybomb.png')
self.grid = anim8.newGrid(21, 21, self.sprite:getWidth(), self.sprite:getHeight())
self.animation = anim8.newAnimation(self.grid('1-5', 1), 0.1)
self.collider = world:newCircleCollider(self.x, self.y, self.radius)
--self.collider = world:newRectangleCollider(self.x, self.y, self.width, self.height)
self.collider:setCollisionClass('DamageObject')
self.collider:setRestitution(0.8)
self.collider:setObject(self)
self.collider:applyLinearImpulse(self.bulletSpeedX, 70)
end
if self.name == "stomp" then
self.sprite = love.graphics.newImage('stomp.png')
self.grid = anim8.newGrid(40, 40, self.sprite:getWidth(), self.sprite:getHeight())
self.animation = anim8.newAnimation(self.grid('1-8', 1), 0.1)
--self.collider = world:newCircleCollider(self.x, self.y, self.radius)
self.collider = world:newRectangleCollider(self.x, self.y, self.width, self.height)
self.collider:setCollisionClass('DamageObject')
self.collider:setObject(self)
end
end
function DamageObject:update(dt)
self.animation:update(dt)
self.x = self.collider:getX()
self.y = self.collider:getY()
--self destroy (need to spit in a new function and make a real explosion)-finish
if self.name == "cherrybomb" then
if self.collider:enter('Frog') then
local collision_data = self.collider:getEnterCollisionData('Frog')
local enemy = collision_data.collider:getObject()
print('yep')
local xaxa = 0
if enemy.collider:getX() < self.collider:getX() then
xaxa = -100
elseif enemy.collider:getX() > self.collider:getX() then
xaxa = 100
end
enemy.collider:setLinearVelocity(xaxa, -100)
enemy.health = enemy.health - 1
table.insert(listOfExplo, EnemyExplosion(self.collider:getX(), self.collider:getY(), "eneExplo", 35))
self:boom()
end
end
if self.name == "stomp" then
if self.collider:enter('Frog') then
local collision_data = self.collider:getEnterCollisionData('Frog')
local enemy = collision_data.collider:getObject()
local xaxa = 0
if enemy.collider:getX() < self.collider:getX() then
xaxa = -100
elseif enemy.collider:getX() > self.collider:getX() then
xaxa = 100
end
enemy.collider:setLinearVelocity(xaxa, -100)
table.insert(listOfExplo, EnemyExplosion(self.collider:getX(), self.collider:getY(), "eneExplo", 35))
enemy.health = enemy.health - 1
end
end
--
self.lifetime = self.lifetime - 1
end
function DamageObject:boom()
for dameObNum, ObjNow in ipairs(listOfDamageObject) do
if ObjNow == self then
self.collider:destroy()
table.remove(listOfDamageObject, dameObNum)
break
end
end
end
function DamageObject:draw()
self.animation:draw(self.sprite, self.x, self.y, nil, 1, 1, self.width/2, self.height/2)
end
Code: Select all
Error: damageobject.lua:54: attempt to index local 'enemy' (a nil value)
stack traceback:
[string "boot.lua"]:637: in function '__index'
damageobject.lua:54: in function 'update'
main.lua:86: in function 'update'
[string "boot.lua"]:509: in function <[string "boot.lua"]:493>
[C]: in function 'xpcall'
This is my project: