Skip to content

Instantly share code, notes, and snippets.

@mattdesl
Created January 2, 2013 21:03
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mattdesl/4438025 to your computer and use it in GitHub Desktop.
package mdes.j4k.tools;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
public class ArrayTranslate {
/** Max number of entities */
public static final int COUNT = 10;
//Our Entity class
enum Entity {
ACTIVE, //whether our entity is active, TRUE or FALSE
TYPE, //type of entity
X, Y, //position
VX, VY, //velocity
HEALTH, //health
MAX_HEALTH, //maximum health
}
// some custom parameters
//false = 0, true = 1
enum Bool {
FALSE,
TRUE;
}
//Entity type constants
enum Entity_types {
PLAYER,
SKELETON,
GOBLIN
}
public static void main(String[] args) {
parse(Entity.values(), "ENTITIES", float.class,
//other types
Entity_types.values(),
Bool.values());
}
public static void parse(Enum<?>[] entities, String arrayName, Class<?> dataType, Enum<?>[] ... constants) {
String prefix = entities[0].getClass().getSimpleName().toUpperCase() + "_";
String dataTypeStr = dataType.getSimpleName();
String vis = "public final static int ";
for (Enum<?>[] en : constants) {
System.out.println("//"+en[0].getClass().getSimpleName().replace('_',' '));
for (Enum<?> e : en) {
System.out.println("public final static "+dataTypeStr+" "+e.name()+" = "+e.ordinal()+";");
}
System.out.println();
}
int entitySize = entities.length;
String strideStr = prefix + "STRIDE";
String countStr = prefix + "COUNT";
String arrayLenStr = prefix + "ARRAY_LENGTH";
System.out.println("//number of " + dataTypeStr + " elements for one entity");
System.out.println(vis + strideStr + " = " + entitySize + ";");
System.out.println("//total number of entities");
System.out.println(vis + countStr + " = " + COUNT + ";");
System.out.println("//array length");
System.out.println(vis + arrayLenStr + " = " + strideStr +" * "+countStr+";");
System.out.println();
System.out.println("//Entity properties");
for (int i = 0; i < entities.length; i++) {
Enum<?> e = entities[i];
if (e.name().equals("STRIDE") || e.name().equals("COUNT") || e.name().equals("ARRAY_LENGTH"))
throw new IllegalArgumentException(e.name()+" is a reserved keyword");
System.out.print(vis);
String name = e.name();
if(!e.name().startsWith("$")) {
System.out.print(prefix);
} else
name = e.name().substring(1);
System.out.println(name + " = " + i+";");
}
System.out.println();
System.out.println("//Entity data");
System.out.println("public final static " + dataTypeStr + "[] " + arrayName + " = new "
+ dataTypeStr + "[" + countStr + " * " + strideStr + "];");
System.out.println("\n//example of looping through each entity");
System.out.println("for (int i=0; i<"+arrayLenStr+"; i+="+strideStr+") {");
System.out.println("\tint index = i/"+strideStr+";");
System.out.println("\t//do something...");
System.out.println("}");
}
static void setClipboard(String contents) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
StringSelection strSel = new StringSelection(contents);
clipboard.setContents(strSel, null);
}
/*
* {
*
* { r, g, b, a nx, ny, nz }
*/
}
package mdes.j4k.tools;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
/**
* Go wild.
* @author davedes
*/
public class ImageTool {
//////////////// COMMON PARAMETERS
/** If false, then BufferedImage will be ignored and only the raw pixels will be used. */
public static boolean useBufferedImage = true;
/** The format to encode with ImageIO when useBufferedImage is true; default "PNG" */
public static String encodeFormat = "PNG";
//////////////// OTHER PARAMETERS
//does not apply to GIF encoding
//-1 or NO_MAX will fit all characters into a single line
public static final int NO_MAX = -1;
/** maximum number of chars to include on a single line for simple encoding */
static int maxStringWidth = NO_MAX;
//This is project-specific; the output is useful if you want to add normal mapping
static boolean useFloatWithNormals = false;
public static void main(String[] args) throws IOException {
//////////////// USAGE
// PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("out.txt")));
// System.setOut(out);
// create(dir("/res/pirates"));
create(dir("/res/pirates"));
// out.close();
// BufferedImage[] imgs = parseBMFont(getResource("res/p.fnt").openStream(), getResource("res/pixel_00.png"), new Dimension(5, 5));
// create(imgs);
//writeFrames("imgs", "char_", 32, "png", imgs);
}
/////////////////////////////////////////////////////////
// MESSY INTERNAL CODE BELOW ... VIEW AT YOUR OWN RISK //
/////////////////////////////////////////////////////////
//TODO: support multiple color formats.. not there yet
static enum Format {
TYPE_INT_ARGB("int", 1),
TYPE_INT_RGBA("int", 1),
TYPE_INT_RGB("int", 1),
TYPE_3BYTE_RGB("byte", 3),
TYPE_4BYTE_RGBA("byte", 4);
public final String type;
public final int numComponents;
Format(String type, int numComponents) {
this.type = type;
this.numComponents = numComponents;
}
}
static Format format = Format.TYPE_INT_ARGB;
public static final Color TRANSPARENT = new Color(0,0,0,0);
static String[] dir(String p) {
URL path = ImageTool.class.getResource(p);
File f = null;
try {
f = new File(path.toURI());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File[] files = f.listFiles();
List<String> out = new ArrayList<String>(files.length);
for (int i=0; i<files.length; i++) {
String o = files[i].getPath();
if (o.toLowerCase().endsWith(".bmp")
|| o.toLowerCase().endsWith(".gif")
|| o.toLowerCase().endsWith(".jpg")
|| o.toLowerCase().endsWith(".jpeg")
|| o.toLowerCase().endsWith(".png")
|| o.toLowerCase().endsWith(".tga"))
out.add(o);
}
return out.toArray(new String[out.size()]);
}
static HashMap<Color, String> colorNames = new HashMap<Color, String>();
static {
try {
Field[] fields = Color.class.getFields();
for (Field f : fields) {
if (!Character.isUpperCase(f.getName().charAt(0)) && f.getDeclaringClass().equals(Color.class.getClass())) {
try {
Color c = (Color)f.get(null);
if (c!=null) {
int rgb = ((int)(c.getRed()) << 16) | ((int)(c.getGreen()) << 8) | (int)(c.getBlue());
colorNames.put(c, "0x"+Integer.toHexString(rgb)+" - "+f.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
colorNames.put(TRANSPARENT, "transparent");
}
static String nameOfColor(Color c, boolean hex) {
String sc = colorNames.get(c);
if (sc!=null)
return sc;
else {
if (hex) {
int rgb = ((int)(c.getRed()) << 16) | ((int)(c.getGreen()) << 8) | (int)(c.getBlue());
return "0x"+Integer.toHexString(rgb);
} else {
return "R="+c.getRed()+", G="+c.getGreen()+", B="+c.getBlue()+", A="+c.getAlpha();
}
}
}
static String parse(String line, String tag) {
tag += "=";
int start = line.indexOf(tag);
if (start==-1)
return null;
int end = line.indexOf(' ', start+tag.length());
if (end==-1)
end = line.length();
return line.substring(start+tag.length(), end);
}
public static void writeFrames(String folder, String namePrefix, int prefixOff, String fmt, BufferedImage ... frames) throws IOException {
File dir = new File(folder);
if (!dir.exists())
dir.mkdir();
for (int i=0; i<frames.length; i++) {
File f = new File(folder+File.separator+namePrefix+(prefixOff+i)+"."+fmt);
if (!f.exists())
f.createNewFile();
ImageIO.write(frames[i], fmt, f);
}
}
public static BufferedImage[] parseBMFont(InputStream bmFont, URL fontImage) throws IOException {
return parseBMFont(bmFont, fontImage, null);
}
public static BufferedImage[] parseBMFont(InputStream bmFont, URL fontImage, Dimension packSize) throws IOException {
if (bmFont==null || fontImage==null)
throw new IllegalArgumentException("font/image files were not found");
BufferedImage[] imgs = new BufferedImage[95]; //standard ASCII characters
BufferedImage sheet = ImageIO.read(fontImage);
BufferedReader br = new BufferedReader(new InputStreamReader(bmFont));
br.readLine(); //skip first
br.readLine(); //skip second
br.readLine(); //skip third
br.readLine(); //skip fourth
String line = "";
while ((line = br.readLine()) != null) {
if (line.startsWith("kernings"))
break;
try {
int id = Integer.parseInt(parse(line, "id"));
int x = Integer.parseInt(parse(line, "x"));
int y = Integer.parseInt(parse(line, "y"));
int width = Integer.parseInt(parse(line, "width"));
int height = Integer.parseInt(parse(line, "height"));
int xoffset = Integer.parseInt(parse(line, "xoffset"));
int yoffset = Integer.parseInt(parse(line, "yoffset"));
BufferedImage img = sheet.getSubimage(x, y, width, height);
if (packSize!=null) {
BufferedImage buf = new BufferedImage(packSize.width, packSize.height, BufferedImage.TYPE_4BYTE_ABGR);
buf.getGraphics().drawImage(img, 0, 0, null);
img = buf;
}
imgs[id-32] = img;
// System.out.println(((char)id)+" x="+id+" y="+x+" "+y+" w="+width+" h="+height+" xoff="+xoffset+" yoff="+yoffset);
} catch (Exception e) {
System.out.println("err on "+line+" "+e.getMessage());
}
}
return imgs;
}
public static void create(String ... frames) throws IOException {
create(null, 0, frames);
}
public static void create(BufferedImage ... frames) throws IOException {
create(null, 0, frames, null);
}
public static void create(List<Color> colorTable, int defaultIndex, String ... frames) throws IOException {
BufferedImage[] imgs = new BufferedImage[frames.length];
String[] names = new String[frames.length];
for (int i=0; i<imgs.length; i++) {
try {
imgs[i] = ImageIO.read(ImageTool.class.getResource(frames[i]));
} catch (Exception e) {
imgs[i] = ImageIO.read(new File(frames[i]));
}
names[i] = frames[i].toUpperCase();
int start = frames[i].replace('\\','/').lastIndexOf('/');
if (start==-1)
start = 0;
int end = frames[i].lastIndexOf('.');
if (end==-1)
end = frames[i].length();
names[i] = frames[i].substring(start+1, end).toUpperCase();
}
create(colorTable, defaultIndex, imgs, names);
}
static void printBigString(CharSequence str, int blockSize) {
String text = str.toString().replace("\\", "\\\\").replace("\"", "\\\"");
if (blockSize==-1) {
System.out.print("\""+text+"\"");
} else {
System.out.println("(");
for (int i=0; i<text.length(); i+=blockSize) {
System.out.print("\t");
boolean appendPlus = false;
if (i+blockSize < text.length()) {
CharSequence seq = text.subSequence(i, i+blockSize);
System.out.print("\""+seq+"\"");
appendPlus = true;
} else {
System.out.print("\""+text.subSequence(i, text.length())+"\"");
}
if (appendPlus) {
System.out.print(" +");
System.out.println();
} else
System.out.print(")");
// System.out.println(buf.substring(i, Math.min(buf.length(), i+maxWidth)).toString())
}
}
}
public static void create(List<Color> colorTable, int defaultIndex, BufferedImage[] frames, String[] names) {
//TODO: formats not yet supported
if (useFloatWithNormals) {
format = Format.TYPE_4BYTE_RGBA;
useBufferedImage = false;
} else {
format = Format.TYPE_INT_ARGB;
}
if (names==null) {
names = new String[frames.length];
for (int i=0; i<names.length; i++) {
names[i] = "IMG_"+i;
}
}
byte[][] pixels = new byte[frames.length][];
int firstWidth=0,firstHeight=0;
int width=0,height=0;
for (int i=0; i<frames.length; i++) {
BufferedImage img = frames[i];
width = img.getWidth();
height = img.getHeight();
if (i==0) {
firstWidth = width;
firstHeight = height;
} else if (firstWidth!=width || firstHeight!=height) {
throw new IllegalArgumentException("frames must be equal size");
}
BufferedImage img2 = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
img2.getGraphics().drawImage(img, 0,0,null);
img = img2;
pixels[i] = ((DataBufferByte)img.getRaster().getDataBuffer()).getData();
}
//loop through once and grab colors
if (colorTable==null) {
colorTable = new ArrayList<Color>();
for (int f=0; f<frames.length; f++) {
byte[] px = pixels[f];
for (int i=0; i<px.length; i+=4) {
int a = px[i] & 0xFF;
int b = px[i+1] & 0xFF;
int g = px[i+2] & 0xFF;
int r = px[i+3] & 0xFF;
Color clr = new Color(r, g, b, a);
int index = colorTable.indexOf(clr);
if (index==-1) {
colorTable.add(clr);
index = colorTable.size()-1;
}
}
}
//make transparent, white and black the first colors...
Color[] reg = new Color[] { Color.white, Color.black, TRANSPARENT };
for (int i=0; i<reg.length; i++) {
if (colorTable.contains(reg[i])) {
colorTable.remove(reg[i]);
colorTable.add(0, reg[i]);
}
}
}
int[] indexed = new int[width*height*frames.length];
for (int f=0, off=0; f<frames.length; f++, off+=width*height) {
byte[] px = pixels[f];
for (int i=0; i<px.length; i+=4) {
int a = px[i] & 0xFF;
int b = px[i+1] & 0xFF;
int g = px[i+2] & 0xFF;
int r = px[i+3] & 0xFF;
int index = colorTable.indexOf(new Color(r, g, b, a));
if (index==-1)
index = defaultIndex;
indexed[off + i/4] = index;
}
}
System.out.println("//"+format.name()+" color table");
System.out.println("public static final "+format.type+"[] TABLE = new "+format.type+"[] {");
for (int i=0; i<colorTable.size(); i++) {
Color c = colorTable.get(i);
boolean hexInComment = true;
if (format.type.equals("int")) {
int value = 0x0;
if (format==Format.TYPE_INT_ARGB) {
value = ((int)(c.getAlpha()) << 24) | ((int)(c.getRed()) << 16) | (int)(c.getGreen() << 8) | c.getBlue();
} else if (format==Format.TYPE_INT_RGBA){
if (useBufferedImage)
throw new IllegalStateException("IntRGBA only works if useBufferedImage=false");
value = ((int)(c.getRed()) << 24) | ((int)(c.getGreen()) << 16) | (int)(c.getBlue() << 8) | c.getAlpha();
} else if (format==Format.TYPE_INT_RGB) {
value = ((int)(c.getRed()) << 16) | ((int)(c.getGreen()) << 8) | c.getBlue();
} else {
throw new IllegalStateException("invalid format "+format.name());
}
//print hex
String s = "0x"+Integer.toHexString(value);
System.out.print("\t"+s);
//use ints in comments
hexInComment = false;
} else {
if (format==Format.TYPE_3BYTE_RGB) {
System.out.print("\t"+c.getRed()+",\t"+c.getGreen()+",\t"+c.getBlue());
} else if (format==Format.TYPE_4BYTE_RGBA) {
System.out.print("\t"+c.getRed()+",\t"+c.getGreen()+",\t"+c.getBlue()+",\t"+c.getAlpha());
} else {
throw new IllegalStateException("invaild format "+format.name());
}
}
if (i!=colorTable.size()-1)
System.out.print(",");
System.out.println("\t//"+nameOfColor(c, hexInComment));
}
System.out.println("};");
System.out.println();
System.out.println("//sprite array properties");
System.out.println("public static final int SPRITE_WIDTH = "+width+";");
System.out.println("public static final int SPRITE_HEIGHT = "+height+";");
System.out.println("public static final int SPRITE_COUNT = "+frames.length+";");
if (useFloatWithNormals) {
System.out.println("public static final int SPRITE_SIZE = SPRITE_WIDTH * SPRITE_HEIGHT;");
System.out.println("public static final int SPRITE_COMPONENTS = "+format.numComponents
+" * 3; //Diffuse."+format.name()+", Normal.XYZ");
System.out.println("public static final int SPRITE_STRIDE = SPRITE_SIZE * SPRITE_COMPONENTS;");
} else {
System.out.println("public static final int SPRITE_STRIDE = SPRITE_WIDTH * SPRITE_HEIGHT;");
}
System.out.println("public static final int SPRITE_ARRAY_LEN = SPRITE_STRIDE * SPRITE_COUNT;");
StringBuilder sb = new StringBuilder();
final int CHR_OFFSET = colorTable.size() <= 10 ? 48 : 32;
for (int i=0, chrs=0; i<indexed.length; i++, chrs++) {
int b = indexed[i];
sb.append((char)(b+CHR_OFFSET));
}
if (useFloatWithNormals)
System.out.println("public static final int SPRITE_ENCODING_LENGTH = "+sb.length()+";");
System.out.println();
String dataType = useFloatWithNormals ? "float" : "int";
if (!useBufferedImage) {
System.out.println("//the sprite image color data");
System.out.println("public static final "+dataType+"[] SPRITES = new "+dataType+"[SPRITE_ARRAY_LEN];");
System.out.println();
}
System.out.println("//offsets to different sprite indices");
for (int i=0; i<names.length; i++) {
System.out.print("public static final int SPRITE_"+names[i]+" = ");
if (useBufferedImage)
System.out.println(i+";");
else
System.out.println("SPRITE_STRIDE * "+i+";");
}
System.out.println();
if (useFloatWithNormals) {
System.out.println("//////// Simple Indexed Color Encoding");
System.out.print("for (int i=0; i<SPRITE_ENCODING_LENGTH; i++) {\n" +
"\tint c = (int)(");
printBigString(sb.toString(), maxStringWidth);
System.out.println(".charAt(i)-"+CHR_OFFSET+");\n" +
"\t//Diffuse RGBA\n" +
"\tSPRITES[i*SPRITE_COMPONENTS] = TABLE[c*"+format.numComponents+"]/255f;\n" +
"\tSPRITES[i*SPRITE_COMPONENTS+1] = TABLE[c*"+format.numComponents+"+1]/255f; \n" +
"\tSPRITES[i*SPRITE_COMPONENTS+2] = TABLE[c*"+format.numComponents+"+2]/255f;\n" +
"\tSPRITES[i*SPRITE_COMPONENTS+3] = TABLE[c*"+format.numComponents+"+3]/255f; \n" +
"\t\n" +
"\t//The x/y position of the current pixel\n" +
"\tint y = i%SPRITE_SIZE / SPRITE_WIDTH;\n" +
"\tint x = i%SPRITE_SIZE - SPRITE_WIDTH * y;\n" +
"\t\n" +
"\t//Normals XYZ\n" +
"\tSPRITES[i*SPRITE_COMPONENTS+4] = ((x/(float)SPRITE_WIDTH)*2-1)*0.5f;\n" +
"\tSPRITES[i*SPRITE_COMPONENTS+5] = ((y/(float)SPRITE_HEIGHT)*2-1)*0.5f;\n" +
"\tSPRITES[i*SPRITE_COMPONENTS+6] = 1f;\n" +
"\t\n" +
"\t//INCLUDED FOR REFERENCE:\n" +
"\t\n" +
"\t//The index of the sprite image\n" +
"\t//int spriteIndex = i/SPRITE_SIZE;\n" +
"\t\n" +
"\t//The index of the current pixel for this sprite image\n" +
"\t//int pixelIndex = i % SPRITE_SIZE;\n" +
"}");
} else if (useBufferedImage) {
System.out.println("//////// ENCODING METHOD: Simple Indexed Color Encoding");
System.out.print(
"public static final BufferedImage SPRITE_SHEET = new BufferedImage(SPRITE_WIDTH, SPRITE_HEIGHT * SPRITE_COUNT, BufferedImage.TYPE_INT_ARGB);\n" +
"public static final int[] SPRITE_PIXELS = ((DataBufferInt)SPRITE_SHEET.getRaster().getDataBuffer()).getData();\n" +
"public static final BufferedImage[] SPRITES = new BufferedImage[SPRITE_COUNT];\n\n"+
"for (int i=0; i<SPRITE_ARRAY_LEN; i++) {\n" +
"\tSPRITE_PIXELS[i] = TABLE[");
printBigString(sb.toString(), maxStringWidth);
System.out.println(".charAt(i)-"+CHR_OFFSET+"];");
if (frames.length>1) {
System.out.println(
"\tif (i%SPRITE_STRIDE == SPRITE_STRIDE-1) {\n" +
"\t\tSPRITES[i/(SPRITE_WIDTH*SPRITE_HEIGHT)] = SPRITE_SHEET.getSubimage(\n" +
"\t\t\t0, i/(SPRITE_WIDTH*SPRITE_HEIGHT)*SPRITE_HEIGHT, \n" +
"\t\t\tSPRITE_WIDTH, SPRITE_HEIGHT);\n" +
"\t}");
}
System.out.println("}");
} else {
System.out.println("//////// ENCODING METHOD: Simple Indexed Color Encoding");
System.out.print("for (int i=0; i<SPRITE_ARRAY_LEN; i++) {\n" +
"\tSPRITES[i] = (byte)(");
printBigString(sb.toString(), maxStringWidth);
System.out.println(".charAt(i)-"+CHR_OFFSET+");\n" +
"}");
}
System.out.println();
//pack gifs into new
if (useBufferedImage) {
BufferedImage sheet;
if (frames.length==1)
sheet = frames[0];
else { //create sprite sheet from frames
sheet = new BufferedImage(width, height*frames.length, BufferedImage.TYPE_INT_ARGB);
Graphics g = sheet.createGraphics();
for (int i=0; i<frames.length; i++) {
g.drawImage(frames[i], 0, i*height, null);
}
g.dispose();
}
System.out.println("//////// ENCODING METHOD: "+encodeFormat+" Encoding");
System.out.println("// You can remove the color table and some of the constants defined earlier");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(sheet, encodeFormat, baos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("BufferedImage SPRITE_SHEET = null;");
if (frames.length>1) {
System.out.println("BufferedImage[] SPRITES = new BufferedImage[SPRITE_COUNT];");
}
String str = DatatypeConverter.printBase64Binary(baos.toByteArray());
System.out.println("try {\n" +
"\tSPRITE_SHEET = ImageIO.read(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(\n" +
"\t\t\""+str+"\"\n" +
"\t\t)));");
if (frames.length>1) {
System.out.println("\tfor (int i=0; i<SPRITE_COUNT; i++) \n" +
"\t\tSPRITES[i] = SPRITE_SHEET.getSubimage(0, i*SPRITE_HEIGHT, SPRITE_WIDTH, SPRITE_HEIGHT);");
}
System.out.println("} catch (Exception e) {\n" +
" // TODO Auto-generated catch block\n" +
"}");
System.out.println();
}
// System.out.println("//Simple block encoding:");
// StringBuilder sbEnc2 = new StringBuilder();
// int last = -1;
// int counter = 1;
// for (int i=0; i<indexed.length; i++) {
// int b = indexed[i];
// if (counter>=94) { //special case.. we need to reset counter
// sbEnc2.append((char)(48+last));
// sbEnc2.append((char)(32+counter));
// counter = 1;
// } else if (last==-1) { //first run
// if (i==indexed.length-1) { //special case -- 1 char long
// sbEnc2.append((char)(48+last));
// sbEnc2.append((char)(32+counter));
// }
// } else if (last==b) { //same index as last check, increase counter
// counter++;
// if (i==indexed.length-1) {
// sbEnc2.append((char)(48+last));
// sbEnc2.append((char)(32+counter));
// }
// } else { //new index, print last one and counter
// sbEnc2.append((char)(48+last));
// sbEnc2.append((char)(32+counter));
// counter = 1;
// }
// last = b;
// }
// System.out.println(sbEnc2.toString());
// System.out.println();
/* TODO: support binary packed encoding
if (!useFloatWithNormals && width * height <= 32 && colorTable.size()==2) {
ArrayList<Integer> packedList = new ArrayList<Integer>();
for (int f=0, off=0; f<frames.length; f++) {
int packed = 0;
for (int i=0; i<width * height; i++) {
packed = (packed << 1) | indexed[off + i];
}
packedList.add(packed);
off += width * height;
}
System.out.println("//////// ENCODING METHOD: Binary-Packed (2 colors, width*height <= 32)");
System.out.println("final int[] SPRITE_DATA = new int[] {");
System.out.print("\t");
for (int i=0, count=0; i<packedList.size(); i++, count++) {
int packed = packedList.get(i);
System.out.print("0x"+Integer.toHexString(packed));
// System.out.print(packed);
if (i!=packedList.size()-1) {
System.out.print(", ");
if (count>8) {
System.out.print("\n\t");
count = 0;
}
}
}
System.out.println("\n};");
System.out.println();
System.out.println("for (int f=0, off=0; f<SPRITE_COUNT; f++, off+=SPRITE_STRIDE) {\n" +
" for (int i=0; i<SPRITE_STRIDE; i++)\n" +
" SPRITES[off+i] = ((SPRITE_DATA[f]>>(SPRITE_STRIDE-1-i)) & 1);\n" +
"}");
System.out.println();
}*/
// if (!useFloatWithNormals && indexed.length < 95 && colorTable.size()<=2) {
// int lastIndex = indexed[0];
// int lastPos = 0;
// int count = 0;
// StringBuilder sbEnc3 = new StringBuilder();
// System.out.println("//Monochromatic (two colors, less than 95 pixels large):");
// for (int i=0; i<indexed.length; i++) {
// int b = indexed[i];
// //if this index is different
// if (b!=lastIndex) {
// if (lastIndex!=0) {
// sbEnc3.append( (char)(32 + lastPos) ); //append pixel position
// sbEnc3.append( (char)(32 + count) ); //append count
// }
// count = 1;
// lastPos = i;
// } else {
// count++;
// if (i==indexed.length-1 && lastIndex!=0) {
// sbEnc3.append( (char)(32 + lastPos) ); //append pixel position
// sbEnc3.append( (char)(32 + count) ); //append count
// }
// }
// lastIndex = b;
// }
//
// System.out.println("final int COLOR_MONOCHROME = 1;\n" +
// "char[] data = \""+sbEnc3.toString().replace("\\", "\\\\").replace("\"", "\\\"")+"\".toCharArray();\n" +
// "for (int i=0; i<data.length; i+=2) {\n" +
// " int index = ((int)data[i])-32;\n" +
// " int num = ((int)data[i+1])-32;\n" +
// " while (num-- > 0) \n" +
// " SPRITES[index + num] = COLOR_MONOCHROME;\n" +
// "}");
// System.out.println();
// }
// String[] s = "".split(' ');
// for (int color=0; color<s.length; color++) {
// for (int i=1; i<s[color].length(); i++) {
// int index = ((int)s[color].charAt(i))-32;
// int num = ((int)s[color].charAt(i+1))-32;
// while (num-- > 0)
// SPRITES[index + num] = color;
// }
// }
// for(int i = 0; i < 8; i++) {
// result[i] = (byte) ((val >> (7 - i)) & 1);
// }
//int value = 1 << ;
// for (int i=0; i)
// value = (value << 1) | 1;
// for (int i=0; i<indexed.length; i++) {
// value = value & indexed[i];
// }
}
}
package mdes.j4k.tools;
public class ImageToolTest {
public static void main(String[] args) throws Exception {
//GIF transparency is a bit wonky with ImageIO
ImageTool.encodeFormat = "PNG";
//If true, then we get code that will work with BufferedImage
//If false, the code is more tailored toward per-pixel rendering
ImageTool.useBufferedImage = true;
//You can pass individual images like so:
//ImageTool.create("/res/knight1.png", "/res/knight2.png");
//Or you can load an entire directory into a sprite sheet
ImageTool.create(ImageTool.dir("/res/pirates/"));
//Or you can pass BufferedImages directly
//ImageTool.create(arrayOfBufferedImages);
}
}
import java.applet.Applet;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
public class T extends Applet implements Runnable {
//////////////////////////////////////////////////////////
// image tool output /////////////////////////////////////
//////////////////////////////////////////////////////////
//TYPE_INT_ARGB color table
public static final int[] TABLE = new int[] {
0x0, //transparent
0xff1a1a1a, //R=26, G=26, B=26, A=255
0xffbfbfbf, //R=191, G=191, B=191, A=255
0xffa29446, //R=162, G=148, B=70, A=255
0xfff7e26b, //R=247, G=226, B=107, A=255
0xffc20000, //R=194, G=0, B=0, A=255
0xffff0000, //R=255, G=0, B=0, A=255
0xff9d9d9d, //R=157, G=157, B=157, A=255
0xff6f4417, //R=111, G=68, B=23, A=255
0xffa46422 //R=164, G=100, B=34, A=255
};
//sprite array properties
public static final int SPRITE_WIDTH = 11;
public static final int SPRITE_HEIGHT = 9;
public static final int SPRITE_COUNT = 6;
public static final int SPRITE_STRIDE = SPRITE_WIDTH * SPRITE_HEIGHT;
public static final int SPRITE_ARRAY_LEN = SPRITE_STRIDE * SPRITE_COUNT;
//offsets to different sprite indices
public static final int SPRITE_PIRATE1_ATTACK = 0;
public static final int SPRITE_PIRATE1_WALK1 = 1;
public static final int SPRITE_PIRATE1_WALK2 = 2;
public static final int SPRITE_PIRATE2_ATTACK = 3;
public static final int SPRITE_PIRATE2_WALK1 = 4;
public static final int SPRITE_PIRATE2_WALK2 = 5;
//////// ENCODING METHOD: Simple Indexed Color Encoding
public static final BufferedImage SPRITE_SHEET = new BufferedImage(SPRITE_WIDTH, SPRITE_HEIGHT * SPRITE_COUNT, BufferedImage.TYPE_INT_ARGB);
public static final int[] SPRITE_PIXELS = ((DataBufferInt)SPRITE_SHEET.getRaster().getDataBuffer()).getData();
public static final BufferedImage[] SPRITES = new BufferedImage[SPRITE_COUNT];
//////////////////////////////////////////////////////////
// end generated code ////////////////////////////////////
//////////////////////////////////////////////////////////
//TODO: remove these if not needed
boolean[] keys = new boolean[32767];
float mouseX, mouseY;
public void start() {
enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
new Thread(this).start();
}
public void run() {
//Set up graphics
final int WIDTH = 240;
final int HEIGHT = 160;
final int SCALE = 2;
setSize(WIDTH*SCALE, HEIGHT*SCALE); // For AppletViewer, remove later.
//Set up our screen image
final BufferedImage screen = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
final int[] pixels = ((DataBufferInt)screen.getRaster().getDataBuffer()).getData();
final Graphics2D g = (Graphics2D)screen.getGraphics();
final Graphics appletGraphics = getGraphics();
// Some variables to use for the fps.
int tick = 0, fps = 0, acc = 0;
long lastTime = System.nanoTime();
// ---------------- LOAD IMAGES ---------------- //
//////////////////////////////////////////////////////////
// image tool output /////////////////////////////////////
//////////////////////////////////////////////////////////
for (int i=0; i<SPRITE_ARRAY_LEN; i++) {
SPRITE_PIXELS[i] = TABLE["000000000001111212000011111110000034141000000344430000255666502220411171400000888880000008000800000000000000001111212020011111110200034141002000344430200055666540000411171000000888880000008000800000111121202001111111020003414100200034443020005566654000041117100000088888000000888880000008000800000000000000006066600000006666600000634141000000344430000288999802220411171400000888880000008000800000000000000006066600020006666600200634141002000344430200088999840000411171000000888880000008000800000606660002000666660020063414100200034443020008899984000041117100000088888000000888880000008000800000".charAt(i)-48];
if (i%SPRITE_STRIDE == SPRITE_STRIDE-1) {
SPRITES[i/(SPRITE_WIDTH*SPRITE_HEIGHT)] = SPRITE_SHEET.getSubimage(
0, i/(SPRITE_WIDTH*SPRITE_HEIGHT)*SPRITE_HEIGHT,
SPRITE_WIDTH, SPRITE_HEIGHT);
}
}
// ---------------- GAME LOOP ---------------- //
while (true) {
long now = System.nanoTime();
long delta = now - lastTime;
acc += delta;
tick++;
if (acc >= 1000000000L) {
acc -= 1000000000L;
fps = tick;
tick = 0;
}
// Update
lastTime = now;
//TODO: remove later if not needed
g.clearRect(0, 0, WIDTH, HEIGHT);
// ---------------- DRAW SPRITES ---------------- //
g.drawImage(SPRITES[SPRITE_PIRATE2_ATTACK],
50, 50,
SPRITE_WIDTH*2, SPRITE_HEIGHT*2,
null);
//TODO: remove later
g.setColor(Color.white);
g.drawString("FPS " + String.valueOf(fps), 20, 30);
// Draw the entire results on the screen.
appletGraphics.drawImage(screen, 0, 0, WIDTH*SCALE, HEIGHT*SCALE, null);
do {
Thread.yield();
} while (System.nanoTime() - lastTime < 1000000000/60);
if (!isActive()) {
return;
}
}
}
public void processEvent(AWTEvent e)
{
boolean down = false;
switch (e.getID())
{
case KeyEvent.KEY_PRESSED:
down = true;
case KeyEvent.KEY_RELEASED:
keys[((KeyEvent) e).getKeyCode()] = down;
break;
case MouseEvent.MOUSE_PRESSED:
down = true;
case MouseEvent.MOUSE_RELEASED:
keys[((MouseEvent) e).getButton()] = down;
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
mouseX = ((MouseEvent) e).getX();
mouseY = ((MouseEvent) e).getY();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment