🤔 Para Refletir :
"Publique seu jogo. Dê a cara a tapa. Vai ter hater? Sim, porque você foi lá e fez, tem gente que nem faz!"
- HenriqueGibi

Dúvida sobre Bitmap e Sprites do RGSS3

Estado
Tópico fechado. Não é possível fazer postagens nela.

Pretty-Belle

Cidadão
Membro
Membro
Juntou-se
18 de Junho de 2015
Postagens
155
Bravecoins
112
Rally-ho. Sim, resolvi voltar a programar com RGSS3. Como eu nunca aprendi a usar esse negócio direito, vou vir aqui pedir uma ajuda básica com um pequeno script que eu tava fazendo. Tava vasculhando classes que têm a ver com imagens e achei a Sprite e a Bitmap, mas não entendi exatamente como funcionam.

- Assim que eu crio um novo Sprite ele automaticamente aparece no jogo? Ou tem que, sei la, estar associado a algum evento?
- Digamos que eu tenha todo um iconset, mas eu quero pegar só um certo ícone para estar no sprite, que tem tamanho (w, h) e está nas coordenadas (x, y) da imagem. Como faço isso?
- Sobre bitmaps. Eu queria tirar uma screen do jogo com o Graphics.snap_to_bitmap e depois salvar num arquivo. Mas não quero salvar uma screen toda, só uma parte dela, um retângulo (x, y, w, h). Como faz?

Por enquanto é só isso, thanks :3
 
Bitmap é simplesmente a classe com os dados da imagem (largura, altura, pixels...), mas sem ter a ver com qualquer coisa do jogo/tela de exibição (coordenadas, ângulo de rotação, por aí), considere como "a imagem bruta".

Sprite é uma classe que possui um Bitmap (ou seja, um de seus atributos é um bitmap, ver code abaixo), e trata de ter métodos e atributos que operam com o jogo/tela (coordenadas, rotação, zoom x/y, src_rect, etc... como atributos, e update, flash, etc... como métodos).

No caso, sobre uma Sprite possuir um bitmap, isso significa poder fazer:
Código:
my_sprite = Sprite.new
my_sprite.bitmap = Bitmap.new(20, 20) # Isso cria um bitmap com tamanho 20x20
my_sprite.bitmap.fill_rect(Rect.new(0, 0, 20, 20), Color.new(255, 0, 0)) # Preenche o bitmap com vermelho

Para entender um pouco mais como essas duas classes interoperam, um exemplinho:
Código:
bmp = Bitmap.new(100, 50) # Cria Bitmap 100x50
bmp.fill_rect(Rect.new(0, 0, 50, 50), Color.new(255, 0, 0)) # Preenche o lado esquerdo com vermelho
bmp.fill_rect(Rect.new(50, 0, 50, 50), Color.new(0, 0, 255)) # Preenche o lado direito com azul

# Cria 2 sprites
sprite1 = Sprite.new
sprite1.x = 0
sprite1.y = 0

sprite2 = Sprite.new
sprite2.x = 200
sprite2.y = 200

# Associa o mesmo Bitmap às duas Sprites
sprite1.bitmap = bmp
sprite2.bitmap = bmp

# Troca a região do Bitmap que as sprites irão exibir
sprite1.src_rect = Rect.new(0, 0, 50, 50) # Exibe apenas o lado esquerdo do bitmap
sprite2.src_rect = Rect.new(50, 0, 50, 50) # Exibe apenas o lado direito do bitmap

Basicamente, se você pudesse ver a memória do jogo e ver o Bitmap da variável bmp, ele seria algo como isso (no momento):

gCZUqQz.png


Se você rodar o código acima, vai ter como resultado algo aproximado do seguinte:

kopUKQ9.png


Agora veja o seguinte: lembra que as duas sprites estão com o mesmo Bitmap, certo?

Isso significa que se você fizer...:

Código:
bmp.fill_rect(Rect.new(15, 15, 70, 20), Color.new(0, 255, 0)) # Preenche uma faixa verde no meio da imagem

O Bitmap ficará da seguinte forma:

JdsScQf.png


E por resultado:

ZNB45DD.png


Perceba que nada foi alterado (diretamente, via código) nas sprites, mas sim no bitmap, e isso alterou a mesma coisa para as duas. RPG Maker usa algo parecido com ícones e algumas outras coisas, a fim de que você não fique com bitmaps repetidos na memória. Inclusive, se em vez de usar bmp.fill_rect você usar sprite1.bitmap.fill_rect, obterá os mesmos resultados, porque a referência do bitmap é a mesma (se não quiser guardar a mesma referência na sprite2, e sim uma cópia, só usar sprite2.bitmap = bmp.clone, que o .clone vai tratar de fazer uma cópia).

Agora respondendo tópico a tópico:

Assim que eu crio um novo Sprite ele automaticamente aparece no jogo? Ou tem que, sei la, estar associado a algum evento?
Sim, só por dar um Sprite.new a sprite já vai aparecer automaticamente. Se não quiser que isso acontece, simplesmente use sprite.visible = false. Lembre-se de que isso não é o caso de Bitmaps.

Digamos que eu tenha todo um iconset, mas eu quero pegar só um certo ícone para estar no sprite, que tem tamanho (w, h) e está nas coordenadas (x, y) da imagem. Como faço isso?
Como falei, as sprites possuem um atributo "src_rect", que é da classe Rect e que diz qual parte do Bitmap da sprite que vai ser exibida por aquela sprite. Se você quiser que a sprite seja o ícone, faça algo como:

Código:
sprite = Sprite.new
sprite.bitmap = Cache.system("iconset.png")
sprite.src_rect = Rect.new(x, y, w, h) # o (x, y) e (w, h) que você se referia

Se você tem um bitmap e quer "pintar" o ícone em um canto dela, use o método blt(x, y, bitmap, src_rect) (ou stretch_blt(dest_rect, bitmap, src_rect), caso queira esticar/encolher o ícone por um determinado retângulo), que copia um bitmap para parte de outro nas coordenadas especificadas:

Código:
sprite.bitmap.blt(4, 4, Cache.system("iconset.png"), Rect.new(x, y, w, h)) # o (x, y) e (w, h) que você se referia

Isso irá copiar o retângulo (x, y, w, h) do iconset para o bitmap já existente da sprite ;) Se quiser dar uma checada nos métodos do bitmap: http://www.rpg-maker.fr/dl/monos/aide/vx/source/rgss/gc_bitmap.html

Sobre bitmaps. Eu queria tirar uma screen do jogo com o Graphics.snap_to_bitmap e depois salvar num arquivo. Mas não quero salvar uma screen toda, só uma parte dela, um retângulo (x, y, w, h). Como faz?
Quanto a isso não tem muita saída, não há um método padrão. O que você pode fazer é usar este script: http://forums.rpgmakerweb.com/index.php?/topic/21633-bitmap-export/

E no caso fazer:

Código:
bitmap = Bitmap.new(w, h)
bitmap.blt(0, 0, Graphics.snap_to_bitmap, Rect.new(x, y, w, h))
bitmap.export("meu_print.png")

Por enquanto é isso, espero ter sanado suas dúvidas.
Minha sugestão quanto a coisas da 1ª dúvida é fazer scripts curtos como o que fiz para testar e respondê-la:

Código:
class Scene_SpriteTest < Scene_Base
  def start
    super
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(50, 50)
    @sprite.bitmap.fill_rect(Rect.new(0, 0, 50, 50), Color.new(255, 0, 0))
  end
end

Aí só criei um evento no mapa que chamasse o script:

Código:
SceneManager.call(Scene_SpriteTest)

"Falei" com o evento e minha scene apareceu com a sprite ali, mesmo sem dar @sprite.update nem nada ;)
 
Ajudou muito *u* eu queria evitar usar scripts de terceiros, não só porque quero aprender a fazer sozinha, mas também por questões de licenças/direitos autorais que os autores às vezes não especificam direito.
Acho que a partir disso eu consigo deduzir o resto. Thanks <3
 
Estado
Tópico fechado. Não é possível fazer postagens nela.
Voltar
Topo Inferior