My code generated gui box node appears correctly in a desktop and Android build but displays as a black box in an HTML5 build. It should show a map of the current game level. Any ideas why this might be?
Hmm, strange. @sven, @Mathias_Westerdahl, @Andreas_Tadic: Is there any reason a run-time created box node with a run-time created texture wouldn’t work correctly on HTML5?
No, and I cannot reproduce it either. It works for me.
However, I had to change the alpha value from 0 in order to actually see the node to begin? (transparent on both desktop and html5). But after that, it worked on both desktop and html5.
Do you have a special gui shader? Or any texture profiles on HTML5?
Hmm, ok.
How do you create the texture?
When I tested, I used the code from the example:
-- untested code (I have the tested code at home)
local w = 128
local h = 128
local orange = string.char(0xff) .. string.char(0x80) .. string.char(0x10)
-- Create the texture. Repeat the color string for each pixel.
if gui.new_texture("map", w, h, "rgb", string.rep(orange, w * h)) then
mapnode = gui.new_box_node(vmath.vector3(224, 360, 0), vmath.vector3(w, h, 0))
gui.set_scale(mapnode, vmath.vector3(1, 1, 0))
gui.set_texture(mapnode, "map")
gui.set_pivot(mapnode, gui.PIVOT_CENTER)
gui.set_color(mapnode, vmath.vector4(1, 1, 1, 1)) -- alpha 1
gui.set_adjust_mode(mapnode, gui.ADJUST_STRETCH)
end
Here’s the whole function - it creates a map texture of the current level.
function generate(self)
local sx, sy, w, h = tilemap.get_bounds(self.levelurl)
local pixels = ""
local solid = string.char(0x00) .. string.char(0x00) .. string.char(0x00) .. string.char(0x44)
local player = string.char(0x66) .. string.char(0x00) .. string.char(0x00) .. string.char(0xaa)
local door = string.char(0x00) .. string.char(0x00) .. string.char(0x00) .. string.char(0x22)
local stairs = string.char(0x00) .. string.char(0x66) .. string.char(0x00) .. string.char(0xaa)
local floor = string.char(0x00) .. string.char(0x00) .. string.char(0x00) .. string.char(0x00)
pos.x = math.floor(data.playerpos.x / 16) + 1
pos.y = math.floor(data.playerpos.y / 16) + 1
for y = sy + h - 1, sy, -1 do
for x = sx, sx + w - 1 do
local tile = tilemap.get_tile(self.levelurl, "world", x, y)
local fog = tilemap.get_tile(self.levelurl, "fog", x, y)
local item = tilemap.get_tile(self.levelurl, "items", x, y)
if x == pos.x and y == pos.y then
pixels = pixels .. player
elseif fog == 0 and tile >= 289 then
pixels = pixels .. solid
elseif fog == 0 and tile >= 280 then
pixels = pixels .. door
elseif fog == 0 and (item == 267 or item == 268) then
pixels = pixels .. stairs
else
pixels = pixels .. floor
end
end
end
if gui.new_texture("map", w, h, "rgba", pixels) then
mapnode = gui.new_box_node(vmath.vector3(224, 360, 0), vmath.vector3(w, h, 0))
gui.set_scale(mapnode, vmath.vector3(MAP_SCALE, MAP_SCALE, 0))
gui.set_texture(mapnode, "map")
gui.set_pivot(mapnode, gui.PIVOT_CENTER)
gui.set_color(mapnode, vmath.vector4(1, 1, 1, 1))
gui.set_adjust_mode(mapnode, gui.ADJUST_STRETCH)
end
end
I feel this is bug, let me explain my experience, after running the set_texture code in a dynamic script gui included in my texture_load function, the sample code for creating a box node won’t display a box.
If I try to create this box node before trying to set this textures I can see the box, I feel like there is some problem with HTML5 and setting dynamic textures, not something I need for my project, but tested it just to check.
function textures_load()
-- Load Chapter Image
local f = assert(io.open("assets/img.png", "rb"))
local data = assert(f:read("*a"))
img = image.load(data, true)
local type = (img.type == image.TYPE_RGB) and "rgb" or "rgba"
gui.new_texture("chapter_image", img.width, img.height, type, img.buffer, false)
-- Load Background Image
f = assert(io.open("assets/bk.png", "rb"))
data = assert(f:read("*a"))
img_bk = image.load(data, true)
type = (img_bk.type == image.TYPE_RGB) and "rgb" or "rgba"
gui.new_texture("back_image", img_bk.width, img_bk.height, type, img_bk.buffer, false)
end
function init(self)
-- Add initialization code here
-- Learn more: https://defold.com/manuals/script/
-- Remove this function if not needed
msg.post(".", "acquire_input_focus") -- <1>
self.state = "-"
textures_load()
-- Create a new box node
local new_position = vmath.vector3(400, 300, 0)
local new_size = vmath.vector3(450, 400, 0)
local new_boxnode = gui.new_box_node(new_position, new_size)
gui.set_color(new_boxnode, vmath.vector4(0.2, 0.26, 0.32, 1))
Wasn’t my intention to call it, just saying, if I create a node, with a solid color after doing the gui.new_texture commands, this node won’t be seen, it think it will go transparent.
If I try to create the same node prior to calling textures_load(), the node can be seen ok.
I now realise that this won’t work on HTML5. File access in HTML5 is quite different and I don’t see how you would be able to load the files like that. You need to load the files in one of two ways:
Using either bundle resources and a normal http.request()
Using custom resources and sys.load_resource()
Note: Functions like io.* and sys.load()/save() works in HTML5 but instead of reading/writing from the local file system or webserver a file system is emulated using the IndexedDB API in the browser.