发布于 

Aardio 乙女-修复贴图

今天在开发足疗馆乙女游戏的时候,意外发现GM8的一点Bug:
当图像背景大部分纯白或纯黑时, sprite_add函数的removeback参数设置为true时, 这个sprite纯白或纯黑并不会被正常的显示出来.

挣扎了一会,发现并不能在GM8层面解决这个问题,而画师又不能做到100%的准确不画纯白或纯黑,
再加上玩家可能会改贴图做mod,所以我想了一个法子:
使用Aardio软件快速开发工具 制作一个贴图修复的工具,将所有的纯白或纯黑更改为#010101#FEFEFE.
思路是: 遍历游戏目录下所有的贴图文件,然后遍历贴图文件里的每个像素点并更改.

import fsys		// import like java
import console	// console like js
console.log("足疗馆乙女游戏 - 修复贴图错误工具 v1.0.0.0")
console.log("开始处理...")
var dir = "~\Players"
fsys.enum(dir, {"*.png","*.jpg"}, function(dirname, filename, fullpath, findData) {
	// 遍历exe文件夹下的所有后缀为png和jpg的图片
})

Aardio兼容多种写法,数组的语法通常是{123,"str",true}也可以是{123;"str";true}
Hash的写法是{a=123;b="str";c=true},甚至可以和Json混用:{"a":123,"str-2":"str","flag":true}
Aardio中,if内如果不是bool类型,则判断其是否为空来执行.
你可以把他理解为:

// JavaScript
var flag = true
if (flag typeof boolean) {
	if (flag) {
		// do something!
	}
} else {
	if (flag != null) {
		// do something!
	}
}

所以我们可以这样:

import fsys
import console
import preg
console.log("足疗馆乙女游戏 - 修复贴图错误工具 v1.0.0.0")
console.log("开始处理...")
var dir = "~\Players"
fsys.enum(dir, {"*.png", "*.jpg"},
	function(dirname, filename, fullpath, findData){ 
		if filename { 
			var regex = preg("(?P<fname>[\s\S]+)(?P<ext>\.[\s\S]+)")
			var m = regex.exec(filename)
			// filename = "Skin.png"
			// m.fname = "Skin", m.ext = ".png"
		}
	}
)

preg库实际是Perl语言的正则表达式库,此处使用了命名捕获组.
Aardio会自动处理捕获到的信息,并转为变量m的成员.
然后使用Aardio自带的gdip库遍历每个像素点:

import fsys
import gdip
import gdip.imageAttributes
import console
import preg
console.log("足疗馆乙女游戏 - 修复贴图错误工具 v1.0.0.0")
console.log("开始处理...")
var dir = "~\Players"
fsys.enum(dir, {"*.png", "*.jpg"},
	function(dirname, filename, fullpath, findData){ 
		if filename { 
			var regex = preg("(?P<fname>[\s\S]+)(?P<ext>\.[\s\S]+)")
			var m = regex.exec(filename)
			// 拼接文件名,并使用该路径创建BitMap
			var bitMap = gdip.bitmap(dirname + m.fname + m.ext)
			// 由BitMap锁定Data32位像素内存
			var bmpdata = bitMap.lockData32()
			for (h = 1; bitMap.height){
				for(w = 1; bitMap.width){
					// 如果其RGBA十进制颜色值大于#01000000
					if bmpdata.bits.rows[h].pixels[w] > 16777215 
					select bmpdata.bits.rows[h].pixels[w] % 16777216 {
						// RGBA十进制颜色值与1677216的模,0是#xx000000,16777215就是#xxFFFFFF
						// x是任意值 (实际应该是ARGB值?忘记了)
						case == 0 
							bmpdata.bits.rows[h].pixels[w] = 0xFF010101 // 转为非纯黑
						case == 16777215 
							bmpdata.bits.rows[h].pixels[w] = 0xFFFEFEFE // 转为非纯白
					}
				}
			}
			bitMap.unlockData(bmpdata)
			// 解锁
		}
	}
)

此处十进制颜色值的判断十分玄学,已经不太记得思路了
最后把bitMap对象保存到文件.

import fsys
import gdip
import gdip.imageAttributes
import console
import preg
console.log("足疗馆乙女游戏 - 修复贴图错误工具 v1.0.0.0")
console.log("开始处理...")
var dir = "~\Players"
fsys.enum(dir, {"*.png", "*.jpg"},
	function(dirname, filename, fullpath, findData) { 
		if filename { 
			var regex = preg("(?P<fname>[\s\S]+)(?P<ext>\.[\s\S]+)")
			var m = regex.exec(filename)
			var bitMap = gdip.bitmap(dirname + m.fname + m.ext) 
			var bmpdata = bitMap.lockData32()
			for(h = 1; bitMap.height){
				for(w = 1; bitMap.width){  
					if bmpdata.bits.rows[h].pixels[w] > 16777215 
					select bmpdata.bits.rows[h].pixels[w] % 16777216 {
						case == 0 
							bmpdata.bits.rows[h].pixels[w] = 0xFF010101
						case == 16777215 
							bmpdata.bits.rows[h].pixels[w] = 0xFFFEFEFE
					}
				} 
			}
			bitMap.unlockData(bmpdata)
			var timestamp = time().milliseconds // 时间戳
			bitMap.save(dirname ++ timestamp ++ m.ext) // 保存到临时文件
			bitMap.dispose() // 释放内存
			fsys.delete(dirname ++ m.fname ++ m.ext) // 删除源文件
			fsys.rename(dirname ++ timestamp ++ m.ext,dirname ++ m.fname ++ m.ext) // 临时文件重命名为源文件
			console.log("处理中", fullpath)
		}
	}
)
console.log("处理完成!")
console.pause(true) // 按下任意键继续
return // 关闭

至于为什么要保存临时文件再重命名呢,我也不知道
大概就是这样一个简单的Aardio程序,效果是酱的: