Kenny
Kenny

Reputation: 2176

Corona / Lua Function scope

I'm new to Corona. I'm not sure how to solve this.

In main I am creating 2 local objects, player and enemy.

Player has a function called takeDamage.

When I try to call player.takeDamage from within enemy, it can't see the function.

I presume it's because main owns both objects and they don't know about each other.

How can I have Enemy call that function so that it can deal damage to Player?

main.lua contains:

-- Create player character
local player = require("player");
player = player.new();

-- Create enemy character
local enemy = require("enemy");
enemy = enemy.new();

I think I could make player global, but from what I know, that would not be a best practice.

Any help would be greatly appreciated.

Upvotes: 1

Views: 507

Answers (2)

Corbin March
Corbin March

Reputation: 25714

Ideally, you don't want the player referencing the enemy directly or the enemy referencing the player. Instead, you could poll each participant in a game loop and update the game state based on the result.

local player = make_player()
local enemy = make_enemy()

--game loop - in a real game this isn't a busy while
while true do

    local move = player.move()
    local result = validate_move(move)
    if result.is_valid then 
        update_position(player, result) 
    end

    move = enemy.move()
    result = validate_move(move)
    if result.is_valid then 
        update_position(enemy, result) 
    end

    local attack = player.attack()
    local attack_result = validate_attack(attack)
    if attack_result.hit then 
        update_health(enemy, attack_result) 
    end

    -- more game logic here

    render(player)
    render(enemy)
end

In a real game, state change would be driven by events - touch events, drawing events, etc. My busy loop (while true do) illustrates the general idea.

You'll also have to use your imagination for missing implementation.

There are many ways to model a game. I'm not suggesting this is the best. It does, however, show one way of decoupling interacting elements.

Upvotes: 1

Michal Kottman
Michal Kottman

Reputation: 16753

If it is safe to assume that there will be only one "player" instance, you can make it global. Otherwise, you would have to do something along these lines:

-- main.lua
local player = require 'player'.new()
local enemy = require 'enemy'.new()
enemy:setPlayer(player)

-- enemy.lua
...
function enemy:setPlayer(player)
  self.player = player
end

And later use self.player in the enemy code to reference the player. Note that this will consume memory, because the player reference will be copied to every enemy instance.

One side note, I do not consider it good to call a module and an instance the same, i.e. player. It will become unclear later if you mean the module, or the instance. A safe way would be to call the modules as Player and Enemy, and the code will look like this:

Player = require 'Player'
local player = Player.new()

Upvotes: 1

Related Questions