Hello,
I tried loading an external script using require from the map script and I tried the same thing from the game manager, but it seems the map script prevented the script from loading in the game manager.
In the map I did:
local name_listing = require("scripts/pick_name.lua")
code here.....
if key == "p" then
name_listing:name_picker() -- Require name_list.lua
end
It worked, but the map script stopped running. How would I get both scripts to run at the same time? Does it have to do with both scripts using same functions for key presses and image drawing?
-Zefk
It should totally be possible to have your game manager and your map running the same script. Although I'm not sure why you'd want the map and the game manager to both be processing key presses for the same script. You're going to have to provide more detail on what your script does and what you are trying to accomplish.
If one of your on_key_pressed() functions returns true, it prevents the on_key_pressed() function from getting called elsewhere for that key press that was already handled.
QuoteIf one of your on_key_pressed() functions returns true, it prevents the on_key_pressed() function from getting called elsewhere for that key press that was already handled.
I think this is the case.
Scripts:I will paste my scripts and simplified my map script because it was too long, but beware....they are still a little messy. This is kinda just an experiment.
game manager.lua (I commented out "name_listing:name_picker() " because it would not run with the map script.)
local game_manager = {}
local name_listing = require("scripts/pick_name.lua")
local initial_game = require("scripts/initial_game")
require("scripts/menus/alttp_dialog_box")
-- Starts the game from the given savegame file,
-- initializing it if necessary.
function game_manager:start_game()
--name_listing:name_picker()
local exists = sol.game.exists("save1.dat")
local game = sol.game.load("save1.dat")
if not exists then
-- Initialize a new savegame.
game:set_max_life(12)
game:set_life(game:get_max_life())
game:set_ability("lift", 2)
game:set_ability("sword", 1)
end
game:start()
local hero = game:get_hero()
hero:set_tunic_sprite_id("main_heroes/eldran")
end
return game_manager
first_map.lua: (This shows an image textbox menu. I normally would not have this code in a map script. I am seeing if it works.)
Without all the code:local name_listing = require("scripts/pick_name.lua")
code here.....
if key == "p" then
name_listing:name_picker() -- Require name_list.lua
end
With all the code simplified:local name_listing = require("scripts/pick_name.lua")
--Tell the script it is a map and to use game functions
local name_listing = require("scripts/pick_name.lua")
local map = ...
local game = map:get_game()
--A table because I like tables and it prevents upvalue errors
local text_box = {
--Lowercase arrays because listing these variables would be a pain.
main_box = {},
main_box_row_2 = {},
main_box_row_3 = {},
main_box_row_4 = {},
box_x ={},
place_x = {},
num1_place = {},
--Boolean for the lower case letters, numbers, and special characters
num1_img = sol.surface.create("lower_case/1.png"),
--box images to false
blinker = false,
lower_case = false,
upper_case = false,
letter_box_background = false,
--load box images
blinker_img = sol.surface.create("blinker.png"),
large_box_img = sol.surface.create("large_box.png"),
main_box_img = sol.surface.create("main_box.png"),
lower_case_img = sol.surface.create("lower_case.png"),
upper_case_img = sol.surface.create("upper_case.png"),
letter_box_background_img = sol.surface.create("letter_input_background.png"),
--direction keyboard to false, so it does not mess with hero movements.
key_picker_direction = 0,
right_key = false,
left_key = false,
up_key = false,
down_key = false,
--Place for char input
place = {},
shift = {},
lowercase_shift = true,
uppercase_shift = false,
naming_character = {},
character = {},
char = {},
name = {},
character_num ={},
character_cals = {},
}
--Main box that browses the letters, numbers, and special characters.
--***************place checks. Keep space, blinker movement/animation, and erase in mind.
--text_box.place[0] = true does nothing apparently, so this activates text_box.place[1] = true
local place = true
--Naming for character number "1" which is most likely the hero.
text_box.character_num[1] = true
--Calculate which character string is true during naming. zero makes character one false based on the calculations for "enter."
--This must equal zero because each time you press enter 1 is added.
-- EX: *Presses enter* character_cal = 1 (now you can name character 2)
local character_cal = 0
--Amount or number of characters set to false. That means the characters that are done being named (enter pressed).
--This must equal zero because each time you press enter 1 is added.
-- Ex: text_box.character_num[amount_false] = true
local amount_false = 0
--This is a backspace and input limit. Make sure this is one (1) below char_amount. If char_limit is 15, then char_amount is 16 for 15 letters, numbers, and/or special characters. Otherwise, it will not backspace.
local char_limit = 15
--This is the loop amount. This must be 16 to make 15 false when using backspace. If 150, then set it to 151.
local char_amount = 16
--Number of images to show. I set the limit to 15.
local char_image_num = 15
--Character limit. Want to name a million monsters? Ex: Pokemon? Change it to over 150!
local character_limit = 15
--Max char to make a string that will be passed on to the textbox with $v
local max_char = 15
--The draw function for showing images
function sol.main:on_draw(screen)
--Textbox images and blinker
if text_box.letter_box_background == true then
text_box.letter_box_background_img:draw(screen)
end
if text_box.blinker == true then
text_box.blinker_img:draw(screen,-1,-2)
end
if text_box.upper_case == true then
text_box.upper_case_img:draw(screen)
end
if text_box.lower_case == true then
text_box.lower_case_img:draw(screen)
end
if text_box.large_box == true then
text_box.large_box_img:draw(screen)
end
if text_box.cancel_box == true then
text_box.cancel_box_img:draw(screen)
end
--Main green box letter picker positions
for x = 0,11 do
--first row
if text_box.main_box[x] == true then
text_box.main_box_img:draw(screen, text_box.box_x[x])
end
--second row
if text_box.main_box_row_2[x] == true then
text_box.main_box_img:draw(screen, text_box.box_x[x],22)
end
--third row
if text_box.main_box_row_3[x] == true then
text_box.main_box_img:draw(screen, text_box.box_x[x],42)
end
--4th row
if text_box.main_box_row_4[x] == true then
text_box.main_box_img:draw(screen, text_box.box_x[x],62)
end
end
--Large green main text boxes
if text_box.main_box[12] == true then
text_box.large_box_img:draw(screen,0,0)
end
if text_box.main_box_row_2[12] == true then
text_box.large_box_img:draw(screen,0,20)
end
if text_box.main_box_row_3[12] == true then
text_box.large_box_img:draw(screen,0,40)
end
if text_box.main_box_row_4[12] == true then
text_box.large_box_img:draw(screen,0,60)
end
--Display char images
for char = 1,char_image_num do
--lowercase drawing
--Draw text number 1 (one) up to 15 places
if text_box.num1_place[char] == true then
text_box.num1_img:draw(screen, text_box.place_x[char])
end
end
end --end of draw function
function sol.main:on_key_pressed(key)
if key == "space" then
--text_box.blinker = true
if text_box.lowercase_shift == true then
text_box.lower_case = true
else
text_box.lower_case = false
end
if text_box.uppercase_shift == true then
text_box.upper_case = true
else
text_box.upper_case = false
end
text_box.letter_box_background = true
text_box.key_picker_direction = 1
text_box.left_key = true
text_box.right_key = true
text_box.up_key = true
text_box.down_key = true
if place == true then
text_box.place[1] = true
else
text_box.place[1] = false
end
game:set_paused(true)
end
--Left control for the key place digits
if key == "right" and text_box.right_key == true
then
print("minus 12 from browse 12")
sol.audio.play_sound("cursor")
if text_box.key_picker_direction == 12
then
text_box.key_picker_direction = text_box.key_picker_direction - 12
text_box.main_box[12] = false
end
end
--Key main box green picker
--1 to 12 calculations
for x = 0,4 do
text_box.box_x[x] = x * 17 - 17
for x = 5,7 do
text_box.box_x[x] = x * 16 - 13
for x = 7,9 do
text_box.box_x[x] = x * 16 - 12
for x = 10,11 do
text_box.box_x[x] = x * 16 - 11
end
end
end
end
--Calculations "char"
for char = 1,char_image_num do
text_box.place_x[char] = char * 9
end
if text_box.key_picker_direction == 1 then
text_box.main_box[1] = true
text_box.main_box[2] = false
end
if text_box.uppercase_shift == true then
if text_box.key_picker_direction == 48 and key == "e" then
text_box.shift[2] = true
text_box.key_picker_direction = 0
text_box.lowercase_shift = true
text_box.uppercase_shift = false
end
end
if text_box.lowercase_shift == true then
if text_box.key_picker_direction == 48 and key == "e" then
text_box.shift[1] = true
text_box.uppercase_shift = true
text_box.lowercase_shift = false
end
end
for i = 0,char_amount do
--input from box position 1
if text_box.place[i] == true then
if key == "e" and text_box.place[i] == true then
sol.audio.play_sound("wrong")
end
--Delete or backspace
if text_box.key_picker_direction == 12 and key == "e" then
if i <= 16 then
if text_box.naming_character[i] == true then
table.remove(text_box.character)
end
text_box.exclamation_place[i - 1] = false
if text_box.place[1] == true then
text_box.place[i - 2] = true
--text_box.place[i] = false
else
text_box.place[i - 1] = true
text_box.place[i] = false
print("*************************************************************************************", i)
end
end
break
end
if text_box.key_picker_direction == 1 and key == "e" and text_box.lowercase_shift == true then
--Inserting char "1" calculations for 15 different characters
if i <= char_limit then
if text_box.naming_character[i] == true then
text_box.char[i] = "1"
table.insert(text_box.character,text_box.char[i])
end
text_box.num1_place[i] = true
text_box.place[i + 1] = true
text_box.place[i] = false
break
end
else
if text_box.key_picker_direction == 1 and key == "e" then
--Inserting char "!" calculations for 15 different characters
if i <= char_limit then
if text_box.naming_character[i] == true then
text_box.char[i] = "!"
table.insert(text_box.character,text_box.char[i])
end
text_box.exclamation_place[i] = true
text_box.place[i + 1] = true
text_box.place[i] = false
break
end
end
end
end
if text_box.shift[1] == true then
if text_box.uppercase_shift == true then
text_box.upper_case = true
text_box.lower_case = false
print("uppercased!")
end
if text_box.lowercase_shift == true then
if text_box.upper_case == true then
text_box.key_picker_direction = 48
end
text_box.upper_case = false
text_box.lower_case = true
print("lowercased!")
end
end
--Allow 15 char to pass on to the character being named.
for i = 1,max_char do
text_box.naming_character[i] = true
end
print("Browse is:", text_box.key_picker_direction)
print("Char is:", table.concat(text_box.character))
for i = 1,character_limit do
if text_box.character_num[i] == true then
text_box.name[i] = table.concat(text_box.character)
print("character", i, "name is:", text_box.name[i])
break
end
end
for i = 1,character_limit do
print("character", i, "1 name is:", text_box.name[i])
--break
end
if key == "p" then
name_listing:name_picker()
end
end
pick_name.lua (This is in the scripts folder. It shows an image with text on it. I want it to show while the map script image menu is showing)
--Tell the script to use game functions
local game = ...
local name_listing = {}
function name_listing:name_picker(game)
local name_list ={
browse_list = 0,
green_box = {},
green_box_y ={},
list_bg = false,
list = false,
up_list = false,
down_list = false,
list_bg_img = sol.surface.create("name_pick/name_list_bg.png"),
list_img = sol.surface.create("name_pick/name_list.png"),
green_box_img = sol.surface.create("name_pick/green_box.png"),
}
local list_box_amount = 8
--The draw function for showing images
function sol.main:on_draw(screen)
if list_bg == true then
name_list.list_bg_img:draw(screen)
end
if list == true then
name_list.list_img:draw(screen)
end
for y = 0,list_box_amount do
if name_list.green_box[y] == true then
name_list.green_box_img:draw(screen,0,name_list.green_box_y[y])
end
end
end --end of draw function
function sol.main:on_key_pressed(key)
if key == "o" then
list_bg = true
list = true
up_list = true
down_list = true
end
if key == "up" and up_list == true then
sol.audio.play_sound("cursor")
if name_list.browse_list <= 8 then
name_list.browse_list = name_list.browse_list + 1
end
end
if key == "down" and down_list == true then
sol.audio.play_sound("cursor")
if name_list.browse_list >= 0 then
name_list.browse_list = name_list.browse_list - 1
end
end
for y = 0,list_box_amount do
name_list.green_box_y[y] = y * 9
end
if name_list.browse_list == 1 then
name_list.green_box[1] = true
name_list.green_box[2] = false
end
if name_list.browse_list == 2 then
name_list.green_box[1] = false
name_list.green_box[2] = true
name_list.green_box[3] = false
end
if name_list.browse_list == 3 then
name_list.green_box[2] = false
name_list.green_box[3] = true
name_list.green_box[4] = false
end
if name_list.browse_list == 4 then
name_list.green_box[3] = false
name_list.green_box[4] = true
name_list.green_box[5] = false
end
if name_list.browse_list == 5 then
name_list.green_box[4] = false
name_list.green_box[5] = true
name_list.green_box[6] = false
end
if name_list.browse_list == 6 then
name_list.green_box[5] = false
name_list.green_box[6] = true
name_list.green_box[7] = false
end
if name_list.browse_list == 7 then
name_list.green_box[6] = false
name_list.green_box[7] = true
name_list.green_box[8] = false
end
if name_list.browse_list == 8 then
name_list.green_box[7] = false
name_list.green_box[8] = true
name_list.green_box[9] = false
end
end -- End of buttoon press function
end -- end of require function
return name_listing
Your problem is that your script defines sol.main:on_key_pressed(key), which can only be defined once. When your game_manager calls the pick_name.lua script, it defines sol.main:on_key_pressed(key). Then when your map loads the calls the pick_name.lua script, a new function is assigned to sol.main:on_key_pressed(key), overwriting the old one.
Using sol.main:on_key_pressed(key) is not the correct way to do things. You really only need that for handling key presses that are handled all the time, including when there isn't a game running (an example would be alt+f4 to exit). And then only define sol.main:on_key_pressed(key) exactly one time. Likewise for sol.main:on_draw()
What you should do instead is make your pick_name.lua script be a menu. So in your pick_name.lua script:
--function sol.main:on_draw(screen) --replace this line with the following
function name_listing:on_draw(screen)
--function sol.main:on_key_pressed(key) --replace this line with the following
function name_listing:on_key_pressed(key)
And then to "run" your script, do the following:
--from game_manager.lua:
local name_listing = require("scripts/pick_name.lua")
function game_manager:start_game()
local exists = sol.game.exists("save1.dat")
local game = sol.game.load("save1.dat") --note this line must come before starting the menu
sol.menu.start(game, name_listing) --assuming you want to start the menu as soon as your game starts
--additional code...
end
--from first_map.lua:
local name_listing = require("scripts/pick_name.lua")
local map = ...
--additional code...
--function sol.main:on_draw(screen) --replace this line with the following
function map:on_draw(screen)
--additional code...
end
--function sol.main:on_key_pressed(key) --replace this line with the following
function map:on_key_pressed(key)
--additional code...
if key == "p" then
sol.menu.start(self, name_listing)
end
end
When you no longer want the pick_name.lua script to be drawing to the screen or handling key press events, call the following:
sol.menu.stop(name_listing)
And by the way, you should delete the following line from your pick_name.lua script. It doesn't work the way you think it works for scripts loaded using require.
local game = ... --delete this line (line 2)
I understand now. I will rework my scripts to follow the menu process. Thank you llamazing for using your time to assist me.
The problem is, if you are using this menu as a way to draw bitmaps on the screen without using map:on_draw() (which is the way to go), it wouldn't work, because your require is recognized as menu, so you need to start the menu through sol.menu.start(map, name_listing) to draw the content of your menu. Llamazing got it right