Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 3761 miembros registrados.
El último usuario registrado es Abraham 331.

Nuestros miembros han publicado un total de 85756 mensajes en 12212 argumentos.

Duda sobre clases internas, GDIplus o SFML

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP Duda sobre clases internas, GDIplus o SFML

Mensaje por Eron el 2017-02-13, 08:13

Hola chicos =) No sabía donde poner ésto así que lo pongo aquí.

He estado tocando cosas de scripts después de bastante tiempo. Me preguntaba si hay alguna forma de modificar algunas clases internas como Audio, Bitmap, Sprite, Window y todo eso por una librería que soporte mucho mejor rendimiento y funciones, tipo GDI+ (para bitmaps/gráficos avanzados) o SFML (para gráficos y audio). También no me interesa tanto personalmente pero sería interesante reescibir cosas usando SoLoud (para audio). He buscado por ahí y hay poca cosa sobre el tema... Intenté hacer algunas pruebas con ámbos descargando las librerías y poniéndolas en el proyecto pero no logré nada de nada, con SFML por ejemplo me salta error de LoadLibrary. Se me dan bastante mal esas cosas así que no sé x'D ¿sería buena idea? ¿hay algún modo? ¿hay álguien lo haya hecho ya?

Por cierto, ¿qué usa el RPG maker por defecto para los gráficos? ¿DirectX como con el Audio, o GDI normal? Quizá si no se puede cambiar al menos se pueda ampliar. Según lo que leí en un post del foro lo que usa por defecto el RPG maker es GDI, yo creía que no era así pero he intenado obtener el HDC del proyecto con GetDC y hacer varias pruebas con eso y parece que sí... Entonces el GDI pese a ser lento ya tiene opciones que se podrían ampliar y mejorar sin tanto cambio estructural.
avatar
Eron
Principiante
Principiante

0/3

Créditos 1995

Gracias : 56

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Wecoc el 2017-02-13, 18:57

Sí, el maker usa GDI, el cual es muy lento porque no usa aceleración por hardware. Ha habido algunos intentos de mejorarlo, por ejemplo usar openGL o DirectX por la parte gráfica supondría una gran mejora. No sé si has oído a hablar del ARGSS; éste proyecto que al menos que yo sepa nunca salió a la luz (su web está caída y vgvgf está desaparecido), inicialmente usaba SDL + openGL y seguía siendo muy lento para según qué cosas, pero leí por ahí que se estaba portando a no sé qué otro sistema. Por cierto, el EasyRPG no tengo ni idea de qué usa xD

Sobre el GDI, creo que curiosamente está más pensado para programas de dibujo que para juegos. Dentro de las bitmaps sus mejoras respecto al "sistema default" del maker son pocas y se han aplicado en varios scripts a veces mediante otras dlls; cuadros con degradado, algunas funciones de los textos... No entiendo demasiado del tema, quizá se pueda sacar algo más de lo que ofrece pero no creo que sea mucho.

Sobre el GDI+ ví que se había logrado aplicarlo en parte, pero en Wolf RPG Editor, así que debería ser totalmente factible en RPG maker también. Publiqué sobre ello en el Topic de aportación de ideas. Yo mismo hice un intento de uso para WecTools pero acabé desechándolo porque no me salía a cuenta, quizá tú tengas más suerte.

Y con los demás, ni idea... pero veo que SoLoud tiene una API para RPG maker así que debería ser coser y cantar ;D
avatar
Wecoc
Administrador
Administrador



Créditos 9360

Gracias : 516

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Eron el 2017-02-15, 08:14

No logré nada de momento, intenté dibujar un recuadro a la bitmap pero no lo conseguí porque no sé sacar el hDC de la bitmap, solo de la ventana, entre otros detalles. Es más duro de lo que creía =(

Código:
module Utils
  
  GPPSA = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'PPPPLP', 'L')
  WPPSA = Win32API.new('kernel32', 'WritePrivateProfileStringA', 'PPPP', 'L')
  RPGMAKER_NAME    = File.open('Game.rxproj').read.split(" ")[0]
  RPGMAKER_VERSION = File.open('Game.rxproj').read.split(" ")[1].to_f
  
  module_function
  def get_string(id, tag = 'Game', file = '.\\Game.ini')
    buffer = "\0" * 255
    GPPSA.call(tag, id, '', buffer, 255, file)
    buffer.delete!("\0")
  end
  
  def set_string(string, id, tag = 'Game', file = '.\\Game.ini')
    WPPSA.call(tag, id, string, file)
  end
end

module GDI
  
  FindWindowA = Win32API.new('user32', 'FindWindowA', 'pp', 'l')
  GetWindowDC = Win32API.new('user32', 'GetWindowDC', 'l', 'l')
  
  module_function
  def hWND
    if @hwnd == nil
      @hwnd = FindWindowA.call('RGSS Player', Utils.get_string('Title'))
    end
    return @hwnd
  end
  
  def hDC
    if @hdc == nil
      @hdc = GetWindowDC.call(GDI.hWND)
    end
    return @hdc
  end
end

class Bitmap
  
  CreateSolidBrush = Win32API.new('gdi32', 'CreateSolidBrush', 'l', 'l')
  SelectObject     = Win32API.new('gdi32', 'SelectObject', 'll', 'l')
  GetDC            = Win32API.new('user32', 'GetDC', 'l', 'l')
  Rectangle        = Win32API.new('gdi32', 'Rectangle', 'lllll', 'l')
  
  def hDC
    GetDC.call(self.__id__) # ¡No funciona!
  end
  
  def n2color(n)
    r = (n & 0x000000FF)
    g = (n & 0x0000FF00) >> 8
    b = (n & 0x00FF0000) >> 16
    # Faltaría el alpha
    return Color.new(r, g, b)
  end
  
  def color2n(color)
    0 # Falta definir el número partiendo del color
  end
  
  def RGB(r, g, b)
    return color2n(Color.new(r, g, b))
  end
  
  def rectangle(x, y, width, height, color)
    brush = CreateSolidBrush.call(color2n(color))
    SelectObject.call(hDC, brush)
    Rectangle.call(hDC, x, y, width, height)
  end
end
avatar
Eron
Principiante
Principiante

0/3

Créditos 1995

Gracias : 56

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Wecoc el 2017-02-15, 20:32

¿Puede que lo que estés intentando sea algo parecido al Zeus81 PNG exporter? Ahí si lo tengo bien entendido se convierte la bitmap actual a otro formato en GDI+ para poder exportarla luego, es decir guardarla en un archivo PNG válido. También en los scripts de Screenshot o de FullScreen+ se suele involucrar el uso de GDI y GDI+ de forma más superficial. Y seguro que H-Mode7 y esos sistemas complejos como editores de mapas isométricos/3D y esas locuras que se han logrado con RPG maker también usan muchas cosas así. Antes de liarte a reinventar la rueda te recomiendo investigar todo lo posible sobre el tema.

Mira por ejemplo el uso de GDI+ para simular los Blend Type del maker tal como ForeverZer0 intentó aquí: Sprite Blend Mode

Por cierto sobre lo que dije ayer del EasyRPG y ARGSS encontré un post donde se explican varios puntos: Opiniones sobre RGSS
RPG maker MV usa OpenGL, por cierto.

Enlazo varios posts que he encontrado sobre el tema, sobre muchas cosas que se han hablado aquí. Yo más que con eso no puedo ayudarte.

RMVXA-GL (OpenGL) + post en HBgames
GDI+ and bitmap handles
Map Screenshot (GDI+ interface)
Tsukihime Mapshot (GDI+ interface)
SFRGSS - RGSS3 engine using SMFL (SMFL)
RPG maker Bitmap Functions
SMFL examples (youtube)
avatar
Wecoc
Administrador
Administrador



Créditos 9360

Gracias : 516

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Eron el 2017-02-22, 08:10

Probé de hacer algo con lo que me pasaste. He intentado pasar la imagen de título a GDI+ combinando los "GDI+ interface" que me pasaste.

Código:
module GDI

  GdiplusStartup = Win32API.new('gdiplus.dll', 'GdiplusStartup', 'PPP', 'L')
  GdiplusShutdown = Win32API.new('gdiplus.dll', 'GdiplusShutdown', 'P', 'V')
  GdipDisposeImage = Win32API.new('gdiplus.dll', 'GdipDisposeImage', 'P', 'L')
  GdipSaveImageToFile = Win32API.new('gdiplus.dll', 'GdipSaveImageToFile', 'PPPP', 'L')
  GdipCreateBitmap = Win32API.new('gdiplus.dll', 'GdipCreateBitmapFromScan0', 'LLLLPP', 'L')

  @@token = [0].pack('I')
  def self.token
    @@token
  end
  
  def self.startup
    GdiplusStartup.call(@@token, [1, 0, 0, 0].pack('L4'), 0)
  end
 
  def self.shutdown
    GdiplusShutdown.call(@@token)
  end
  
  class Image
    attr_reader :instance
    def initialize
      @instance = 0
      true
    end
    
    def dispose
      GDI::GdipDisposeImage.call(@instance)
    end
  end
  
  class Bitmap < Image
    def initialize(*args)
      w = args.shift
      h = args.shift
      bitmap_id = args.shift
      argv = [w, h, w * -4, 0x26200a, bitmap_id]
      argv.push([0].pack('I'))
      retval = GDI::GdipCreateBitmap.call(*argv)
      @instance = retval ? argv.last.unpack('I').first : 0
      retval
    end
  end
end

GDI.startup

module Kernel
  alias gdiplus_exit exit unless $@
  def exit(*args)
    GDI.shutdown
    gdiplus_exit(*args)
  end
end

class Bitmap
  def _data_struct(offset = 0)
    # No funciona en RPG maker XP
    @_data_struct ||= (DL::CPtr.new((object_id << 1) + 16).ptr + 8).ptr
    (@_data_struct + offset).ptr.to_i
  end
  def scan0
    # No funciona en RPG maker XP
    _data_struct(12)
  end
end

class Sprite
  # Ésto se carga los sprites en el mapa, pero sin ello no puedo
  # usar GDI::Bitmap como Bitmap
  attr_reader :bitmap
  def bitmap=(bitmap)
    @bitmap = bitmap
  end
end

class Plane
  # Ésto se carga los planes en el mapa, pero sin ello no puedo
  # usar GDI::Bitmap como Bitmap
  attr_reader :bitmap
  def bitmap=(bitmap)
    @bitmap = bitmap
  end
end

class Scene_Title
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  def main
    # If battle test
    if $BTEST
      battle_test
      return
    end
    # Load database
    $data_actors        = load_data("Data/Actors.rxdata")
    $data_classes       = load_data("Data/Classes.rxdata")
    $data_skills        = load_data("Data/Skills.rxdata")
    $data_items         = load_data("Data/Items.rxdata")
    $data_weapons       = load_data("Data/Weapons.rxdata")
    $data_armors        = load_data("Data/Armors.rxdata")
    $data_enemies       = load_data("Data/Enemies.rxdata")
    $data_troops        = load_data("Data/Troops.rxdata")
    $data_states        = load_data("Data/States.rxdata")
    $data_animations    = load_data("Data/Animations.rxdata")
    $data_tilesets      = load_data("Data/Tilesets.rxdata")
    $data_common_events = load_data("Data/CommonEvents.rxdata")
    $data_system        = load_data("Data/System.rxdata")
    # Make system object
    $game_system = Game_System.new
    # Make title graphic
    @sprite = Sprite.new
    bitmap = RPG::Cache.title($data_system.title_name)
    # @sprite.bitmap = GDI::Bitmap.new(bitmap.width, bitmap.height, bitmap.scan0)
    @sprite.bitmap = GDI::Bitmap.new(bitmap.width, bitmap.height, bitmap.__id__)
    # Make command window
    s1 = "Nuevo"
    s2 = "Cargar"
    s3 = "Salir"
    @command_window = Window_Command.new(192, [s1, s2, s3])
    @command_window.back_opacity = 160
    @command_window.x = 320 - @command_window.width / 2
    @command_window.y = 288
    # Continue enabled determinant
    # Check if at least one save file exists
    # If enabled, make @continue_enabled true; if disabled, make it false
    @continue_enabled = false
    for i in 0..3
      if FileTest.exist?("Save#{i+1}.rxdata")
        @continue_enabled = true
      end
    end
    # If continue is enabled, move cursor to "Continue"
    # If disabled, display "Continue" text in gray
    if @continue_enabled
      @command_window.index = 1
    else
      @command_window.disable_item(1)
    end
    # Play title BGM
    $game_system.bgm_play($data_system.title_bgm)
    # Stop playing ME and BGS
    Audio.me_stop
    Audio.bgs_stop
    # Execute transition
    Graphics.transition
    # Main loop
    loop do
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Frame update
      update
      # Abort loop if screen is changed
      if $scene != self
        break
      end
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of command window
    @command_window.dispose
    # Dispose of title graphic
    @sprite.bitmap.dispose
    @sprite.dispose
  end
end

Sí, la instancia de la bitmap resultante no vale 0, y no sale error ni nada, eso es buena señal...
El problemilla es que ahora el título sale todo negro puesto que la imagen está vacía y no se cargan las bitmap de Sprite y Plane.


Me rindo =((
avatar
Eron
Principiante
Principiante

0/3

Créditos 1995

Gracias : 56

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por orochii el 2017-02-22, 16:41

EasyRPG usa SDL, particularmente me parece recordar que lo habían portado hace unos años al SDL2.
==
Yo diría que usar GDI, SFML, SDL, o lo que sea en sí no es una idea buena xD. Lo mejor es hacerlo tal como se hace con Mode7 y tal. Que es simplemente encontrar la dirección en memoria de los datos del bitmap a modificar, y modificarlo desde una DLL. Total luego el maker va a tener que dibujarlo a su forma habitual a menos que se reescriba el intérprete y la biblioteca gráfica entera, creo.

Pero claro, es lo que creo, no he visto los links que puso Wec. Quiza los jóvenes de hoy hacen magias raras. :'D
avatar
orochii
Reportero

0/3

Créditos 6796

Gracias : 356

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Wecoc el 2017-02-22, 18:50

Lo mejor es hacerlo tal como se hace con Mode7 y tal. Que es simplemente encontrar la dirección en memoria de los datos del bitmap a modificar, y modificarlo desde una DLL.

Opino lo mismo, además es más fácil porque no hay que cambiar la estructura de la bitmap ni nada.

Intentar aplicar incluso las funciones más básicas de GDI como BitBlt mediante Win32API desde el maker directamente es muy complicado, de hecho no sé ni si es posible. Al fin y al cabo para aplicar esa función hay que crear una HDC compatible a la de la ventana con CreateCompatibleDC, crear una HBITMAP con CreateBitmap, copiarle los datos de la bitmap (creo que ésta es la parte que más flojea intentándolo desde el propio RGSS), asignar la HBITMAP como objeto al HDC con SelectObject, hacer todo el mismo proceso también para la source bitmap, aplicar ahora sí la función GDI en éste caso BitBlt con los dos HDC resultantes y los demás parámetros, y finalmente borrar los HDC con DeleteDC. Hacer todo ese proceso con C++ es... menos doloroso xD
avatar
Wecoc
Administrador
Administrador



Créditos 9360

Gracias : 516

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por newold el 2017-02-22, 21:17

Te paso un código hecho en c para manejar las bitmaps de RPG maker, tiene un montón de funciones, algunas propias para hacer cosas interesantes, y puedes añadir las que quieras, solo tienes que compilar la dll, por si te sirve de algo,

pongo el link al code k es muy largo para ponerlo en un post

RGSS BITMAp CODE C

yo uso el dev c++ 5.7.1 para compilar eso
avatar
newold
Principiante
Principiante

0/3

Créditos 1096

Gracias : 71

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Wecoc el 2017-02-22, 23:22

No he entendido a quien hay que dar créditos por usar ésto, ¿podrías especificarlo?
Me suena haber visto algunas de esas funciones en un topic de Chaos Project pero no sé si es exactamente la misma dll o no.

¿Y hay algún script o demo de uso? He hecho un scriptillo para probarlo pero algunos no supe hacerlos funcionar demasiado bien xD

Pongo aquí mi script de prueba:

Spoiler:
Código:
class Bitmap
  
  # DrawMap ??
  
  # DrawLight = Win32API.new('BitmapRGSS.dll', 'draw_light', 'LLLII', '')
  # def draw_light(src_bitmap, src_rect, color, back_color)
  #   DrawLight.call(self.__id__, src_bitmap.__id__, src_rect.__id__,
  #   color.__id__, back_color.__id__)
  #   return self
  # end
  
  # DrawLight2 ??
  
  BlendBlt = Win32API.new('BitmapRGSS.dll', 'blend_blt', 'LLIIIIIIII', '')
  def blend_blt(x, y, src_bitmap, src_rect, blend_type=0, opacity=255)
    src_x = src_rect.x
    src_y = src_rect.y
    w = src_rect.width
    h = src_rect.height
    BlendBlt.call(self.__id__, src_bitmap.__id__, x, y, src_x, src_y, w, h,
    blend_type, opacity)
    return self
  end
  
  TransferBlt = Win32API.new('BitmapRGSS.dll', 'transfer_blt', 'LLIIIIIIII', '')
  def transfer_blt(x, y, src_bitmap, src_rect, mode=0, opacity=255)
    src_x = src_rect.x
    src_y = src_rect.y
    w = src_rect.width
    h = src_rect.height
    TransferBlt.call(self.__id__, src_bitmap.__id__, x, y, src_x, src_y, w, h,
    mode, opacity)
    return self
  end
  
  Split = Win32API.new('BitmapRGSS.dll', 'split_bitmap', 'LLII', '')
  def self.split_bitmap(bmp_a, bmp_b, dx, dy)
    Split.call(bmp_a.__id__, bmp_b.__id__, dy, dx)
  end
  
  Tint = Win32API.new('BitmapRGSS.dll', 'tint', 'LIIII', '')
  def tint(color)
    result = self.clone
    result.tint!(color)
    return result
  end
  
  def tint!(color)
    r, g, b = color.red, color.green, color.blue
    amount = (color.alpha * 100 / 255.0).floor
    Tint.call(self.__id__, amount, r, g, b)
  end
  
  Colorize = Win32API.new('BitmapRGSS.dll', 'colorize', 'LIIII', '')
  def colorize(color)
    result = self.clone
    result.colorize!(color)
    return result
  end
  
  def colorize!(color)
    r, g, b = color.red, color.green, color.blue
    amount = (color.alpha * 100 / 255.0).floor
    Colorize.call(self.__id__, amount, r, g, b)
  end
  
  GrayScale = Win32API.new('BitmapRGSS.dll', 'grayscale', 'LI', '')
  def grayscale(amount)
    result = self.clone
    result.grayscale!(amount)
    return result
  end
  
  def grayscale!(amount)
    GrayScale.call(self.__id__, amount)
  end
  
  Ripple = Win32API.new('BitmapRGSS.dll', 'ripple', 'LLIII', '')
  RippleCirc = Win32API.new('BitmapRGSS.dll', 'ripple_circ', 'LIIIIII', '')
  
  def ripple(amp, wavelength, dir)
    source = self.clone
    Ripple.call(self.__id__, source.__id__, amp, wavelength, dir)
  end
  
  def ripple_circ(cx, cy, o, w, change, amount)
    RippleCirc.call(self.__id__, cx, cy, o, w, change, amount)
  end
  
  Negative = Win32API.new('BitmapRGSS.dll', 'negative', 'L', '')
  def negative
    result = self.clone
    result.negative!
    return result
  end
  
  def negative!
    Negative.call(self.__id__)
    return nil
  end
  
  DrawCircle = Win32API.new('BitmapRGSS.dll', 'draw_circle', 'LIIIIIIIIII', '')
  def draw_circle(x, y, rad, thick, color, start_angle=0, end_angle=360)
    r, g, b, a = color.red, color.green, color.blue, color.alpha
    DrawCircle.call(self.__id__, x, y, rad, thick, start_angle, end_angle,
    r, g, b, a)
  end
  
  def fill_circle(x, y, rad, color, start_angle=0, end_angle=360)
    draw_circle(x, y, rad, rad, color, start_angle, end_angle)
  end
  
  # DrawEllipse = Win32API.new('BitmapRGSS.dll', 'draw_ellipse', 'LIIIIIIIIIII', '')
  # def draw_ellipse(x, y, rx, ry, thick, color, start_angle=0, end_angle=360)
  #   r, g, b, a = color.red, color.green, color.blue, color.alpha
  #   DrawEllipse.call(self.__id__, x, y, rx, ry, thick, start_angle, end_angle,
  #   r, g, b, a)
  # end
  
  RadialBlur = Win32API.new('BitmapRGSS.dll', 'radial_blur', 'LLIII', '')
  def radial_blur(scale, amount, wc)
    source = self.clone
    RadialBlur.call(self.__id__, source.__id__, scale, amount, wc)
  end
  
  TableLookUp = Win32API.new('BitmapRGSS.dll', 'table_lookup', 'LLL', '')
  def table_lookup(table, ua)
    TableLockUp.call(self.__id__, table.__id__, ua)
  end
  
  Pixelize = Win32API.new('BitmapRGSS.dll', 'pixelize', 'LII', '')
  def pixelize(*args)
    case args.size
    when 1 then x = y = args[0]
    when 2 then x, y, = args[0], args[1]
    end
    Pixelize.call(self.__id__, x, y)
  end
  
  # Transform ??
  
  # RotateX = Win32API.new('BitmapRGSS.dll', 'table_lookup', 'LLLLLLLLL', '')
  # def rotate_x(angle)
  #   result = Bitmap.new(self.width, self.height)
  #   invert_x = 0
  #   invert_y = 0
  #   invert_animation = 0
  #   z = 0
  #   div_z = 0
  #   rect = Rect.new(0, 0, self.width, self.height)
  #   RotateX.call(self.__id__, result.__id__, angle, invert_x, invert_y,
  #   invert_animation, z, div_z, rect.__id__)
  #   return result
  # end
  
  # RotateY ??
  # RotateZ ??
  
  Filter33 = Win32API.new('BitmapRGSS.dll', 'Filter33', 'LIIPIL', '')
  
  def blur
    Filter33.call(self.__id__, 3, 3, [0,1,0,1,1,1,0,1,0,5].pack("i*"), 1, 0)
  end
  
  def blur_more
    Filter33.call(self.__id__, 3, 3, [1,1,1,1,1,1,1,1,1,9].pack("i*"), 1, 0)
  end
  
  def sharpen
    Filter33.call(self.__id__, 3, 3, [0,-1,0,-1,5,-1,0,-1,0,1].pack("i*"), 1, 0)
  end
  
  def sharpen_more
    Filter33.call(self.__id__, 3, 3, [-1,-1,-1,-1,9,-1,-1,-1,-1,1].pack("i*"), 1, 0)
  end
  
  def detect_edges
    Filter33.call(self.__id__, 3, 3, [0,-1,0,-1,4,-1,0,-1,0,1].pack("i*"), 1, 0)
  end
  
  def emboss
    Filter33.call(self.__id__, 3, 3, [-2,-1,0,-1,1,1,0,1,2,1].pack("i*"), 1, 0)
  end
  
  def glow
    Filter33.call(self.__id__, 5, 4, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0].pack("i*"),1,1)
  end
  
  Multiply = Win32API.new('BitmapRGSS.dll', 'multiply', 'LIII', '')
  def multiply(color)
    r, g, b = color.red, color.green, color.blue
    Multiply.call(self.__id__, r, g, b)
  end
end

Lo que más me gustó fueron los nuevos blend type para blend_blt y los cálculos con colores tipo el tint, el colorize o el multiply.
avatar
Wecoc
Administrador
Administrador



Créditos 9360

Gracias : 516

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por newold el 2017-02-23, 10:54

las funciones que tienen comentarios en español son mías aunque hay alguna más que no tiene ningún comentario, otras funciones si son de chaos project, y hay alguna más k no se donde saqué :D. Con las de rotate_x, y y z se puede hacer rotar imágenes como esto:

https://www.youtube.com/watch?v=vfT3IXmJuxo


eso usa un código como esto para funcionar:

Código:
#===============================================================================
module Newold_Scripts
end
#===============================================================================


#===============================================================================
module Newold_Scripts
    
  # ================================ CREDITS ===================================
  # - Newold (Script below)
  # ============================================================================
  
  # ================================ LICENSE ===================================
  # Free for non-commercial use
  # ============================================================================
  
  #-----------------------------------------------------------------------------
  #                               Class Flip_Card
  #-----------------------------------------------------------------------------
  
  #=============================================================================
  class Flip_Card
    #--------------------------------------------------------------------------
    # sprite: Destination Sprite
    # new_image: New image to show when card turn around 270º
    # back_image: Back image to show when card turn around 90º
    # rotate_time: Time for turn in seconds
    # rotate_mode: Type of rotation (0 = rotate_x, 1 = rotate_y, 2 = rotate_z)
    # dx = Displacement of image in X axis
    # dy = Displacement of image in Y axis
    # z = Number for improve result
    # div_z = Divide z calculated beetween div_z
    # turnabout: Flip card fully (true) or to the back (false)
    # inverse_angle: Invert animation of flip card
    #--------------------------------------------------------------------------
    def initialize(sprite, new_image, back_image, rotate_time=0.8,
                   rotate_mode=0, dx=0, dy=0, z=0, div_z=2,
                   inverse_animation=false, turnabout=true)
      

      @inverse_animation = inverse_animation
      @rotate_mode = rotate_mode
      case @rotate_mode
      when 0
        @rotate_x = Win32API.new("Bitmap.dll","rotate_x",("llplllppp"),"l")
      when 1
        @rotate_y = Win32API.new("Bitmap.dll","rotate_y",("llplllppp"),"l")
      when 2
        @rotate_z = Win32API.new("Bitmap.dll","rotate_z",("llplllppp"),"l")
      else
        p "Error: Wrong rotate_mode (#{rotate_mode}). Only valid 0,1,2"
        exit
      end
      @turnabout = turnabout
      @mod_angle = 360.0 / (Graphics.frame_rate * rotate_time / 2)
      @max_shadow_card = 200.0
      @mod_color = @max_shadow_card / (90 / @mod_angle)
      @color = Color.new(0,0,0,0)
      @angle = @inverse_animation ? 360 : 0
      @sprite = sprite
      @z = z.to_f
      @div_z = div_z
      @div_z = 1 if @div_z == 0
      @dx = dx
      @dy = dy
      set_movement
      if false # (erased in this version)
      else
        image = Bitmap.new(@sprite.src_rect.width, @sprite.src_rect.height)
        @front_image = image.dup
 if false # (erased in this version)
 end
        @front_image.stretch_blt(@front_image.rect,@sprite.bitmap,@sprite.bitmap.rect)
        @back_image = image.dup
 if false # (erased in this version)
 else
 b = back_image
 end
        @back_image.stretch_blt(@back_image.rect,b,b.rect)
        @new_image = image
 if false # (erased in this version)
 else
 b = new_image
 end
        @new_image.stretch_blt(@new_image.rect,b,b.rect)
      end
      @current_image = @front_image
      create_bitmap
      @running = true
    end
    #--------------------------------------------------------------------------
    def set_movement
      # (erased in this version)
      @index_movement = 0
      @movement_array = []
    end
    #--------------------------------------------------------------------------
    def update
      if @running
 # set current image
        unless @inverse_animation
          @angle += @mod_angle
          if @angle >= 90 and @current_image == @front_image
            @current_image = @back_image
            
          elsif @angle >= 270 and @current_image == @back_image
            @current_image = @new_image
          end
        else
          @angle -= @mod_angle
          if @angle < 270 and @current_image == @front_image
            @current_image = @back_image
          elsif @angle < 90 and @current_image == @back_image
            @current_image = @new_image
          end
        end
        if false # (erased in this version)
        end
        # update animations (only if current image is an Animated Sprite)
 update_animation_sprites
 # clear global bitmap
        @bitmap.clear
 # set draknen for the image
        unless @inverse_animation
          if (@angle <= 90) or
             (@angle >= 180 and @angle <= 270)
            @color.alpha += @mod_color
          else
            @color.alpha -= @mod_color
          end
        else
          if (@angle > 270) or
             (@angle >= 90 and @angle <= 180)
            @color.alpha += @mod_color
          else
            @color.alpha -= @mod_color
          end
        end
        @s.color = @color
        # set angle
        angle = @angle * Math::PI / 180.0
        # rotate image
        case @rotate_mode
        when 0; rotate_x(angle)
        when 1; rotate_y(angle)
        when 2; rotate_z(angle)
        end
 # set flaq running
        unless @inverse_animation
          if (@angle >= 180 and not @turnabout) or @angle >= 360
            @running = false
            @color.alpha = 0
          end
        else
          if (@angle <= 180 and not @turnabout) or @angle <= 0
            @running = false
            @color.alpha = 0
          end
        end
      end
    end
    #--------------------------------------------------------------------------
 def update_animation_sprites
 # erased in this version      
 end
 #--------------------------------------------------------------------------
    def rotate_x(angle)
 # Fast method with DLL
 begin
 invert_x, invert_y = get_real_x_y_2
 invert_animation = @inverse_animation ? 1 : 0
 xi = yi = 100000
 xf = yf = -100000
 rect = [xi,xf,yi,yf].pack("I*")
 @rotate_x.call(@current_image.__id__, @bitmap.__id__, [angle].pack("D"),
 invert_x, invert_y, invert_animation, [@z].pack("D"),
 [@div_z].pack("D"), rect)
 rect = rect.unpack("i*")
 xi = rect[0]
 xf = rect[1]
 yi = rect[2]
 yf = rect[3]
 draw_sprite(xi,yi,xf,yf)
 rescue
 rotate_x_without_dll(angle)
 end
    end
 #--------------------------------------------------------------------------
    def rotate_x_without_dll(angle)
 # Slow method without DLL
      z = @z
      m = (@inverse_animation ? -1 : 1)
      xi = yi = 1000000000000
      xf = yf = -1000000000000
      if defined?(Graphics.width)
        x0, y0 = Graphics.width / 2, Graphics.height / 2
      else
        x0, y0 = 320, 240
      end
      sin = Math.sin(angle)
      cos = Math.cos(angle)
      if not @inverse_animation
        sin *= -1; cos *= -1
      end
      for y in 0...@current_image.height
        for x in 0...@current_image.width
          real_x, real_y = get_real_x_y(x,y)
          color = @current_image.get_pixel(real_x,real_y)
          z2 = y * sin - z * cos
          y2 = y0 + y * cos - z * sin
          x2 = x0 + x + z2 / @div_z
          @bitmap.fill_rect(x2,y2,2,2,color)
          xi = x2 if x2 < xi
          yi = y2 if y2 < yi
          xf = x2 if x2 > xf
          yf = y2 if y2 > yf
        end
      end
      draw_sprite(xi,yi,xf,yf)
 end
    #--------------------------------------------------------------------------
    def rotate_y(angle)
 # Fast method with DLL
 begin
 invert_x, invert_y = get_real_x_y_2
 invert_animation = @inverse_animation ? 1 : 0
 xi = yi = 100000
 xf = yf = -100000
 rect = [xi,xf,yi,yf].pack("I*")
 @rotate_y.call(@current_image.__id__, @bitmap.__id__, [angle].pack("D"),
 invert_x, invert_y, invert_animation, [@z].pack("D"),
 [@div_z].pack("D"), rect)
 rect = rect.unpack("i*")
 xi = rect[0]
 xf = rect[1]
 yi = rect[2]
 yf = rect[3]
 draw_sprite(xi,yi,xf,yf)
 rescue
 rotate_y_without_dll(angle)
 end
    end
 #--------------------------------------------------------------------------
 def rotate_y_without_dll(angle)
 # Slow method without DLL
      z = @z
      xi = yi = 1000000000000
      xf = yf = -1000000000000
      if defined?(Graphics.width)
        x0, y0 = Graphics.width / 2, Graphics.height / 2
      else
        x0, y0 = 320, 240
      end
      sin = Math.sin(angle)
      cos = Math.cos(angle)
      if not @inverse_animation
        sin *= -1; cos *= -1
      end
      for y in 0...@current_image.height
        for x in 0...@current_image.width
          real_x, real_y = get_real_x_y(x,y)
          color = @current_image.get_pixel(real_x,real_y)
          z2 = x * sin - z * cos
          x2 = x0 + x * cos + z * sin
          y2 = y0 + y + z2 / @div_z
          @bitmap.fill_rect(x2,y2,2,2,color)
          xi = x2 if x2 < xi
          yi = y2 if y2 < yi
          xf = x2 if x2 > xf
          yf = y2 if y2 > yf
        end
      end
      draw_sprite(xi,yi,xf,yf)
 end
    #--------------------------------------------------------------------------
    def rotate_z(angle)
 begin
 # Fast method with DLL
 invert_x, invert_y = get_real_x_y_2
 invert_animation = @inverse_animation ? 1 : 0
 xi = yi = 100000
 xf = yf = -100000
 rect = [xi,xf,yi,yf].pack("I*")
 @rotate_z.call(@current_image.__id__, @bitmap.__id__, [angle].pack("D"),
 invert_x, invert_y, invert_animation, [@z].pack("D"),
 [@div_z].pack("D"), rect)
 rect = rect.unpack("i*")
 xi = rect[0]
 xf = rect[1]
 yi = rect[2]
 yf = rect[3]
 draw_sprite(xi,yi,xf,yf)
 rescue
 rotate_z_without_dll(angle)
 end
    end
 #--------------------------------------------------------------------------
 def rotate_z_without_dll(angle)
 # Slow method without DLL
      z = @z
      xi = yi = 1000000000000
      xf = yf = -1000000000000
      if defined?(Graphics.width)
        x0, y0 = Graphics.width / 2, Graphics.height / 2
      else
        x0, y0 = 320, 240
      end
      sin = Math.sin(angle)
      cos = Math.cos(angle)
      if not @inverse_animation
        sin *= -1; cos *= -1
      end
      for y in 0...@current_image.height
        for x in 0...@current_image.width
          real_x, real_y = get_real_x_y(x,y)
          color = @current_image.get_pixel(real_x,real_y)
          z2 = z * cos - x * sin
          x2 = x0 + x * cos - y * sin + z2 / @div_z
          y2 = y0 + x * sin + y * cos - z2 / @div_z
          @bitmap.fill_rect(x2,y2,2,2,color)
          xi = x2 if x2 < xi
          yi = y2 if y2 < yi
          xf = x2 if x2 > xf
          yf = y2 if y2 > yf
        end
      end
      draw_sprite(xi,yi,xf,yf)
 end
    #--------------------------------------------------------------------------
    def get_real_x_y(x,y)
      if @rotate_mode == 1 and not @inverse_animation and
        (@current_image == @front_image or @current_image == @new_image)
        x = @current_image.width - x
      elsif @rotate_mode == 1 and @current_image == @back_image and
        @inverse_animation
        x = @current_image.width - x
      elsif @rotate_mode == 0 and not @inverse_animation and
        @current_image != @back_image
        y = @current_image.height - y
      elsif @rotate_mode == 0 and @inverse_animation and
        @current_image == @back_image
        y = @current_image.height - y
      elsif @rotate_mode == 2 and not @inverse_animation and
        (@current_image == @front_image or @current_image == @new_image)
        x = @current_image.width - x
        y = @current_image.height - y
      elsif @rotate_mode == 2
        x = @current_image.width - x
        y = @current_image.height - y
      end
      return x, y
    end
    #--------------------------------------------------------------------------
    def get_real_x_y_2
      invert_x = invert_y = 0
      if @rotate_mode == 1 and not @inverse_animation and
        (@current_image == @front_image or @current_image == @new_image)
        invert_x = 1
      elsif @rotate_mode == 1 and @current_image == @back_image and
        @inverse_animation
        invert_x = 1
      elsif @rotate_mode == 0 and not @inverse_animation and
        @current_image != @back_image
        invert_y = 1
      elsif @rotate_mode == 0 and @inverse_animation and
        @current_image == @back_image
        invert_y = 1
      elsif @rotate_mode == 2 and not @inverse_animation and
        (@current_image == @front_image or @current_image == @new_image)
        invert_x = 1
        invert_y = 1
      elsif @rotate_mode == 2 and not @inverse_animation and
        @current_image == @back_image
        invert_y = 1
      end
      return invert_x, invert_y
    end
    #--------------------------------------------------------------------------
    def draw_sprite(xi,yi,xf,yf)
      # --- Set bitmap for the card
      w = [1,(xf-xi)].max
      h = [1,(yf-yi)].max
      b = Bitmap.new(w,h)
      b.blt(0,0,@bitmap,Rect.new(xi,yi,w,h))
      @s.bitmap.dispose
      @s.bitmap = b
      # --- Set x and y for the card
      unless @movement_array[@index_movement].nil?
        @s.x = @movement_array[@index_movement][0]
        @s.y = @movement_array[@index_movement][1]
        @index_movement += 1
      end
      # --- Set visibility for the card
      #@s.visible = (b.width >= 1 and b.height >= 1)
      # --- Set bitmap for the shadow
      @s2.bitmap = b
      # --- Set zoom for the shadow
      set_zoom
      # --- Set x and y for the shadow
      @s2.x = (@sprite.x - @sprite.ox) +
        (@sprite.bitmap.width/2*@sprite.zoom_x) - b.width/2*@s2.zoom_x
      @s2.y = (@sprite.y - @sprite.oy) +
        (@sprite.bitmap.height/2*@sprite.zoom_y) - b.height/2*@s2.zoom_y
    end
    #--------------------------------------------------------------------------
    def set_zoom
      p1 = [@s.x,@s.y]
      p2 = [@s2.x,@s2.y]
      dx = (p2[0] - p1[0])
      dy = (p2[1] - p1[1])
      dist = Math.sqrt((dx**2) + (dy**2));
      zoom = 1 - [0.005,1 - 0.006 * (dist / 2)].max
      zoom2 = 1 - [3,1 + 0.004 * (dist / 2)].min
      @s2.zoom_x = @sprite.zoom_x - zoom
      @s2.zoom_y = @sprite.zoom_y - zoom
      @s.zoom_x = @sprite.zoom_x - zoom2
      @s.zoom_y = @sprite.zoom_y - zoom2
    end
    #--------------------------------------------------------------------------
    def create_bitmap
      #if defined?(Graphics.width)
        #w, h = Graphics.width, Graphics.height
      #else
        #w, h = 640, 480
      #end
      w, h = 750, 750
      @bitmap = Bitmap.new(w,h)
      # --- Card image
      @s = Sprite.new
      @s.bitmap = @sprite.bitmap.dup
      @s.x = @sprite.x - @sprite.ox
      @s.y = @sprite.y - @sprite.oy
      @s.z = 1000000000
      @s.zoom_x = @sprite.zoom_x
      @s.zoom_y = @sprite.zoom_y
      # --- Shadow
      @s2 = Sprite.new
      @s2.bitmap = @s.bitmap
      @s2.x = @s.x
      @s2.y = @s.y
      @s2.color = Color.new(255,255,255,255)
      @s2.z = @s.z - 1
      @s2.opacity = 120
      @s2.zoom_x = @sprite.zoom_x
      @s2.zoom_y = @sprite.zoom_y
      @s2.blend_type = 2
      # --- Hide original bitmap
      @sprite.visible = false
    end
    #--------------------------------------------------------------------------
    def set_shadow(value)
      @s2.visible = (value == true)
    end
    #--------------------------------------------------------------------------
    def running?
      return @running
    end
    #--------------------------------------------------------------------------
    def dispose
      # change sprite bitmap
      unless false
        if false # erased in this version
        else
          @sprite.bitmap = @current_image.dup
        end
        @front_image.dispose
        @back_image.dispose
        @new_image.dispose
        @current_image.dispose
      end
      @sprite.visible = true
      @s.bitmap.dispose
      @s.dispose
      @s2.bitmap.dispose
      @s2.dispose
    end
    #--------------------------------------------------------------------------
  end
  #=============================================================================
end
#===============================================================================




# EJEMPLO

s = Sprite.new
s.bitmap = Bitmap.new(640,480)
s.bitmap.fill_rect(0,0,640,480,Color.new(210,210,210))


b1 = bitmap = Bitmap.new(100,100)
b1.fill_rect(0,0,100,100,Color.new(255,0,0))

sprite = Sprite.new
sprite.bitmap = b1.dup
sprite.x = 100
sprite.y = 100

new_image = Bitmap.new(100,100)
new_image.fill_rect(0,0,100,100,Color.new(0,255,0))

back_image = Bitmap.new(100,100)
back_image.fill_rect(0,0,100,100,Color.new(40,0,0))



while true
  rotate_mode = rand(3)
  invert_animation = rand(2) == 0
  flip = Newold_Scripts::Flip_Card.new(sprite, new_image, back_image, 3,
    rotate_mode, 0, 0, 0, 1.7, invert_animation, true)
  while flip.running?
    Graphics.update
    flip.update
  end
  flip.dispose
  20.times {Graphics.update}
  new_image, b1 = b1, new_image
  sprite.bitmap = b1.dup
end

por cierto estoy pensando que con mi método flip_card se puede adaptar un poco para crear un libro que pase páginas, tal vez un día lo haga pero ahí lo dejo por si alguien quiere intentarlo :D
avatar
newold
Principiante
Principiante

0/3

Créditos 1096

Gracias : 71

Volver arriba Ir abajo

RPG Maker XP Re: Duda sobre clases internas, GDIplus o SFML

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.