关于love2d:Lua错误“尝试调用方法”(nil值)

Lua Error "Attempt to call method '' (a nil Value)

我想制作一个2D平台(带有Love2D-Framework),并有一个main.lua文件从状态文件夹中选择随机映射。
首先,我只是说main-main.lua应该在/ states / map1 /中打开main.lua文件。 但是每次我尝试运行它时,我都会收到以下错误消息:

错误

States / map1 / main.lua:169:尝试调用方法" update"(nil值)

追溯

States / map1 / main.lua:169:在"更新"函数中
[C]:在函数" xpcall"中

main-main.lua代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function clearLoveCallbacks()
    love.draw = nil
    love.joystickpressed = nil
    love.joystickreleased = nil
    love.keypressed = nil
    love.keyreleased = nil
    --love.load = nil
    love.mousepressed = nil
    love.mousereleased = nil
    love.update = nil
end

state = {}
function loadState(name)
    state = {}
    clearLoveCallbacks()
    local path ="states/" .. name
    require(path .."/main")
    load()
    local player
end

function load()
end

function love.load()
    loadState("map1")
end

/ states / map1 /-文件中的main.lua:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
player = table
local AdvTiledLoader = require("AdvTiledLoader.Loader")
require("camera")

function love.load()
    love.graphics.setBackgroundColor( 198, 220, 255 )
    song1 = love.audio.newSource("sound/Brightly_Fancy.mp3", true)
    song1:setVolume(0.1)
    song1:play()

    imgPlayer = love.graphics.newImage("textures/player.png")
    AdvTiledLoader.path ="maps/"
    map = AdvTiledLoader.load("map1.tmx")
    map:setDrawRange(0, 0, map.width * map.tileWidth, map.height * map.tileHeight)

    camera:setBounds(0, 0, map.width * map.tileWidth - love.graphics.getWidth(), map.height * map.tileHeight - love.graphics.getHeight() )

    world =     {
                gravity = 1536,  --1536
                ground = 512,
                }

    player =    {
                x = 256,
                y = 256,
                x_vel = 0,
                y_vel = 0,
                jump_vel = -1024,
                speed = 512, --512
                flySpeed = 700,
                state ="",
                h = 32,
                w = 32,
                standing = false,
                }
    function player:jump()
        if self.standing then
            self.y_vel = self.jump_vel
            self.standing = false
        end
    end

    function player:right()
        self.x_vel = self.speed
    end

    function player:left()
        self.x_vel = -1 * (self.speed)
    end

    function player:stop()
        self.x_vel = 0
    end

    function player:collide(event)
        if event =="floor" then
            self.y_vel = 0
            self.standing = true
        end
        if event =="cieling" then
            self.y_vel = 0
        end
    end

    function player:update(dt)
        local halfX = self.w / 2
        local halfY = self.h / 2

        self.y_vel = self.y_vel + (world.gravity * dt)

        self.x_vel = math.clamp(self.x_vel, -self.speed, self.speed)
        self.y_vel = math.clamp(self.y_vel, -self.flySpeed, self.flySpeed)

        local nextY = self.y + (self.y_vel*dt)
        if self.y_vel < 0 then
            if not (self:isColliding(map, self.x - halfX, nextY - halfY))
                and not (self:isColliding(map, self.x + halfX - 1, nextY - halfY)) then
                self.y = nextY
                self.standing = false
            else
                self.y = nextY + map.tileHeight - ((nextY - halfY) % map.tileHeight)
                self:collide("cieling")
            end
        end
        if self.y_vel > 0 then
            if not (self:isColliding(map, self.x-halfX, nextY + halfY))
                and not(self:isColliding(map, self.x + halfX - 1, nextY + halfY)) then
                    self.y = nextY
                    self.standing = false
            else
                self.y = nextY - ((nextY + halfY) % map.tileHeight)
                self:collide("floor")
            end
        end

        local nextX = self.x + (self.x_vel * dt)
        if self.x_vel > 0 then
            if not(self:isColliding(map, nextX + halfX, self.y - halfY))
                and not(self:isColliding(map, nextX + halfX, self.y + halfY - 1)) then
                self.x = nextX
            else
                self.x = nextX - ((nextX + halfX) % map.tileWidth)
            end
        elseif self.x_vel < 0 then
            if not(self:isColliding(map, nextX - halfX, self.y - halfY))
                and not(self:isColliding(map, nextX - halfX, self.y + halfY - 1)) then
                self.x = nextX
            else
                self.x = nextX + map.tileWidth - ((nextX - halfX) % map.tileWidth)
            end
        end

        self.state = self:getState()
    end

    function player:isColliding(map, x, y)
        local layer = map.tl["Solid"]
        local tileX, tileY = math.floor(x / map.tileWidth), math.floor(y / map.tileHeight)
        local tile = layer.tileData(tileX, tileY)
        return not(tile == nil)
    end

    function player:getState()
        local tempState =""
        if self.standing then
            if self.x_vel > 0 then
                tempState ="right"
            elseif self.x_vel < 0 then
                tempState ="left"
            else
                tampState ="stand"
            end
        end
        if self.y_vel > 0 then
            tempState ="fall"
        elseif self.y_vel < 0 then
            tempState ="jump"
        end
        return tempState
    end
end

function love.draw()
    camera:set()

    love.graphics.setColor( 255, 255, 255, 255 )
    love.graphics.draw( imgPlayer, player.x - player.w/2, player.y - player.h/2, 0, 1, 1, 0, 0)
    love.graphics.setColor( 255, 255, 255 )
    map:draw()

    camera:unset()
end

function love.update(dt)
    if dt > 0.05 then
        dt = 0.05
    end
    if love.keyboard.isDown("d") then
        player:right()
    end
    if love.keyboard.isDown("a") then
        player:left()
    end
    if love.keyboard.isDown("w") then --and not (hasJumped) then
        player:jump()  
    end

    player:update(dt)

    camera:setPosition( player.x - (love.graphics.getWidth()/2), player.y - (love.graphics.getHeight()/2))
end

function love.keyreleased(key)
    if (key =="a") or (key =="d") then
        player.x_vel = 0
    end
end

我真的不知道问题出在哪里:/


您的代码将无法以您认为的方式工作。 您调用love.load,然后加载设置其自己的love.loadlove.update的地图特定文件。 这将覆盖您以前使用的love.load,但是该更改无效,因为love.load仅被调用一次,因此您所在的特定于映射的初始化未执行,但是特定于映射的love.update代码已执行,但失败 因为它缺少初始化部分。 您需要重新组织代码,以便只有一个love.loadlove.update,但是它们会根据需要调用特定于地图的函数。 我建议您看一些love2d游戏的示例,以了解它们的组织方式。