Hola,
Ésta vez vengo a reportar un posible bug que en OneLua, el cual me ha causado un dolor de cabeza mientras lo asimilaba lo que pasaba en el debugeo XD
O bien, esto puede ser un error lógico de mi parte, (ojalá que así sea jaja).
Resulta que después de programar un par de 'controles', para el proyecto que me encuentro desarrollando, los cuales son: Image, en el cual tiene propiedades como el ancho y alto, sus coordenadas en x,y & métodos respectivos a sus requerimientos funcionales.
Pues las funciones para el componente Image es guardar la referencia a una imagen (éste puede ser sprite o imagen normal) donde sus propiedades width y height hacen uso de las funciones image.getw y image.geth, respectivamente.
Entonces, el error que tengo es que cuando hago uso de image.getw para un sprite, éste me devuelve el ancho total del sprite y no del frame como se desea, pues ya se ha hecho uso del mismo método para otros sprites y dicha función a primera instancia devuelve el ancho de la imagen y posteriormente devuelve el ancho del frame en algunas ocaciones.
A continuación, dejo imágenes representativas:
Imagen A
Imagen B
En la imagen A, se puede apreciar la pantalla de ajustes cuando es mostrada por primera vez, y en la imagen B se muestra la pantalla cuando es mostrada por segunda vez (esto es desde A a B, presionando 'O Back' y volviendo a entrar a Settings desde el menu principal) y se nota que se hace un reajuste en las imágenes.
Ahora dejo el código en orden de ejecución del script.
Controles y componentes principales
--[[ File: image.lua Author: PerezRE Description: Represents an image object ]] Image = {} Image.__index = Image setmetatable(Image, { __call = function(cls, x, y, img, frame) return cls.new(x, y, img, frame) end }) function Image.new(x, y, img, frame) return setmetatable({ img = img, x = x, y = y, frame = frame, width = image.getw(img), height = image.geth(img), }, Image) end function Image:print() if self.frame == nil then image.blit(self.img, self.x, self.y) else image.blitsprite(self.img, self.x, self.y, self.frame or 0) end end
--[[ File: menu.lua Author: PerezRE Description: Menu object ]] dofile('/modules/controls/menu_item.lua') Menu = {} Menu.__index = Menu setmetatable(Menu, { __call = function(cls, x, y, padding, width) return cls.new(x, y, padding, width) end }) function Menu.new(_x, _y, _width, _padding) return setmetatable({ x = _x or 0, y = _y or 0, width = _width or 125, height = 0, p = _padding or 1, cur_menuitem = 0, menu_items = {}, }, Menu) end function Menu:add_item(text) if text == nil then return end local menu_item = MenuItem(self.x, 0, text, self.width) table.insert(self.menu_items, menu_item) self:_initialize() end function Menu:remove_item(index) if index > 0 and index <= #self.menu_items then table.remove(self.menu_items, index) self:_initialize() end end function Menu:_initialize() local y = self.y self.height = 0 if #self.menu_items > 0 then self.cur_menuitem = 1 self.height = (self.p + self.menu_items[1].height) * self:size() - self.p end for i=1, #self.menu_items do self.menu_items[i].x = self.x self.menu_items[i].y = y y = y + self.p + self.menu_items[i].height end end function Menu:size() return #self.menu_items end function Menu:selected_down() self.cur_menuitem = self.cur_menuitem + 1 if self.cur_menuitem >= self:size() then self.cur_menuitem = self:size() end end function Menu:selected_up() self.cur_menuitem = self.cur_menuitem - 1 if self.cur_menuitem <= 0 then self.cur_menuitem = 1 end end function Menu:print() for i=1, #self.menu_items do self.menu_items[i].selected = i == self.cur_menuitem self.menu_items[i]:print() end end
--[[ File: component.lua Author: PerezRE Description: Just like Composite pattern ]] GroupComponent = {} GroupComponent.__index = GroupComponent setmetatable(GroupComponent, { __call = function(cls, x, y, padding) return cls.new(x, y, padding) end }) function GroupComponent.new(x, y, padding) return setmetatable({ padding = padding or 5, components = {}, x = x, y = y, width = 0, height = 0 }, GroupComponent) end function GroupComponent:add(component) table.insert(self.components, component) self:_update() end function GroupComponent:remove(index) table.remove(self.components, index) self:_update() end function GroupComponent:_update() local x = self.x self.width = 0 for _,component in pairs(self.components) do component.x = x component.y = self.y x = component.x + component.width + self.padding self.width = self.width + component.width + self.padding end if self.width ~= 0 then self.width = self.width - self.padding end end function GroupComponent:print() for _,component in pairs(self.components) do component:print() end end
En runtime
--[[ File: menu_state.lua Author: PerezRE Description: It represents an game state ]] local MenuSate = {} MenuSate.__index = MenuSate setmetatable(MenuSate, { __call = function(cls, game_engine) return cls.new(game_engine) end }) function MenuSate.new(_game_engine) return setmetatable({ game_engine = _game_engine }, MenuSate) end function MenuSate:on_state() local di = self.game_engine.di local sound = di.loader:sound('menu_' .. math.random(3)) di.container:add('font', di.loader:font('halo-ltn0')) di.container:add('buttons', di.loader:sprite('buttons', 20, 16.42)) dofile(di.loader.modules.controls .. 'image.lua') dofile(di.loader.modules.controls .. 'menu.lua') dofile(di.loader.modules.engine.api .. 'rendering/component.lua') local view = assert(loadfile(di.loader.modules.engine.views_dir .. 'menu/menu.lua'))(di) messenger:send('sound_manager', { action = 'play_loop', payload = sound }) messenger:send('render', { action = 'print', payload = view }) end local args = {...} -- GameEngine return MenuSate(args[1])
Luego se muestra el menu principal y seleccionamos ajustes, éste hace la carga del script de ajustes:
local args = {...} local di = args[1] local background = Image(0, 0, di.loader:image('/backgrounds/settings')) local title = Label(20, 50, di.lang:read('menu', 'settings'), 1, nil, nil, nil, di.container:get('font')) local img_btns = di.container:get('buttons') local btn = { o = 0, x = 1, l = 2, r = 3 } -- Accept label and button icon local accept = Label(0, 0, di.lang:read('text', 'accept'), 0.5) local cross_icon = Image(0, 0, img_btns, btn.x) -- Back label and button icon local back = Label(0, 0, di.lang:read('text', 'back'), 0.5) local circle_icon = Image(0, 0, img_btns, btn.o) local group_buttons = GroupComponent(0, 272 - accept.height, 5) group_buttons:add(circle_icon) group_buttons:add(back) group_buttons:add(cross_icon) group_buttons:add(accept) -- Menu local menu = Menu(5, 86, 150) menu:add_item(di.lang:read('settings', 'lang')) menu:add_item(di.lang:read('settings', 'controls')) menu:add_item(di.lang:read('settings', 'default')) menu:add_item(di.lang:read('settings', 'save')) local delta = { x = menu.width - 15, y = menu.y + 4 } -- Lang and misc icons local langs_files = files.listfiles('/assets/lang/') local langs = {} for i=0, #langs_files - 1 do local filename = langs_files[i+1].name:lower() langs[filename:gsub('.' .. langs_files[i+1].ext, '')] = i end local langs_icons = di.loader:sprite('config/langs', 16, 11) local lang_icon = Image(delta.x, delta.y, langs_icons, langs[di.config.lang]) local lpad_icon = Image(delta.x - 22, delta.y - 3, img_btns, btn.l) local rpad_icon = Image(delta.x + 18, delta.y - 3, img_btns, btn.r) local group_lang = GroupComponent(delta.x, delta.y, 3) group_lang:add(lpad_icon) group_lang:add(lang_icon) group_lang:add(rpad_icon) -- GUI Elements to be printed local gui_elements = { background, title, menu, group_lang, --lang_icon, group_buttons } repeat for i=1, #gui_elements do gui_elements[i]:print() end if menu.cur_menuitem == 1 then lpad_icon:print() rpad_icon:print() end buttons.read() if buttons.right and menu.cur_menuitem == 1 then lang_icon.frame = lang_icon.frame + 1 elseif buttons.left and menu.cur_menuitem == 1 then lang_icon.frame = lang_icon.frame - 1 elseif buttons.up then menu:selected_up() elseif buttons.down then menu:selected_down() end if lang_icon.frame > 2 then lang_icon.frame = 2 elseif lang_icon.frame < 0 then lang_icon.frame = 0 end screen.flip() until buttons.circle
Cualquier duda o sugerencia déjenlo en los comentarios.
¡Saludos!
--[NO EXISTEN LOS LIMITES =D]--
Posiblemente
Hola PerezRE!,
Posiblemente el fallo se deba a que requieres hacer un blitsprite para que este torne su w y h a lo del sprite,
Puedes solucionarlo usando en tu objeto Image valores de w y h definidos cuando sea un sprite (ya que estos no cambiaran),
Solucionado
Hola, DevDavisNunez!
Un gusto saber que aún hay gente activa por aquí de vez en cuando.
Regresando al tema; seguí la sugerencia que me indicaste y éste ya quedó solucionado, no sé como no se me ocurrió antes jaja.
Supongo que me aferre a la idea de que fuese "automático" pero supongo que da igual, pues como mencionas, el ancho y alto, al ser un frame, no cambian.
Te agradezco la replica.
¡Saludos!
--[NO EXISTEN LOS LIMITES =D]--
Excelentes Noticias!
Excelente PerezRE!
Bueno, de vez en cuando aun entro a SB por sentimentalismo!,
Ya no esta tan activa como solia estar, pero igual, si tienes alguna duda y no respondo manda Mensaje, asi me notifica en breve.
Saludos y suerte en el proyecto!
Te entiendo, Ahora todo ha
Te entiendo,
Ahora todo ha cambiado pero bueno, aun tengo un par de proyectos que ofrecer, aunque estos van algo lentos por compromisos escolares y laborales >.<' pero haré todo lo posible por verlos realizados.
¡Saludos!
--[NO EXISTEN LOS LIMITES =D]--