www.jpct.net

jPCT - a 3d engine for Java => Projects => Topic started by: KittenKoder on November 01, 2012, 01:27:12 am

Title: New Library And Game
Post by: KittenKoder on November 01, 2012, 01:27:12 am
Alright, I am working on a project that's cyberpunk "hacking," I spent the last year practicing modeling in 3D just so I could do this one. OpenGL perplexed me, and developing a system from scratch was too tedious so I found jPCT, which is perfect for my needs. However for the game I am developing a library that includes:

1. Multilayer world system, one layer for a GUI, another for the game, and one in between for "x-ray" objects. There is a world manager than can clean out things owned by only one of the worlds, included textures not needed elsewhere if the extended texture manager is used.

2. A texture manager that incorporates the jPCT texture manager with a few lists for tracking the texture image. Texture image class can be a texture, buffered image, or both, and has a built in dynamic update. Textures can be "owned" by objects and/or worlds so when those are removed from the game the textures can also be removed with them using only one method call.

3. Texture "sequences" for more complex texture animations. A complete system for adding these to the extended object class, extended to accommodate a lot of game dependent data.

4. Texture "layering" the efficient way. The library uses the AWT GL Canvas, which has a few limitations. The layered texture class overcomes some of them by combining multiple buffered images into one new texture, it actually combines multiple buffered images then creates a texture from that.

5. A managed HUD system, pretty straight forward, for posting things like text to the player or meters, 2D elements and the like.

6. The world GUI system, which includes animation responses, an event binding system that is versatile yet easy to use with keyboard, mouse, or even game controller input, you can combine several for each binding allowing multiple ways for the player to access something if desired.

7. An actor system for managing objects, specifically animated objects used for characters.

8. An audio system that utilizes the Tritonus plugins.

I will hopefully have the working demo, and a set of example programs, very soon. The demo will be the game demo as well. The jPCT extension library is dependent on my dev-libs, which includes a Canvas 2D GUI system as well, though it's basic it has some useful features and widgets focused on games.

My standard library, I often call my dev-lib.
http://www.java-gaming.org/user-generated-content/members/130380/kittstandard-v0-1.jar (http://www.java-gaming.org/user-generated-content/members/130380/kittstandard-v0-1.jar)

The jPCT extension, requires jPCT of course, as well as Tritonus plugins for some audio formats, wav is supported directly by Java so if you don't use any other formats you don't need Tritonus.
http://www.java-gaming.org/user-generated-content/members/130380/jpctkitt-v0-1.jar (http://www.java-gaming.org/user-generated-content/members/130380/jpctkitt-v0-1.jar)

Edit: Thank you for moving it to the correct location.
Title: Re: New Library And Game
Post by: KittenKoder on November 04, 2012, 09:47:33 am
Large screen caps of the test app so far.

The 3D GUI.
(http://digitalnoisegraffiti.com/backups/3D.png)

The Canvas GUI.
(http://digitalnoisegraffiti.com/backups/2D.png)
Title: Re: New Library And Game
Post by: EgonOlsen on November 05, 2012, 09:39:36 am
Nice. I like the 3d effect. Does it render the labels by itself or are they part of a texture?
Title: Re: New Library And Game
Post by: KittenKoder on November 06, 2012, 06:05:54 am
Nice. I like the 3d effect. Does it render the labels by itself or are they part of a texture?

They are rendered onto the texture. There is a method in the Image/Texture class that allows you to make it dynamic using an texture effect interface, which is actually an alternate class to conserve memory. The image font class I wrote for the Canvas widgets is used for the printing onto the texture. If you use the dynamic interface then you can call a method in the image/texture object to update the texture easily. The text display at the bottom uses the same method, instead of blitting every letter.

Basically, it takes a BufferedImage, keeps the image in memory, and when you change the image you call the update method and that change is made to the texture using jPCT's texture effect interface. There is also a loader, which I need to work on a bit more as it's highly inefficient yet, that will combine two images to produce the texture, using BufferedImage of course. The green icons on that screen shot uses that specific technique as well. The icons and blank model texture are loaded as buffered images, then the you duplicate the blank one, paint the icon onto it, and it creates the texture. Though those I did not use dynamic texture images since they only needed to do that once. The model texture for the widgets I used a half texture for each of the color sets, so one texture has two color sets, and just flipped the U or V based on the orientation. Still working on how to simplify that process, it may not be something that can be simplified, but I extended the Object3D to include two methods, one for flipping the U the other for flipping the V, to make that part easier.
Title: Re: New Library And Game
Post by: KittenKoder on November 06, 2012, 11:52:50 am
Figured I should show what the test app looks like so you can get an idea of how it's done a bit.

Code: [Select]
package app;

import java.awt.Color;
import java.awt.Container;
import java.awt.HeadlessException;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import kitt.com.jpct.WorldManager;
import kitt.com.jpct.XMLLoader;
import kitt.com.jpct.actor.Actor;
import kitt.com.jpct.actor.ActorCameraFocal;
import kitt.com.jpct.anim.Animator;
import kitt.com.jpct.anim.AnimatorCallback;
import kitt.com.jpct.anim.AnimatorCharacter;
import kitt.com.jpct.anim.AnimatorStayWith;
import kitt.com.jpct.ext.AmbientFull;
import kitt.com.jpct.ext.LightFlicker;
import kitt.com.jpct.ext.Object3DEx;
import kitt.com.jpct.ext.RadialCamera;
import kitt.com.jpct.game.ControllerData;
import kitt.com.jpct.game.GamePads;
import kitt.com.jpct.gui.world.CanvasEventHandler;
import kitt.com.jpct.gui.world.GUIWorldEx;
import kitt.com.jpct.gui.world.WorldEventHandler;
import kitt.com.jpct.gui.world.WorldSelector;
import kitt.com.jpct.gui.world.anim.GUIAnimator;
import kitt.com.jpct.gui.world.event.Controller2ButtonBinding;
import kitt.com.jpct.gui.world.event.ControllerAxisBinding;
import kitt.com.jpct.gui.world.event.ControllerBinding;
import kitt.com.jpct.gui.world.event.ControllerButtonBinding;
import kitt.com.jpct.gui.world.event.KeyBinding;
import kitt.com.jpct.gui.world.event.KeyDualBinding;
import kitt.com.jpct.gui.world.event.KeyQuadBinding;
import kitt.com.jpct.gui.world.event.MouseBinding;
import kitt.com.jpct.gui.world.event.bind.ActorBinding;
import kitt.com.jpct.gui.world.event.bind.CanvasBinding;
import kitt.com.jpct.gui.world.event.bind.EventBinding;
import kitt.com.jpct.gui.world.event.bind.EventBindingCallback;
import kitt.com.jpct.gui.world.event.bind.GUISelectionBinding;
import kitt.com.jpct.gui.world.event.bind.GUISelectorBinding;
import kitt.com.jpct.gui.world.event.bind.GUIToggleBinding;
import kitt.com.jpct.gui.world.event.bind.RadialCameraBinding;
import kitt.com.jpct.gui.world.event.bind.WorldSelectionBinding;
import kitt.com.jpct.gui.world.event.bind.data.ToggleData;
import kitt.com.jpct.gui.world.kits.ElementKits;
import kitt.com.jpct.gui.world.kits.SelectorKit;
import kitt.com.jpct.hud.AnimatedBackground;
import kitt.com.jpct.hud.HUDBarVerUp;
import kitt.com.jpct.hud.HUDManager;
import kitt.com.jpct.hud.HUDTextLayer;
import kitt.com.jpct.hud.HUDTextureElement;
import kitt.com.jpct.swing.GLPanel;
import kitt.com.jpct.tex.LinkedTextureImage;
import kitt.com.jpct.tex.TextureImage;
import kitt.com.jpct.tex.TextureManagerEx;
import kitt.com.jpct.tex.TexturePack;
import kitt.com.jpct.tex.TextureSequence;
import kitt.com.math.ColorFloat;
import kitt.com.math.Coordinate;
import kitt.com.math.Dimension;
import kitt.com.swing.Util;
import kitt.com.swing.canvas.CanvasButton;
import kitt.com.swing.canvas.CanvasGUI;
import kitt.com.swing.canvas.CanvasLabel;
import kitt.com.swing.canvas.CanvasPointer;
import kitt.com.swing.canvas.data.CanvasImageFont;
import kitt.com.swing.canvas.kits.MenuKit;
import kitt.com.swing.canvas.kits.ToggleMenuKit;
import kitt.com.swing.canvas.kits.WidgetKits;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;

public class HUDTest extends JFrame implements EventBindingCallback, AnimatorCallback {
private static final long serialVersionUID = 1L;

private static final String modelsdir = "res/models/";
private static final String texdir = "res/tex/";

private GLPanel mainpanel = null;
private HUDManager hud = null;
private TextureImage guitexture = null;
private TextureImage barstexture = null;
private RadialCamera camera = null;
private ControllerData controller = null;
private GUIWorldEx gui3d = null;
private ActorBinding mover = null;
// private File ping = null;

private Object3DEx box = null;
private WorldEventHandler eventhandler = null;
private CanvasEventHandler canvashandler = null;
private GUIToggleBinding hextoggle = null;
private HUDTextLayer textlayer = null;
private ActorCameraFocal mainactor = null;
private AnimatorCharacter mainanimator = null;

private CanvasGUI basecanvas = null;

public HUDTest() throws HeadlessException {
this.setup();
}

private void setup() {
this.setTitle("HUD Test");
this.setBounds(0, 0, 256, 256);
this.setLocationRelativeTo(null);

this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.setResizable(false);
Container cpane = this.getContentPane();
cpane.setLayout(null);

this.setVisible(true);
Dimension dim = Util.getRealSize(this, 1024, 768);
Coordinate loc = Util.centerScreen(dim.width, dim.height);
this.setBounds(loc.x, loc.y, dim.width, dim.height);

Config.isIndoor = true;
Config.glFullscreen = false;
Config.glAvoidTextureCopies = true;
Config.glColorDepth = 24;
// Config.farPlane = 4000;
Config.glShadowZBias = 0.8f;
Config.lightMul = 1;
Config.collideOffset = 500;
Config.glTrilinear = true;

this.mainpanel = new GLPanel(1024, 768);
this.mainpanel.setRenderGL(false);

// AudioManager.playLoop("res/audio/music/danosongs.com-bitbybits.ogg", -5.0f);
// this.ping = new File("res/audio/effects/ping.wav");

this.basecanvas = new CanvasGUI();
this.mainpanel.setBaseCanvas(this.basecanvas);
this.basecanvas.setBackground(new Color(0,128,128,128));
this.basecanvas.setForeground(new Color(64,255,255));
this.basecanvas.setName("Main Menu");
this.basecanvas.setFont(CanvasGUI.FONTLARGE);
this.basecanvas.setTextColor(Color.WHITE);

CanvasGUI.DEFAULT_DISABLED = new Color(255,0,0,128);
CanvasGUI.DEFAULT_HOVER = new Color(0,255,0,128);
CanvasGUI.DEFAULT_PRESSED = new Color(0,0,255,128);
CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,0);
CanvasGUI.DEFAULT_BACKGROUND = CanvasGUI.HALFBLACK;;

this.canvashandler = new CanvasEventHandler(this.basecanvas);
this.canvashandler.addTo(this.basecanvas);
this.mainpanel.setCurrentEventHandler(this.canvashandler);

this.basecanvas.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER);

this.guitexture = TextureManagerEx.loadImageTexture("res/tex/gui/base.png", "gui", true, true);
this.barstexture = TextureManagerEx.loadImageTexture("res/tex/gui/bars-ver.png", "bars", true, true);
TextureImage timage = TextureManagerEx.loadImageTexture("res/tex/font-base.png", "font", true, true);
CanvasGUI.IMAGEFONT = new CanvasImageFont(timage.getImage(), 32, 32);
CanvasGUI.IMAGEFONT.setBaseline(8);
CanvasGUI.IMAGEFONT.setAsciiOffset(32);
CanvasGUI.IMAGEFONT.setScale(0.5f);
TexturePack icons = XMLLoader.loadPackFromXML("res/xml/texpack-icons.xml", HUDTest.texdir, this.gui3d);

TextureImage image = TextureManagerEx.loadImageTexture("res/tex/icons/icon-logo-full.png", "icon-logo", true, true);
CanvasLabel label = new CanvasLabel(null, "Hacker's\nHaven", 100, 50, 100, 100);
label.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_LEFT | CanvasGUI.TEXT_TOP | CanvasGUI.IMAGE_STRETCH);
label.setImage(image.getImage());
this.basecanvas.addWidget(label);

CanvasButton button = new CanvasButton(null, "Pause", 0, 0, 100, 100);
button.setID("Pause");
this.basecanvas.addWidget(button);

String[][] options = {
{"GameStart", "Start"},
{"GameLoad", "Load"},
{"GameConfigure", "Settings"},
{"GameDelete", "Delete"},
{"GameExit", "Exit"}
};
MenuKit menu = WidgetKits.makeMenu(this.basecanvas, "Main Menu",
null, 150, 40,
options, 3, -1);
menu.parent.setLocation(200, 250);
menu.parent.setEnabled(false);

CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,255);

String[][] toptions = {
{"GameFun", "Fun"},
{"GameWicked", "Wicked"},
{"GameCool", "Cool"},
{"GameRun", "Run"}
};
ToggleMenuKit togglemenu = WidgetKits.makeToggleMenu(this.basecanvas, "Sub Menu",
null, 150, 40,
toptions, 2, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_RIGHT | CanvasGUI.TEXT_BOTTOM | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
togglemenu.parent.setLocation(400, 50);
togglemenu.parent.setSingleToggle(true);
for (int i = 0; i < togglemenu.options.length; i++) {
togglemenu.options[i].setImage(icons.getTextureImage(i).getImage());
}

CanvasPointer pointer = new CanvasPointer(this.guitexture.getImage());
pointer.setImageOffset(new Coordinate(0, 200));
pointer.setImagePart(new Dimension(64,64));
pointer.setSize(64, 64);
pointer.setLocation(-8, -20);
this.basecanvas.setPointer(pointer);

this.basecanvas.setBackImage(new BufferedImage(this.mainpanel.getWidth(), this.mainpanel.getHeight(),
BufferedImage.TYPE_INT_RGB));

this.guitexture.makeTexture();
this.barstexture.makeTexture();

this.mainpanel.setLocation(0, 0);
cpane.add(this.mainpanel);
this.mainpanel.alignBaseCanvas();

this.gui3d = WorldManager.createGUIWorld("GUI");

this.hud = new HUDManager();
this.eventhandler = new WorldEventHandler(this.mainpanel.getBuffer());
this.eventhandler.installFixer();

this.mainpanel.addEventHandler(this.eventhandler);
this.mainpanel.setCurrentEventHandlerGL(this.eventhandler);
this.mainpanel.setGUIWorld(this.gui3d);
this.mainpanel.setHUD(this.hud);

this.camera = new RadialCamera();
this.mainpanel.getWorld().setCameraTo(this.camera);
this.camera.setDistance(0.05f);
Camera linked = new Camera();
linked.setFOV(1.5f);
this.camera.setLinked(linked);
this.mainpanel.enableTopWorld(linked);

this.eventhandler.addWorld(this.gui3d);
this.eventhandler.addWorld(this.mainpanel.getWorld());

HUDTextureElement element = new HUDTextureElement("text", 0, 512, 1024, 256);
element.setTexture(this.guitexture, 0, 0, 1024, 200);
this.hud.add(element);

element = new HUDTextureElement("text2", 10, 548, 100, 200);
element.setTexture(this.guitexture, 0, 0, 1024, 200);
element.setZOrder(0);
element.setVisible(false);
this.hud.add(element);

HUDBarVerUp elementbar = new HUDBarVerUp("bars", 10, 680, 5, 100);
elementbar.setTexture(this.barstexture, 0, 0, 100, 512);
elementbar.setZOrder(5);
elementbar.setValue(1.0f);
this.hud.add(elementbar);

CanvasImageFont font = new CanvasImageFont(CanvasGUI.IMAGEFONT, 0.8f);

this.textlayer = new HUDTextLayer("text-layer", 0, 512, 1024, 256);
this.textlayer.setZOrder(1);
this.textlayer.setFont(font);
this.textlayer.setBorder(32);
this.hud.add(this.textlayer);

this.hud.zSort();

TextureSequence tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-dissolve.xml", HUDTest.texdir, null);
tseq.makeTexture();
tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-appear.xml", HUDTest.texdir, null);
tseq.makeTexture();
tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-grid-shine.xml", HUDTest.texdir, null);
tseq.makeTexture();

if(tseq != null) {
AnimatedBackground background = new AnimatedBackground("background", this.mainpanel.getCanvas());
background.setTexture(tseq);
background.setFullImage();
this.mainpanel.setBackgroundElement(background);
}

this.controller = GamePads.getController(0);
if (this.controller != null) {
this.controller.setEnabled(true);
System.out.println("Controller Enabled");
this.eventhandler.addController(this.controller);
this.canvashandler.addController(this.controller);
}

TextureImage concrete = TextureManagerEx.loadImageTexture("res/tex/concrete.jpg", "concrete", false, false);
concrete.makeTexture();
Object3DEx tobject = XMLLoader.loadObject("res/models/scene.obj", 1.75f);
if(tobject != null) {
tobject.setName("scene");
System.out.println("Got Scene");
tobject.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
tobject.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
tobject.rotateX((float)Math.toRadians(180.0));
tobject.setTexture("concrete");
tobject.build();
tobject.setSelectable(false);
this.mainpanel.getWorld().addObjectEx(tobject);
}


XMLLoader.loadXMLObjectCollection("res/xml/obj-hexes.xml", HUDTest.modelsdir, HUDTest.texdir, true, this.gui3d);
Object3DEx object = WorldManager.findObject(null, "hex-hor");
if(object != null) {
SelectorKit selectorkit = ElementKits.makeSelector(ElementKits.HEXAGONAL |
ElementKits.HORIZONTAL | ElementKits.OFFSETUP | ElementKits.EVENODD,
"Hex Menu", null, object, "Hex", 0.5f, 0.5f, 0.0f,
3, 3, this.gui3d, this.eventhandler);
if(selectorkit != null) {
GUIAnimator animator = new GUIAnimator();
animator.setRotationVectorY();
animator.setSpeed(0.025f);
animator.setRotationAngle((float)Math.toRadians(180.0f));

this.hextoggle = new GUIToggleBinding(null);
this.hextoggle.setAnimator(animator);
this.hextoggle.setElementArray(selectorkit.elements);
this.eventhandler.addEvent(this.hextoggle);

selectorkit.parent.translate(1.4f, -0.5f, 1.0f);
selectorkit.parent.rotateY((float)Math.toRadians(75.0));
selectorkit.parent.scale(0.125f);

TextureImage hex = TextureManagerEx.getImage(null, "hex-blank-hor");

TextureImage icon = icons.getTextureImage("icon-buffer");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-buffer-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[0].setTexture(tex.getName());
selectorkit.elements[0].flipUVVert();
tex.setOwner(selectorkit.elements[0]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-clone");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-clone-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[1].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[1]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-crash-bomb");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-crash-bomb-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[2].setTexture(tex.getName());
selectorkit.elements[2].flipUVVert();
tex.setOwner(selectorkit.elements[2]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-decode");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-decode-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[3].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[3]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-deflector");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-deflector-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[4].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[4]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-firewall");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-firewall-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[5].setTexture(tex.getName());
selectorkit.elements[5].flipUVVert();
tex.setOwner(selectorkit.elements[5]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-mask");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-mask-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[6].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[6]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-slicer");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-slicer-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[7].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[7]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-spy-bot");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-spy-bot-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[8].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[8]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-torrent");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-torrent-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[9].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[9]);
TextureManagerEx.addImage(tex);
}
}
}

GUIAnimator inanim = new GUIAnimator();
inanim.setTranslation(0.0f, 0.0f, -0.5f);
inanim.setSpeed(0.08f);

object = WorldManager.findObject(null, "panel-hex");
if(object != null) {
object.setRelativeRotationPivot(-1.0f, 0.0f, 0.0f);
SelectorKit selectorkit = ElementKits.makeMenuSelector("Panel Menu",
inanim, object, "Panel", 0.5f, 0.5f, 0.0f,
7, this.gui3d, this.eventhandler);
if(selectorkit != null) {
ToggleData toggledata = new ToggleData("Panel-0", this.hextoggle.getElementArray());
toggledata.states[0] = true;
toggledata.states[7] = true;
toggledata.states[8] = true;
this.hextoggle.setToggleSet(toggledata);

toggledata = new ToggleData("Panel-1", this.hextoggle.getElementArray());
toggledata.states[1] = true;
toggledata.states[4] = true;
toggledata.states[9] = true;
this.hextoggle.setToggleSet(toggledata);

GUISelectorBinding sevent = new GUISelectorBinding(null, selectorkit.selector);
sevent.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.YDIRECTION));
sevent.setController(this.controller);
sevent.setWorld(this.gui3d);
this.eventhandler.addEvent(sevent);

GUIAnimator animator = new GUIAnimator();
animator.setTranslation(0.075f, 0.0f, 0.0f);
animator.setSpeed(0.08f);
animator.setBounce(true);

GUISelectionBinding event = new GUISelectionBinding(null, selectorkit.selector);
event.setAnimator(animator);
event.setMouseEvent(new MouseBinding(EventBinding.MOUSE_CLICK, 1, 0, 1, 0));
event.setControllerEvent(new ControllerButtonBinding(false, 1));
event.setController(this.controller);
event.setKeyEvent(new KeyBinding('c', 0, EventBinding.KEY_TYPED));
event.setWorld(this.gui3d);
event.setHitCheck(true);
this.eventhandler.addEvent(event);

selectorkit.parent.translate(-1.8f, -0.3f, 1.0f);
selectorkit.parent.rotateY(-(float)Math.toRadians(75.0));
selectorkit.parent.scale(0.25f);

TextureImage hex = TextureManagerEx.getImage(null, "panel-hex-blank");
if(hex != null) {
LinkedTextureImage tex = new LinkedTextureImage(hex, "panel-hex-attack", true, true);
tex.printOnto(font, "Attack", 26, 210, false, false);
tex.printOnto(font, "Attack", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[0].setTexture(tex.getName());
selectorkit.elements[0].flipUVVert();
tex.setOwner(selectorkit.elements[0]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-defend", true, true);
tex.printOnto(font, "Defend", 26, 210, false, false);
tex.printOnto(font, "Defend", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[1].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[1]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-killer", true, true);
tex.printOnto(font, "Killer", 26, 210, false, false);
tex.printOnto(font, "Killer", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[2].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[2]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-slash", true, true);
tex.printOnto(font, "Slash", 26, 210, false, false);
tex.printOnto(font, "Slash", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[3].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[3]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-drain", true, true);
tex.printOnto(font, "Drain", 26, 210, false, false);
tex.printOnto(font, "Drain", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[4].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[4]);
TextureManagerEx.addImage(tex);
}
}
}

this.box = XMLLoader.loadObjectXML("res/xml/avat-shiva.xml", HUDTest.modelsdir, HUDTest.texdir);
this.box.averageCollisionXZ();
this.box.setCollisionMode(Object3D.COLLISION_CHECK_SELF);
this.box.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
this.mainpanel.getWorld().addObjectEx(this.box);

this.camera.setObject(this.box);
this.camera.setPullIn(false);
this.camera.setDistance(0.5f);
this.camera.cameraChangeAngle(0, 0, this.mainpanel.getWorld());

tobject = XMLLoader.loadObjectXML("res/xml/obj-pointer.xml", "res/models/", "res/tex/");
if(tobject != null) {
tobject.setSelectable(false);
this.mainpanel.getTopWorld().addObjectEx(tobject);

AnimatorStayWith animator = new AnimatorStayWith(tobject);
animator.offsetAboveTarget();
animator.setSpeed(1.0f);
animator.setCamera(this.camera);
animator.setMaxDistance(20.0f);
animator.setVisibility(false);
this.mainpanel.getWorld().addActor(new Actor("Pointer", tobject, animator, this.mainpanel.getWorld(), false));

WorldSelector selector = new WorldSelector(this.mainpanel.getWorld(), this.box, animator, 10.0f);
selector.setClickOnly(true);
selector.setMaxRange(20.0f);
this.eventhandler.addWorldSelector(selector);

WorldSelectionBinding event = new WorldSelectionBinding("Object-Click", selector);
event.setMouseWheel(true);
event.setKeyEvent(new KeyDualBinding('q', 'e', 0, EventBinding.KEY_TYPED));
event.setWorld(this.mainpanel.getWorld());
event.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.XDIRECTION));
event.setController(this.controller);
event.setHitCheck(true);
this.eventhandler.addEvent(event);
}


this.mainanimator = new AnimatorCharacter(this.box);
this.mainanimator.setCurrentMeshAnimation("stand", false);
this.mainanimator.setCallback(this);

this.mainactor = new ActorCameraFocal("Actor", this.camera, this.mainanimator, this.mainpanel.getWorld(), true);
this.mainactor.setTeam(0);
this.mainactor.setCollision(true);
this.mainactor.setBounds(new SimpleVector(30.0f, 150.0f, 20.0f));
this.mainactor.setChangeAnimation(true);
this.mainactor.setScale(0.5f);
this.mainactor.setPickable(true);
this.mainactor.setPausable(true);
this.camera.setLinkedActor(this.mainactor);
this.mainpanel.getWorld().addActor(this.mainactor);

this.mover = new ActorBinding(null, this.mainactor);
this.mover.setController(this.controller);
this.mover.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.LEFT));
this.mover.getControllerEvent().scale = 1.0f;
this.mover.setKeyEvent(new KeyQuadBinding(KeyEvent.VK_A, KeyEvent.VK_S, KeyEvent.VK_W, KeyEvent.VK_Z,
0, EventBinding.KEY_HOLD));
this.mover.getKeyEvent().scale = 0.5f;
this.mover.getKeyEvent().continual = false;
this.eventhandler.addEvent(this.mover);

ActorBinding abind = new ActorBinding(null, this.mainactor);
abind.setEffectLift(true);
abind.setController(this.controller);
abind.setControllerEvent(new Controller2ButtonBinding(true, 4, 5));
abind.getControllerEvent().scale = 0.2f;
abind.setMouseEvent(new MouseBinding(EventBinding.MOUSE_FULL_DRAG, 2, 0, 1, EventBinding.AXIS_Y));
abind.getMouseEvent().scale = -0.5f;
this.eventhandler.addEvent(abind);

RadialCameraBinding cevent = new RadialCameraBinding(null, this.camera);
cevent.setWorld(this.mainpanel.getWorld());
cevent.setController(this.controller);
cevent.setControllerEvent(new ControllerAxisBinding(true, ControllerBinding.RIGHT));
cevent.getControllerEvent().scale = 0.025f;
cevent.setMouseEvent(new MouseBinding(EventBinding.MOUSE_FULL_DRAG, 3, 0, 1, EventBinding.AXIS_BOTH));
cevent.getMouseEvent().scale = 0.05f;
this.eventhandler.addEvent(cevent);

EventBinding gevent = new EventBinding("Pause");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 9));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_P, 0, EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.eventhandler.addEvent(gevent);
this.canvashandler.addEvent(gevent);

gevent = new EventBinding("Canvas");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 3));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_ESCAPE, 0,
EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.eventhandler.addEvent(gevent);

CanvasBinding canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.BOTH));
canevent.setEffectPointer(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new Controller2ButtonBinding(false, 4, 5));
canevent.setNavigateWidgets(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerButtonBinding(false, 1));
canevent.setSimulateClick(true);
this.canvashandler.addEvent(canevent);

AmbientFull fogger = new AmbientFull(this.mainpanel.getWorld());
this.mainpanel.getWorld().setAmbient(fogger);
fogger.setLight(new ColorFloat(128,128,128), new ColorFloat(200,64,64), 0.001f);
fogger.setFogging(true);
fogger.setFogger(new ColorFloat(-255.0f,128.0f,-255.0f), new ColorFloat(-255.0f,-255.0f,-255.0f));
fogger.setFogRange1(20.0f, 40.0f);
fogger.setFogRange2(50.0f, 70.0f);

LightFlicker light = new LightFlicker(this.mainpanel.getWorld(), "red");
light.set(-3, -3, -3, 255, 0, 0, 30.0f, 5.0f);
light.setFlicker(new ColorFloat(255,0,0), new ColorFloat(255,255,0), 0.01f);

light = new LightFlicker(this.mainpanel.getWorld(), "blue");
light.set(-3, -3, 3, 255, 0, 0, 30.0f, 5.0f);
light.setFlicker(new ColorFloat(0,0,255), null, 0.025f);

this.mainpanel.getWorld().addLight("main", 0, -3, 0, 255, 255, 255, 30.0f, 5.0f);
// this.mainpanel.getWorld().createTriangleStrips();
// this.gui3d.createTriangleStrips();
// this.mainpanel.getTopWorld().createTriangleStrips();
}

public static void main(String[] args) {
HUDTest app = new HUDTest();
try {
app.loop();
} catch (Exception e) {
e.printStackTrace();
}
}

private void loop() throws Exception {
System.out.println("Looping");
if(!GamePads.isInitialized()) GamePads.initialize();
this.mainpanel.setRenderGL(true);
this.textlayer.addLine("Environment simulation loaded.");
this.textlayer.addLine("Avatar Shiva loaded.");
this.textlayer.addLine("Interface initiated.");
this.textlayer.addLine("Login in progress ...");
this.mainpanel.clearTimer();

while (this.isShowing()) {
while(this.eventhandler.hasCommands() || this.canvashandler.hasCommands()) {
String tcomm = "";
if(this.eventhandler.hasCommands()) tcomm = this.eventhandler.popCommand();
else if(this.canvashandler.hasCommands()) tcomm = this.canvashandler.popCommand();
System.out.println(tcomm);
this.textlayer.addLine(tcomm);

this.hextoggle.toggleCommand(tcomm);
if(tcomm.compareTo("Panel-2") == 0) {
this.mainanimator.setCurrentMeshAnimation("access", true);
}
if(tcomm.compareTo("Panel-3") == 0) {
this.mainanimator.setCurrentMeshAnimation("delete", true);
// AudioManager.pauseLoop(true);
}
if(tcomm.compareTo("Panel-4") == 0) {
TextureSequence seq = TextureManagerEx.getSequence("dissolve");
this.mainanimator.setTextureSequence(seq);
this.mainanimator.setCurrentMeshAnimation("dissolve", false);
// AudioManager.pauseLoop(false);
}
if(tcomm.compareTo("Panel-5") == 0) {
TextureSequence seq = TextureManagerEx.getSequence("appear");
this.mainanimator.setTextureSequence(seq);
this.mainanimator.setAnimateMesh(false);
this.mainanimator.setCurrentMeshAnimation("appear", true);
// AudioManager.playEffect(this.ping);
}
if(tcomm.compareTo("Panel-6") == 0) {
this.mainanimator.setCurrentMeshAnimation("failb", true);
}
if(tcomm.compareTo("Pause") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.setPaused(!this.mainpanel.isPaused());
this.mover.setEnabled(!this.mainpanel.isPaused());
} else {
this.mainpanel.setPaused(true);
this.mover.setEnabled(false);
this.mainpanel.setRenderGL(true);
}
}
if(tcomm.compareTo("Canvas") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.snapshot(this.basecanvas.getBackImage());
this.mainpanel.setRenderGL(false);
}
}
}
this.mainpanel.renderScene();
Thread.sleep(30);
}

System.out.println("Exiting!");
this.mainpanel.dispose();
this.eventhandler.removeFixer();
System.exit(0);
}

@Override
public boolean eventCall(int event, EventBinding binding) {
System.out.println("Callback!");
return true;
}

@Override
public void animateCallback(Animator animator, int event) {
if(animator == this.mainanimator) {
if(event == AnimatorCallback.TEXTURE_DONE) {
this.mainanimator.setAnimateMesh(true);
}
if(event == AnimatorCallback.MESH_DONE) {

}
}
}

}

I really suck with comments, so I don't actually put many inside my code itself, so sorry about that. Anyhow, this is the mucky way of making an app with the library, but it demonstrates (tests) a lot of the core methods and objects so that's why it's mucky instead of well done. A real app would be written much cleaner, but this is the one used for the screenshots.

An example XML file used, the avat-shiva.xml
Code: [Select]
<?xml version="1.0"?>
<base>
    <type>md2</type>
    <filename>avatars/shiva.md2</filename>
    <scale>1.0</scale>
    <object>
        <model name="Shiva-0_Shiva">
            <name>avatar-shiva</name>
            <setting name="EnvMap">false</setting>
            <setting name="Culling">true</setting>
            <setting name="Compile">true</setting>
            <setting name="Specular">true</setting>
            <setting name="Transparency">128</setting>
            <setting name="CollisionEllipse">1.0</setting>
            <setting name="Color">128,128,128</setting>
        </model>
        <animations>
            <sequence name="faila" cyclic="false">0.01</sequence>
            <sequence name="run" cyclic="true">0.01</sequence>
            <sequence name="appear" cyclic="false">0.01</sequence>
            <sequence name="scan" cyclic="true">0.005</sequence>
            <sequence name="walk" cyclic="true">0.005</sequence>
            <sequence name="access" cyclic="false">0.0075</sequence>
            <sequence name="failb" cyclic="false">0.01</sequence>
            <sequence name="stand" cyclic="true">0.005</sequence>
            <sequence name="dissolve" cyclic="false">0.02</sequence>
            <sequence name="delete" cyclic="false">0.02</sequence>
        </animations>
        <textures speed="0.05" usealpha="true">
            <sequence>shiva-ice</sequence>
            <texture index="0" maintain="false">
                <name>shiva-1</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00000.png</filename>
            </texture>
            <texture index="1" maintain="false">
                <name>shiva-2</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00001.png</filename>
            </texture>
            <texture index="2" maintain="false">
                <name>shiva-3</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00002.png</filename>
            </texture>
            <texture index="3" maintain="false">
                <name>shiva-4</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00003.png</filename>
            </texture>
            <texture index="4" maintain="false">
                <name>shiva-5</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00004.png</filename>
            </texture>
            <texture index="5" maintain="false">
                <name>shiva-6</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00005.png</filename>
            </texture>
            <texture index="6" maintain="false">
                <name>shiva-7</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00006.png</filename>
            </texture>
            <texture index="7" maintain="false">
                <name>shiva-8</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00007.png</filename>
            </texture>
            <texture index="8" maintain="false">
                <name>shiva-9</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00008.png</filename>
            </texture>
            <texture index="9" maintain="false">
                <name>shiva-10</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00009.png</filename>
            </texture>
            <texture index="10" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="11" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="12" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="13" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="14" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="15" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="16" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="17" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="18" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="19" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="20" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="21" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="22" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
        </textures>
    </object>
</base>
Title: Re: New Library And Game
Post by: KittenKoder on November 08, 2012, 12:17:51 pm
Just a quick update on the progress. I am almost happy with the arrangement and will hopefully be out of the experimental phase of development and have a real version to launch. Some of the actor, animation, and manipulation classes are still a bit of a mess though. Trying to make the semantics for the classes to be universal yet comprehensive, without weighing it down.

The current method is:

Actor: Controls the object in the world space, based on game needs. This merges objects with everything else, and is only needed for objects that interact in the world, static map like objects with no animations will not need this class.
Animator: Animated object animations based on time passed. Only needed for objects with animations or animated texture sequences.
Manipulator: Moves the objects or alters some of the object settings based on time passed.

Currently only one manipulator is installed per actor, I am debating multiple manipulators per actor, though manipulators can effect multiple objects or even be used in other classes effecting objects. The base manipulator is an interface, not a class, making it easier to extend hopefully. Considering a "wandering" actor, but I'm having a difficult time figuring out exactly how to work that without limiting it too much or making it too elaborate.
Title: Re: New Library And Game
Post by: KittenKoder on November 09, 2012, 04:12:04 pm
SNAFU, pretty big one. My method for texture management was too heavy on memory I think, either that or I'm swapping objects to the new class wrong, could be either. I need to sleep on it to figure it out but any ideas may be helpful if anyone has any. Currently to port an object3D into the new class I'm using super(object3D, true) to reuse mesh data, unsure if it holds the original when I do that or not, if it does then I may just need to fix that.

I do need to rework the textures+images system though, it's messy now that I look at it, and far from neat. I neglected a lot of problem areas through the experimental portion of development, and now seeing issues that will arise eventually. Heap stack keeps screaming at me and I think streamlining the textures will help prevent future problems there.
Title: Re: New Library And Game
Post by: EgonOlsen on November 09, 2012, 09:04:26 pm
Currently to port an object3D into the new class I'm using super(object3D, true) to reuse mesh data, unsure if it holds the original when I do that or not, if it does then I may just need to fix that.
...the "orginal" what is it supposed to hold? This constructor makes an Object3D share the mesh with another. If you use compile() on your objects, you might consider to use shareCompiledData() as well.
Title: Re: New Library And Game
Post by: KittenKoder on November 10, 2012, 10:58:41 am
Currently to port an object3D into the new class I'm using super(object3D, true) to reuse mesh data, unsure if it holds the original when I do that or not, if it does then I may just need to fix that.
...the "orginal" what is it supposed to hold? This constructor makes an Object3D share the mesh with another. If you use compile() on your objects, you might consider to use shareCompiledData() as well.

Well, i don't call compile until after the new one is made, I let the old Object3D die after I am finished with it. The point was if there was a reference to the original Object3D somewhere  that i am unaware of. On my end the object is only used to create the new object then it's gone. But the library needs the data that's in the extended Object3D to work efficiently.
Title: Re: New Library And Game
Post by: KittenKoder on November 10, 2012, 11:19:01 am
I may have figured out the error, which will need an overhaul of my original texture system. It seems that my image manager is likely causing the error. Possibly making too many textures, and I know I'm loading too many "dead" images that are only used for a moment in the test app.

The trick of it is that I need to maintain images of some textures, and not others, and some images don't get made into textures, so I'm still ironing out the specific techniques I want to use for this. I was thinking of using the iTextureEffect with the byte arrays for animated textures, though it would limit the variation with objects using the same animation it would improve memory consumption a lot.
Title: Re: New Library And Game
Post by: KittenKoder on November 11, 2012, 12:26:03 am
Alright, before I commit to a specific method, which would be harder on the CPU for texture animations:

1. Loading all the frames to the GPU then setting a different frame each "pass."

2. Using an ITextureEffect and updating the buffer directly each "pass."

A "pass" is when the frame actually changes.
Title: Re: New Library And Game
Post by: KittenKoder on November 13, 2012, 10:49:54 am
Slight change in plans, though not massive. I developed a pretty decent 3D GUI system, but the drain on the CPU due to collision checks and such with the mouse have made me choose to change gears a bit. Getting rid of the "picking" with the mouse completely, for the 3D GUI, most games use hotkeys for such things anyway so I'm probably just going too big. I am also going to put more focus on the HUD system, making it into a full GUI which will respond to the mouse. As it is I have to do something that will wind up abusing memory and queuing all the events in order to prevent some serious glitches when working cross threads, Swing's event system demands such and that's sort of the purpose of this library, to merge Swing with the GL rendering.

So to recap:

1. More focus on 2D HUD elements and interactions.
2. Elimination of 3D GUI object "picking."
3. A more refined event queue system.
4. A HUD system that's comprehensive and useful, as well as more GUI capable, that means event bindings and animations for the HUD elements themselves.

For those interested, I managed to iron out the texture system in a way that will actually benefit even small projects. Added a new object, the Scene object, which only tracks things that are unique to that scene allowing you to remove them easier and faster when changing scenes. Considering being rid of the 3D GUI completely, as cool as it looks, I want my library to be capable of operating on lower level machines than modern top of the line, the 2D HUD system can look not only as smooth, but also more like what people are used to for widgets anyway.

If there are any suggestions of ideas, please let me know, also any specific requests. I will hold onto the 3D GUI and maybe develop it further later on, but for now I prefer the 2D one.
Title: Re: New Library And Game
Post by: KittenKoder on November 17, 2012, 01:48:05 am
Alright, I got the Blender to Kitt jPCT engine scripts done, here's a scene exported from Blender to the engine.

(http://digitalnoisegraffiti.com/backups/hudtest-1.png)

(http://digitalnoisegraffiti.com/backups/hudtest-2.png)

The beams and the green ground have animated textures, the ground shimmers, the small beams look like blips flying through, and the big one looks freaking cool animated. lol
Title: Re: New Library And Game
Post by: KittenKoder on November 17, 2012, 11:27:52 pm
Quick update, the code for the above test app is now:

Code: [Select]
package app;

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import kitt.com.jpct.GameControls;
import kitt.com.jpct.XMLLoader;
import kitt.com.jpct.anim.Animator;
import kitt.com.jpct.anim.AnimatorCallback;
import kitt.com.jpct.event.CanvasEventHandler;
import kitt.com.jpct.event.Controller2ButtonBinding;
import kitt.com.jpct.event.ControllerAxisBinding;
import kitt.com.jpct.event.ControllerBinding;
import kitt.com.jpct.event.ControllerButtonBinding;
import kitt.com.jpct.event.EventHandler;
import kitt.com.jpct.event.KeyBinding;
import kitt.com.jpct.event.bind.CanvasBinding;
import kitt.com.jpct.event.bind.EventBinding;
import kitt.com.jpct.event.bind.EventBindingCallback;
import kitt.com.jpct.ext.GameWorld;
import kitt.com.jpct.ext.Object3DEx;
import kitt.com.jpct.ext.RadialCamera;
import kitt.com.jpct.game.ControllerData;
import kitt.com.jpct.game.GamePads;
import kitt.com.jpct.hud.HUDCellElement;
import kitt.com.jpct.hud.HUDElement;
import kitt.com.jpct.hud.HUDManager;
import kitt.com.jpct.hud.HUDTextLayer;
import kitt.com.jpct.hud.HUDTextureElement;
import kitt.com.jpct.hud.anim.HUDAnimator;
import kitt.com.jpct.hud.kits.HUDSelectorKit;
import kitt.com.jpct.scene.Scene;
import kitt.com.jpct.swing.GLPanel;
import kitt.com.jpct.swing.RenderCallback;
import kitt.com.jpct.tex.TextureEx;
import kitt.com.jpct.tex.TextureLabel;
import kitt.com.jpct.tex.TextureSequence;
import kitt.com.jpct.tex.TextureStored;
import kitt.com.jpct.tex.TextureSystem;
import kitt.com.math.Coordinate;
import kitt.com.math.Dimension;
import kitt.com.swing.Util;
import kitt.com.swing.canvas.CanvasButton;
import kitt.com.swing.canvas.CanvasGUI;
import kitt.com.swing.canvas.CanvasLabel;
import kitt.com.swing.canvas.CanvasPointer;
import kitt.com.swing.canvas.data.CanvasImageFont;
import kitt.com.swing.canvas.kits.MenuKit;
import kitt.com.swing.canvas.kits.ToggleMenuKit;
import kitt.com.swing.canvas.kits.WidgetKits;

import com.threed.jpct.Config;
import com.threed.jpct.Object3D;
import com.threed.jpct.Texture;

public class HUDTest extends JFrame implements EventBindingCallback, RenderCallback, AnimatorCallback {
private static final long serialVersionUID = 1L;

private static final String modelsdir = "res/models/";
private static final String texdir = "res/tex/";
    private static final String xmldir = "res/xml/";

private GLPanel mainpanel = null;
private HUDManager hud = null;
private TextureStored guitexture = null;
private TextureStored barstexture = null;
private RadialCamera camera = null;
private ControllerData controller = null;
private GameWorld gameworld = null;
// private File ping = null;

private Object3DEx box = null;
private CanvasEventHandler canvashandler = null;
private HUDTextLayer textlayer = null;
private CanvasImageFont font = null;

private CanvasGUI basecanvas = null;

private GameControls gamecontroller = null;

public HUDTest() throws HeadlessException {
this.setup();
}

private void setup() {
this.setTitle("HUD Test");
this.setBounds(0, 0, 256, 256);
this.setLocationRelativeTo(null);

this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.setResizable(false);
Container cpane = this.getContentPane();
cpane.setLayout(null);

this.setVisible(true);
Dimension dim = Util.getRealSize(this, 1024, 768);
Coordinate loc = Util.centerScreen(dim.width, dim.height);
this.setBounds(loc.x, loc.y, dim.width, dim.height);

// Config.isIndoor = true;
Config.tuneForOutdoor();
Config.doSorting = false;
Config.glFullscreen = false;
Config.glAvoidTextureCopies = true;
Config.glColorDepth = 24;
// Config.maxAnimationSubSequences = 10;
Config.farPlane = 100;
Config.glShadowZBias = 0.5f;
Config.saveMemory=true;
Config.maxTextureLayers = 2;
Config.maxPolysVisible = 20000;
Config.collideOffset = 1;
Config.glUseIgnorantBlits = true;
Config.autoBuild = true;
Config.lightMul = 5;
// Config.glTrilinear = true;

this.mainpanel = new GLPanel(1024, 768);
this.mainpanel.setRenderGL(false);
this.gameworld = this.mainpanel.getWorld();

// AudioManager.playLoop("res/audio/music/danosongs.com-bitbybits.ogg", -5.0f);
// this.ping = new File("res/audio/effects/ping.wav");

this.basecanvas = new CanvasGUI();
this.mainpanel.setBaseCanvas(this.basecanvas);
this.basecanvas.setBackground(new Color(0,128,128,128));
this.basecanvas.setForeground(new Color(64,255,255));
this.basecanvas.setName("Main Menu");
this.basecanvas.setFont(CanvasGUI.FONTLARGE);
this.basecanvas.setTextColor(Color.WHITE);

CanvasGUI.DEFAULT_DISABLED = new Color(255,0,0,128);
CanvasGUI.DEFAULT_HOVER = new Color(0,255,0,128);
CanvasGUI.DEFAULT_PRESSED = new Color(0,0,255,128);
CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,0);
CanvasGUI.DEFAULT_BACKGROUND = CanvasGUI.HALFBLACK;;

this.canvashandler = new CanvasEventHandler(this.basecanvas);
this.canvashandler.addTo(this.basecanvas);
this.mainpanel.setCurrentEventHandler(this.canvashandler);

this.basecanvas.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER);

this.guitexture = TextureSystem.loadStoredImage("res/tex/gui/base.png", "gui");
this.guitexture.makeTexture();
this.guitexture.addTexture();
this.barstexture = TextureSystem.loadStoredImage("res/tex/gui/bars-ver.png", "bars");
this.barstexture.makeTexture();
this.barstexture.addTexture();
TextureStored image = TextureSystem.loadStoredImage("res/tex/font-base.png", "font");
CanvasGUI.IMAGEFONT = new CanvasImageFont(image.getImage(), 32, 32);
CanvasGUI.IMAGEFONT.setBaseline(8);
CanvasGUI.IMAGEFONT.setAsciiOffset(32);
CanvasGUI.IMAGEFONT.setScale(0.5f);
TextureStored[] icons = XMLLoader.loadStoredPackFromXML("res/xml/texpack-icons.xml", HUDTest.texdir, null);
XMLLoader.loadStoredPackFromXML("res/xml/texpack-basic.xml", HUDTest.texdir, null);

image = TextureSystem.loadStoredImage("res/tex/icons/icon-logo-full.png", "icon-logo");
CanvasLabel label = new CanvasLabel(null, "Hacker's\nHaven", 100, 50, 100, 100);
label.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_LEFT | CanvasGUI.TEXT_TOP | CanvasGUI.IMAGE_STRETCH);
label.setImage(image.getImage());
this.basecanvas.addWidget(label);

CanvasButton button = new CanvasButton(null, "Pause", 0, 0, 100, 100);
button.setID("Pause");
this.basecanvas.addWidget(button);

String[][] options = {
{"GameStart", "Start"},
{"GameLoad", "Load"},
{"GameConfigure", "Settings"},
{"GameDelete", "Delete"},
{"GameExit", "Exit"}
};
MenuKit menu = WidgetKits.makeMenu(this.basecanvas, "Main Menu",
null, 150, 40,
options, 3, -1);
menu.parent.setLocation(200, 250);
menu.parent.setEnabled(false);

CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,255);

String[][] toptions = {
{"GameFun", "Fun"},
{"GameWicked", "Wicked"},
{"GameCool", "Cool"},
{"GameRun", "Run"}
};
ToggleMenuKit togglemenu = WidgetKits.makeToggleMenu(this.basecanvas, "Sub Menu",
null, 150, 40,
toptions, 2, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_RIGHT | CanvasGUI.TEXT_BOTTOM | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
togglemenu.parent.setLocation(400, 50);
togglemenu.parent.setSingleToggle(true);
for (int i = 0; i < togglemenu.options.length; i++) {
togglemenu.options[i].setImage(icons[i].getImage());
}

CanvasPointer pointer = new CanvasPointer(this.guitexture.getImage());
pointer.setImageOffset(new Coordinate(0, 200));
pointer.setImagePart(new Dimension(64,64));
pointer.setSize(64, 64);
pointer.setLocation(-8, -20);
this.basecanvas.setPointer(pointer);

this.basecanvas.setBackImage(new BufferedImage(this.mainpanel.getWidth(), this.mainpanel.getHeight(),
BufferedImage.TYPE_INT_RGB));

this.guitexture.makeTexture();
this.barstexture.makeTexture();

this.mainpanel.setLocation(0, 0);
cpane.add(this.mainpanel);
this.mainpanel.alignBaseCanvas();

this.gamecontroller = new GameControls(this.gameworld, this.mainpanel.getBuffer());
this.hud = this.gamecontroller.getHUD();
// EventHandler.installFixer();

this.mainpanel.addEventHandler(this.gamecontroller.getHandler());
this.mainpanel.setCurrentEventHandlerGL(this.gamecontroller.getHandler());
this.mainpanel.setHUD(this.hud);

this.controller = GamePads.getController(0);
if (this.controller != null) {
this.controller.setEnabled(true);
System.out.println("Controller Enabled");
this.gamecontroller.setControllerDevice(this.controller);
this.canvashandler.addController(this.controller);
}

this.camera = new RadialCamera();
this.gameworld.setCameraTo(this.camera);
this.camera.setDistance(0.05f);

HUDTextureElement element = new HUDTextureElement(null, "text", 0, 512, 1024, 256);
element.setTexture(this.guitexture.getTexture(), 0, 0, 1024, 200);
element.setZOrder(0);
this.hud.add(element);

this.font = new CanvasImageFont(CanvasGUI.IMAGEFONT, 0.8f);

this.textlayer = new HUDTextLayer(element, "text-layer", 0, 0, 1024, 256);
this.textlayer.setZOrder(1);
this.textlayer.setFont(font);
this.textlayer.setBorder(32);
this.textlayer.setZOrder(1);
this.hud.add(this.textlayer);

TextureStored tex = TextureSystem.findStoredImage(null, "hud-panel-option");
if(tex != null) tex.addTexture();

HUDSelectorKit selectorkit = HUDSelectorKit.makeMenuSelector(
HUDSelectorKit.CELLELEMENTS, "Menu", null, "Panel",
-200.0f, 50.0f, 256.0f, 32.0f, 10, this.hud, null, tex, 0, 0, 512, 64);
if(selectorkit != null) {
        HUDAnimator animator = new HUDAnimator();
        animator.setTranslation(200.0f, -8.0f);
        animator.setSpeed(0.025f);
        animator.setScale(1.0f, 1.5f);
       
            HUDAnimator select = new HUDAnimator();
            select.setSpeed(0.1f);
            select.setTranslation(0.0f, 10.0f);
            select.setBounce(true);

    this.gamecontroller.setHUDList(selectorkit.elements, animator, select);
   
for(HUDElement elem : selectorkit.elements) {
    TextureLabel ntex = new TextureLabel(tex, elem.getName());
    ntex.initializeCenters(2);
    ntex.getCenters()[0] = new Coordinate(256, 32);
                ntex.getCenters()[1] = new Coordinate(768, 32);
                ntex.setFont(this.font);
                ntex.setText(elem.getName());
                ntex.updateText();
                ntex.makeTexture();
                ntex.addTexture();
                TextureSystem.addStoredImage(ntex);
                ((HUDTextureElement)elem).setTexture(ntex.getTexture());
}
}

tex = TextureSystem.findStoredImage(null, "hud-icon-hex");
if(tex != null) tex.addTexture();
selectorkit = HUDSelectorKit.makeSelector(HUDSelectorKit.EVENODD | HUDSelectorKit.HEXAGONAL |
HUDSelectorKit.HORIZONTAL | HUDSelectorKit.OFFSETUP | HUDSelectorKit.CELLELEMENTS,
"Menu", null, "Hex",
800.0f, 50.0f, 80.0f, 80.0f, 3, 3, this.hud, null, tex, 0, 0, 128, 128);
if(selectorkit != null) {
String[] iconnames = {
"icon-buffer",
"icon-clone",
"icon-crash-bomb",
"icon-decode",
"icon-deflector",
"icon-firewall",
"icon-mask",
"icon-slicer",
"icon-spy-bot",
"icon-torrent"
};
for(int i = 0; i < iconnames.length; i++) {
TextureStored icontex = TextureSystem.findStoredImage(null, iconnames[i]);
if(icontex != null && tex != null) {
BufferedImage img = Util.cloneImage(tex.getImage());
Graphics2D g = (Graphics2D)img.getGraphics();
Util.quickPaint(g, icontex.getImage(), 0, 0, false, false);
Util.quickPaint(g, icontex.getImage(), 128, 0, false, false);
g.dispose();
TextureEx eltex = new TextureEx(null, "hex-" + iconnames[i], new Texture(img, true));
TextureSystem.addTexture(eltex);
eltex.addTexture();
System.out.println(eltex.getName());
((HUDCellElement)selectorkit.elements[i]).setTexture(eltex.getTexture());
if(i == (i/3)*3)
((HUDCellElement)selectorkit.elements[i]).setCell(1);
}
}
}

this.hud.zSort();

// TextureSequence tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-dissolve.xml", HUDTest.texdir, null);
// tseq.addTextures();
// tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-appear.xml", HUDTest.texdir, null);
// tseq.addTextures();
TextureSequence tanim = XMLLoader.loadSequenceFromXML("res/xml/texseq-barslide.xml", HUDTest.texdir, null);
tanim.addTextures();
// tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-grid-shine.xml", HUDTest.texdir, null);
// tseq.makeTexture();

// if(tseq != null) {
// AnimatedBackground background = new AnimatedBackground("background", this.mainpanel.getCanvas());
// background.setTexture(tseq);
// background.setFullImage();
// this.mainpanel.setBackgroundElement(background);
// }

Scene scene = XMLLoader.loadSceneFromXML("res/xml/scene-internet.xml", HUDTest.xmldir, HUDTest.modelsdir, HUDTest.texdir);
scene.setWorld(this.gameworld);
scene.setScene();

this.box = XMLLoader.loadObjectXML("res/xml/avat-shiva.xml", HUDTest.modelsdir, HUDTest.texdir);
this.box.averageCollisionXZ();
this.box.setCollisionMode(Object3D.COLLISION_CHECK_SELF);
this.box.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
        this.box.translate(scene.getSpawn("Logon"));
this.gameworld.addObjectEx(this.box);
this.gamecontroller.setPlayerObject(this.box);
        this.gamecontroller.getPlayerAnimator().setCurrentMeshAnimation("stand", false);

element = new HUDTextureElement(null, "Pointer", 0, 0, 32, 32);
element.setTexture(this.guitexture.getTexture(), 64, 200, 64, 64);
element.setVisible(true);
this.hud.add(element);
this.gamecontroller.setPointer(element);

EventBinding gevent = new EventBinding("Pause");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 9));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_P, 0, EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.gamecontroller.getHandler().addEvent(gevent);
this.canvashandler.addEvent(gevent);

gevent = new EventBinding("Canvas");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 3));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_ESCAPE, 0,
EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.gamecontroller.getHandler().addEvent(gevent);

CanvasBinding canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.BOTH));
canevent.setEffectPointer(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new Controller2ButtonBinding(false, 4, 5));
canevent.setNavigateWidgets(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerButtonBinding(false, 1));
canevent.setSimulateClick(true);
this.canvashandler.addEvent(canevent);

this.gamecontroller.enableControls();
}

public static void main(String[] args) {
HUDTest app = new HUDTest();
try {
app.loop();
} catch (Exception e) {
e.printStackTrace();
}
}

private void loop() throws Exception {
System.out.println("Looping");
if(!GamePads.isInitialized()) GamePads.initialize();
this.mainpanel.setRenderGL(true);
this.textlayer.addLine("Environment simulation loaded.");
this.textlayer.addLine("Avatar Shiva loaded.");
this.textlayer.addLine("Interface initiated.");
this.textlayer.addLine("Login in progress ...");
this.mainpanel.clearTimer();

while (this.isShowing()) {
while(this.gamecontroller.getHandler().hasCommands() || this.canvashandler.hasCommands()) {
String tcomm = "";
if(this.gamecontroller.getHandler().hasCommands()) tcomm = this.gamecontroller.getHandler().popCommand();
else if(this.canvashandler.hasCommands()) tcomm = this.canvashandler.popCommand();
System.out.println(tcomm);
this.textlayer.addLine(tcomm);

if(tcomm.compareTo("Panel-2") == 0) {
this.gamecontroller.getPlayerAnimator().setCurrentMeshAnimation("access", true);
}
if(tcomm.compareTo("Panel-3") == 0) {
this.gamecontroller.getPlayerAnimator().setCurrentMeshAnimation("delete", true);
// AudioManager.pauseLoop(true);
}
if(tcomm.compareTo("Panel-4") == 0) {
// AudioManager.pauseLoop(false);
}
if(tcomm.compareTo("Panel-5") == 0) {
this.gamecontroller.getPlayerAnimator().setCurrentMeshAnimation("appear", true);
// AudioManager.playEffect(this.ping);
}
if(tcomm.compareTo("Panel-6") == 0) {
this.gamecontroller.getPlayerAnimator().setCurrentMeshAnimation("failb", true);
}
if(tcomm.compareTo("Pause") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.setPaused(!this.mainpanel.isPaused());
this.gamecontroller.setPause(this.mainpanel.isPaused());
} else {
this.mainpanel.setRenderGL(true);
}
}
if(tcomm.compareTo("Canvas") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.snapshot(this.basecanvas.getBackImage());
                        this.mainpanel.setPaused(true);
                        this.gamecontroller.setPause(true);
this.mainpanel.setRenderGL(false);
}
}
}
this.mainpanel.renderScene();
Thread.sleep(30);
}

System.out.println("Exiting!");
this.mainpanel.dispose();
EventHandler.removeFixer();
System.exit(0);
}

@Override
public boolean eventCall(int event, EventBinding binding) {
System.out.println("Callback!");
return true;
}

@Override
public void animateCallback(Animator animator, int event) {
// if(animator == this.mainanimator) {
// if(event == AnimatorCallback.TEXTURE_DONE) {
// this.mainanimator.setAnimateMesh(true);
// }
// if(event == AnimatorCallback.MESH_DONE) {
//
// }
// }
}

@Override
public void renderCallback() {
// Called after each render.
}

}
Title: Re: New Library And Game
Post by: EgonOlsen on November 17, 2012, 11:42:23 pm
Looks very...tronish. I like it.
Title: Re: New Library And Game
Post by: KittenKoder on November 18, 2012, 01:18:08 am
Looks very...tronish. I like it.

Thank you, that's what I was hoping for. Going to put up the first official version of the library soon, just need to do a tax test on it to see where I need to tweak some things. It's actually turning out better than I had expected, but the game and the library. Thanks to your input, I think I have something that other people may just find useful.
Title: Re: New Library And Game
Post by: zbych on November 19, 2012, 10:43:55 pm
I like it already :D It reminds me my first project for Android: Trace_On
Title: Re: New Library And Game
Post by: KittenKoder on November 20, 2012, 03:41:11 pm
I like it already :D It reminds me my first project for Android: Trace_On

Cool. I have finally gotten the animation system refined, and the HUD style GUI can be interacted with the mouse and game controller, so the player can choose which they prefer. I just want to finish an animation system for the Canvas GUI before I release an official version of the library. The labels for the elements are actually a dynamic texture class I wrote, combining the TextureEffect interface and BufferedImage to create a "zone" label. That way a single texture can contain one label on top of multiple backgrounds, which can be switched out easily in the HUD elements without having to make too many calls to the hardware. The HUD elements are relatively simple, they're all buttons or dummies, using a parent system you can effect entire groups just by manipulating the parent. So both groups are actually parented to one element, to hide the entire group just hide the parent.

One thing I can't screenshot, the library even has a audio system as well, though it's dependent on Tritonus plugins because I'm too lazy to write my own.

For the actual game demo I will be making better models for the map, though Shiva was just a test model avatar, I'm going to keep it in the demo and likely the finished game because of how well it turned out. If I could save the animated version you'd see why I'm happy with the model.
Title: Re: New Library And Game
Post by: KittenKoder on November 22, 2012, 12:54:10 am
Alright, I have added a movie player to the canvas GUI system, It's lightweight but effective. It operates by playing a sequence of images from a jar. Pretty simple really.
Title: Re: New Library And Game
Post by: KittenKoder on November 23, 2012, 12:46:11 am
I know the wiki should be made after I actually test the library completely, but meh, the wiki is not just for this library anyway. Figure I may as well start making all my libraries available, under open source licensing, though really I'll just enforce a cc-By, since I prefer that license over all others. I call it honor-ware.  :P Basically, this is me taking my skill seriously finally, after so long.

Right now I am parking it on my other site, once I get some stuff added based on input from people who use the library, I'll purchase a new domain name for it.

http://digitalnoisegraffiti.com/wiki/
Title: Re: New Library And Game
Post by: KittenKoder on November 23, 2012, 07:24:31 am
Check these out, other than one tiny mistake I just corrected, these are actual GUI's created by my CanvasGUI system using only a few images. The hex in the background is an image widget, the green symbols in the the second one are all icon images, the rest is pure code, and only one way to make the widgets look.

(http://digitalnoisegraffiti.com/wiki/images/b/b2/Testgui-1.png)
(http://digitalnoisegraffiti.com/wiki/images/6/6e/Testgui-2.png)
Title: Re: New Library And Game
Post by: EgonOlsen on November 23, 2012, 08:34:12 pm
Nice. Is it still 3D based or more like 2D blits?
Title: Re: New Library And Game
Post by: KittenKoder on November 23, 2012, 10:04:33 pm
Nice. Is it still 3D based or more like 2D blits?

Those screencaps are from the CanvasGUI, it's pure Java painting. Though the difference between that and the in game HUD system is minimal. The HUD system, which doesn't have default textures but I could easily write them into it and will be doing so soon, is 2D blitting, and the textures I use are almost identical to the images you see here but using a dynamic texture for printing text or painting onto. I used the regular Swing Canvas for most of the menus because of how light weight it is, but the beauty of it is that the canvas itself can have a backdrop, such as a shot from the GL rendering in some of the earlier screencaps.

It is all animated as well, menus "slide" into and out of view, on both the Canvas and the HUD, by only using a few lines of code, one single animation class, and animation "data" classes. I had to use ArrayLists for animation tracking, which ate up some memory, but there's no telling how many animations will be happening at any given moment so it was a necessary evil. That specific GUI is created with the following code, of course I have added more to it since I made those screencaps:

Code: [Select]
package app;

import java.awt.Color;

import kitt.com.jpct.tex.TextureStored;
import kitt.com.swing.canvas.CanvasButton;
import kitt.com.swing.canvas.CanvasGUI;
import kitt.com.swing.canvas.CanvasLabel;
import kitt.com.swing.canvas.CanvasVideo;
import kitt.com.swing.canvas.CanvasWidget;
import kitt.com.swing.canvas.anim.CanvasAnimationData;
import kitt.com.swing.canvas.data.CanvasImageFont;
import kitt.com.swing.canvas.kits.MenuKit;
import kitt.com.swing.canvas.kits.ToggleMenuKit;
import kitt.com.swing.canvas.kits.WidgetKits;

public class CanvasGUISystem {
    public static final int MODE_CLEAR = 0;
    public static final int MODE_VIDEO = 1;
    public static final int MODE_MAIN = 2;
    public static final int MODE_STATUS = 3;
    public static final int MODE_MODES = 4;
    public static final int MODE_AVATAR = 5;
    public static final int MODE_SYSTEM = 6;
    public static final int MODE_FILES = 6;
   
   
    public static final int STATUS_AVATAR = 0;
    public static final int STATUS_THREADS = 1;
    public static final int STATUS_RAM = 2;
    public static final int STATUS_STORAGE = 3;
    public static final int STATUS_HARDENING = 4;
    public static final int STATUS_SPEED = 5;

    public static final int STATUS_USED_RAM = 6;
    public static final int STATUS_USED_STORAGE = 7;
    public static final int STATUS_USED_HARDENING = 8;
   
    public static final int STATUS_COUNT = 9;
   
    protected CanvasGUI canvas = null;
   
    protected MenuKit mainmenu = null;
    protected CanvasAnimationData mainmenuappear = null;
   
    protected MenuKit statusmenu = null;
    protected CanvasAnimationData statusmenuappear = null;
   
    protected ToggleMenuKit modelist = null;
    protected CanvasAnimationData modelistappear = null;
   
    protected ToggleMenuKit programlist = null;
    protected CanvasAnimationData programlistappear = null;
   
    protected ToggleMenuKit filelist = null;
    protected CanvasAnimationData filelistappear = null;
   
    protected MenuKit filemenu = null;
    protected CanvasAnimationData filemenuappear = null;
   
    protected CanvasWidget statusparent = null;
    protected CanvasLabel[] statusfields = null;
    protected CanvasAnimationData statusappear = null;
   
    protected CanvasLabel logo = null;
    protected CanvasAnimationData logoappear = null;
   
    protected CanvasVideo video = null;
   
    protected TextureStored[] icons = null;
    protected boolean[][] modestates = null;
    protected int currentmode = -1;
   
    protected Color availableprogram = new Color(0,255,255);
    protected Color unavailableprogram = new Color(255,255,0);
    protected Color foreground = new Color(0,255,0);
           
    protected int guimode = 0;
   
    public CanvasGUISystem(CanvasGUI canvas, TextureStored[] icons) {
        this.canvas = canvas;
        this.icons = icons;
       
        CanvasGUI.DEFAULT_DISABLED = new Color(255,0,0,128);
        CanvasGUI.DEFAULT_HOVER = new Color(0,255,0,128);
        CanvasGUI.DEFAULT_PRESSED = new Color(0,0,255,128);
        CanvasGUI.DEFAULT_FOREGROUND = this.foreground;
        CanvasGUI.DEFAULT_BACKGROUND = CanvasGUI.HALFBLACK;

        this.createGUI();
    }
   
    protected void createGUI() {
        this.createLogo();
        this.createMainMenu();
        this.createModeList();
        this.createProgramList();
        this.createStatusMenu();
        this.createStatus();
        this.createFileMenu();
        this.createFileList();
        this.modestates = new boolean[this.modelist.options.length - 1][];
        for(int i = 0; i < this.modestates.length; i++)
            this.modestates[i] = new boolean[this.programlist.options.length];

        CanvasButton button = new CanvasButton(null, "Return\nTo\nGame", 920, 689, 100, 75);
        button.setID("Option-5");
        this.canvas.addWidget(button);

        this.video = new CanvasVideo(null, 50, 50, 924, 668);
        this.video.setFlags(CanvasGUI.IMAGE_STRETCH | CanvasGUI.IMAGE_CENTER);
        this.video.setVisible(false);
        this.canvas.addWidget(this.video);

        this.canvas.sortWidgets();
    }
   
    protected void createLogo() {
        this.logo = new CanvasLabel(null, null, 262, 134, 500, 500);
        this.logo.setFlags(CanvasGUI.SHOWTEXT | CanvasGUI.TEXT_CENTER | CanvasGUI.TEXT_MIDDLE | CanvasGUI.IMAGE_STRETCH);
        this.logo.setZOrder(-1);
        this.logo.setImageFont(new CanvasImageFont(CanvasGUI.IMAGEFONT, 1.5f));
        this.logo.setName("Loading ...");
        for(TextureStored image : this.icons)
            if(image.getName().equals("icon-logo-full"))
                this.logo.setImage(image.getImage());
        this.canvas.addWidget(this.logo);
    }
   
    protected void createMainMenu() {
        CanvasGUI.DEFAULT_FOREGROUND = this.foreground;
        String[][] options = {
                {"Game-Start", "Start"},
                {"Game-Load", "Load"},
                {"Game-Configure", "Settings"},
                {"Game-Delete", "Delete"},
                {"Game-Quit", "Quit"}
            };
        this.mainmenu = WidgetKits.makeMenu(this.canvas, "MainMenu",
                null, 150, 40,
                options, 5, -1);
        this.mainmenu.parent.setLocation(512 - (this.mainmenu.parent.getSize().width / 2), 900);
        this.mainmenu.parent.setVisible(false);
        this.mainmenuappear = CanvasAnimationData.Create(0.0f, -200.0f, 0.05f, true);
    }
   
    protected void createStatusMenu() {
        CanvasGUI.DEFAULT_FOREGROUND = this.foreground;
        String[][] options = {
                {"Status-Play", "Return"},
                {"Status-Avatar", "Avatar"},
                {"Status-Programs", "Programs"},
                {"Status-Files", "Files"},
                {"Status-System", "System"},
                {"Status-Main", "Main Menu"}
            };
        this.statusmenu = WidgetKits.makeMenu(this.canvas, "MainMenu",
                null, 175, 40,
                options, 1, -1);
        this.statusmenu.parent.setLocation(-this.statusmenu.parent.getSize().width, 50);
        this.statusmenu.parent.setVisible(false);
        this.statusmenuappear = CanvasAnimationData.Create(50 + this.statusmenu.parent.getSize().width, 0.0f, 0.05f, true);
    }
   
    protected void createStatus() {
        CanvasGUI.DEFAULT_FOREGROUND = this.availableprogram;
        this.statusparent = new CanvasWidget(null, 100 + this.statusmenu.parent.getSize().width, -500, 500, 500);
        this.statusparent.setFlags(CanvasGUI.BORDER | CanvasGUI.FILL);
        this.statusparent.setBackground(CanvasGUI.HALFBLACK);
        this.statusparent.setForeground(new Color(128,255,128,128));
        this.statusparent.setVisible(false);
        this.canvas.addWidget(this.statusparent);
        this.statusappear = CanvasAnimationData.Create(0.0f, 550.0f, 0.05f, true);
       
        CanvasImageFont font = new CanvasImageFont(CanvasGUI.IMAGEFONT, 1.0f);
       
        CanvasLabel label = new CanvasLabel(this.statusparent, "Avatar:", 10, 10, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "Threads:", 10, 90, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "RAM:", 10, 130, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "/", 340, 130, 20, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_CENTER | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "Storage:", 10, 170, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "/", 340, 170, 20, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_CENTER | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "Hardening:", 10, 210, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "/", 340, 210, 20, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_CENTER | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        label = new CanvasLabel(this.statusparent, "Speed:", 10, 250, 230, 40);
        label.setImageFont(font);
        label.setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
        this.canvas.addWidget(label);
       
        this.statusfields = new CanvasLabel[CanvasGUISystem.STATUS_COUNT];
        for(int i = 0; i < CanvasGUISystem.STATUS_COUNT; i++) {
            if(i == 0) {
                this.statusfields[i] = new CanvasLabel(this.statusparent, "Shiva", 100, 50, 360, 40);
                this.statusfields[i].setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_RIGHT | CanvasGUI.SHOWTEXT);
            } else if(i < CanvasGUISystem.STATUS_USED_RAM) {
                this.statusfields[i] = new CanvasLabel(this.statusparent, "000", 240, 50 + (i * 40), 100, 40);
                this.statusfields[i].setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_RIGHT | CanvasGUI.SHOWTEXT);
            } else {
                this.statusfields[i] = new CanvasLabel(this.statusparent, "000", 360, 130 + ((i - CanvasGUISystem.STATUS_USED_RAM) * 40), 100, 40);
                this.statusfields[i].setFlags(CanvasGUI.TEXT_MIDDLE | CanvasGUI.TEXT_LEFT | CanvasGUI.SHOWTEXT);
            }
            this.statusfields[i].setImageFont(font);
            this.canvas.addWidget(this.statusfields[i]);
        }
    }

    protected void createProgramList() {
        CanvasGUI.DEFAULT_FOREGROUND = this.availableprogram;
       
        String[][] options = {
                {"Program-0", "Buffer"},
                {"Program-1", "Clone"},
                {"Program-2", "Crash Bomb"},
                {"Program-3", "Decode"},
                {"Program-4", "Deflector"},
                {"Program-5", "Firewall"},
                {"Program-6", "Mask"},
                {"Program-7", "Slicer"},
                {"Program-8", "Spy Bot"},
                {"Program-9", "Torrent"}
            };
        String[] iconname = {
                "icon-buffer",
                "icon-clone",
                "icon-crash-bomb",
                "icon-decode",
                "icon-deflector",
                "icon-firewall",
                "icon-mask",
                "icon-slicer",
                "icon-spy-bot",
                "icon-torrent"
            };
        this.programlist = WidgetKits.makeToggleMenu(this.canvas, "ProgramList",
                null, 200, 40,
                options, 2, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
                CanvasGUI.TEXT_RIGHT | CanvasGUI.TEXT_MIDDLE | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
        this.programlist.parent.setLocation(100 + this.modelist.parent.getSize().width, -this.programlist.parent.getSize().height);
        this.programlist.parent.setVisible(false);
        for (int i = 0; i < this.programlist.options.length; i++) {
            TextureStored icon = null;
            for(int ic = 0; ic < this.icons.length && icon == null; ic++)
                if(this.icons[ic].getName().equals(iconname[i]))
                    icon = this.icons[ic];
            if(icon != null)
                this.programlist.options[i].setImage(icon.getImage());
        }
        this.programlistappear = CanvasAnimationData.Create(0.0f, this.modelist.parent.getY() + this.programlist.parent.getSize().height, 0.05f, true);
    }
   
    protected void createFileList() {
        CanvasGUI.DEFAULT_FOREGROUND = this.availableprogram;
       
        String[][] options = new String[45][];
        for(int i = 0; i < options.length; i++) {
            options[i] = new String[2];
            options[i][0] = "File-" + i;
            options[i][1] = "File (" + (i * 10) + ")";
        }
        this.filelist = WidgetKits.makeToggleMenu(this.canvas, "FileList",
                null, 250, 40,
                options, 3, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
                CanvasGUI.TEXT_RIGHT | CanvasGUI.TEXT_MIDDLE | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
        this.filelist.parent.setLocation(100 + this.filemenu.parent.getSize().width, -this.filelist.parent.getSize().height);
        this.filelist.parent.setVisible(false);
        this.filelist.parent.setSingleToggle(true);
        this.filelistappear = CanvasAnimationData.Create(0.0f, this.filemenu.parent.getY() + this.filelist.parent.getSize().height, 0.05f, true);
    }

    protected void createModeList() {
        CanvasGUI.DEFAULT_FOREGROUND = this.foreground;
       
        String[][] options = {
                {"Mode-0", "Attacker"},
                {"Mode-1", "Defender"},
                {"Mode-2", "Stealth"},
                {"Mode-3", "Interrogator"},
                {"Mode-4", "Ripper"},
                {"Mode-5", "Tank"},
                {"Mode-6", "Worm"},
                {"Mode-7", "Balance"},
                {"Mode-8", "Spy Bot"},
                {"Mode-9", "Back"}
            };
        this.modelist = WidgetKits.makeToggleMenu(this.canvas, "ModeList",
                null, 150, 40,
                options, 1, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
                CanvasGUI.TEXT_CENTER | CanvasGUI.TEXT_MIDDLE | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
        this.modelist.parent.setLocation(-this.modelist.parent.getSize().width, 50);
        this.modelist.parent.setVisible(false);
        this.modelist.parent.setSingleToggle(true);
        this.modelistappear = CanvasAnimationData.Create(50.0f + this.modelist.parent.getSize().width, 0.0f, 0.05f, true);
    }
   
    protected void createFileMenu() {
        CanvasGUI.DEFAULT_FOREGROUND = this.foreground;
       
        String[][] options = {
                {"FileAct-PgUp", "< Page"},
                {"FileAct-PgDn", "Page >"},
                {"FileAct-View", "View"},
                {"FileAct-Delete", "Delete"},
                {"FileAct-Upload", "Upload"},
                {"FileAct-Back", "Back"}
            };
        this.filemenu = WidgetKits.makeMenu(this.canvas, "FileMenu",
                null, 150, 40,
                options, 1, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
                CanvasGUI.TEXT_CENTER | CanvasGUI.TEXT_MIDDLE | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
        this.filemenu.parent.setLocation(-this.filemenu.parent.getSize().width, 50);
        this.filemenu.parent.setVisible(false);
        this.filemenuappear = CanvasAnimationData.Create(50.0f + this.filemenu.parent.getSize().width, 0.0f, 0.05f, true);
    }

    public void mainMenu(String comm) {
        if(comm.equals("Game-Start")) {
            this.changeGUI(CanvasGUISystem.MODE_STATUS);
        } else if(comm.equals("Game-Load")) {
        } else if(comm.equals("Game-Delete")) {
        }       
    }
   
    public void fileMenu(String comm) {
        if(comm.equals("FileAct-View")) {
        } else if(comm.equals("FileAct-PgUp")) {
        } else if(comm.equals("FileAct-PgDn")) {
        } else if(comm.equals("FileAct-Delete")) {
        } else if(comm.equals("FileAct-Upload")) {
        } else if(comm.equals("FileAct-Back")) {
            this.changeGUI(CanvasGUISystem.MODE_STATUS);
            this.filelist.parent.allOffExcept(null);
        }       
    }
   
    public void statusMenu(String comm) {
        if(comm.equals("Status-Avatar")) {
        } else if(comm.equals("Status-Programs")) {
            this.changeGUI(CanvasGUISystem.MODE_MODES);
        } else if(comm.equals("Status-System")) {
//            this.changeGUI(CanvasGUISystem.MODE_SYSTEM);
        } else if(comm.equals("Status-Files")) {
            this.changeGUI(CanvasGUISystem.MODE_FILES);
        } else if(comm.equals("Status-Main")) {
            this.changeGUI(CanvasGUISystem.MODE_MAIN);
        }
    }
   
    public void updateGUI() {
        this.logo.setVisible(
                (this.guimode != CanvasGUISystem.MODE_VIDEO)
            );
        this.video.setVisible(
                (this.guimode == CanvasGUISystem.MODE_VIDEO)
            );
        if(this.guimode== CanvasGUISystem.MODE_CLEAR || this.guimode == CanvasGUISystem.MODE_VIDEO) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);
           
        } else if(this.guimode == CanvasGUISystem.MODE_FILES) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
           
            if(!this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, false);
            if(!this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, false);

        } else if(this.guimode == CanvasGUISystem.MODE_SYSTEM) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);
           
        } else if(this.guimode == CanvasGUISystem.MODE_MAIN) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);

            if(!this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, false);
           
        } else if(this.guimode == CanvasGUISystem.MODE_STATUS) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);
           
            if(!this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, false);
            if(!this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, false);
           
        } else if(this.guimode == CanvasGUISystem.MODE_AVATAR) {
            if(this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, true);
            if(this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);
           
        } else if(this.guimode == CanvasGUISystem.MODE_MODES) {
            if(!this.modelist.parent.isVisible())
                this.canvas.animate(this.modelist.parent, this.modelistappear, false);
            if(!this.programlist.parent.isVisible())
                this.canvas.animate(this.programlist.parent, this.programlistappear, false);
           
            if(this.filelist.parent.isVisible())
                this.canvas.animate(this.filelist.parent, this.filelistappear, true);
            if(this.filemenu.parent.isVisible())
                this.canvas.animate(this.filemenu.parent, this.filemenuappear, true);
            if(this.mainmenu.parent.isVisible())
                this.canvas.animate(this.mainmenu.parent, this.mainmenuappear, true);
            if(this.statusmenu.parent.isVisible())
                this.canvas.animate(this.statusmenu.parent, this.statusmenuappear, true);
            if(this.statusparent.isVisible())
                this.canvas.animate(this.statusparent, this.statusappear, true);
        }
    }
   
    public void changeGUI(int mode) {
        this.guimode = mode;
        this.updateGUI();
    }
   
    public void setLogo(String label) {
        this.logo.setName(label);
    }
   
    public void synchModeList(HUDSystem hud) {
        for(int i = 0; i < this.modelist.options.length; i++) {
            hud.setModeLabel("ModeSet-" + i, this.modelist.options[i].getName());
        }
    }
   
    public boolean[][] getModeStates() {
        return this.modestates;
    }
   
    public void setMode() {
        int modeindex = -1;
        for(int i = 0; i < this.modelist.options.length && modeindex == -1; i++)
            if(this.modelist.options[i].isToggled())
                modeindex = i;
        this.currentmode = modeindex;
        if(modeindex != -1) {
            if(modeindex == 9) {
                this.modelist.options[9].setToggled(false);
                this.changeGUI(CanvasGUISystem.MODE_STATUS);
            } else
                for(int i = 0; i < this.programlist.options.length; i++)
                    this.programlist.options[i].setToggled(this.modestates[modeindex][i]);
        }
    }
   
    public void setProgram(String name) {
        if(this.currentmode != -1) {
            int progindex = -1;
            for(int i = 0; i < this.programlist.options.length && progindex == -1; i++)
                if(this.programlist.options[i].getID().equals(name))
                    progindex = i;
            if(progindex != -1) {
                this.modestates[this.currentmode][progindex] = this.programlist.options[progindex].isToggled();
            }
        }
    }
   
    public void playMovie(String movie) {
        this.video.playMovie(movie);
        this.changeGUI(CanvasGUISystem.MODE_VIDEO);
    }
    public boolean isMovieDone() {
        return this.video.isDone();
    }
    public void endMovie() {
        if(this.video.isPlaying()) {
            this.video.endPlaying();
            this.changeGUI(CanvasGUISystem.MODE_STATUS);
        }
    }
    public void setMoviePause(boolean pause) {
        this.video.setPause(pause);
    }
}

Also, if you sign up for the wiki I have, I'll make you a contributor immediately since my game library depends a lot on jPCT.

I also figured out how to add texture "melting" to objects using the polygon manager. It's a pretty nifty effect, considering working on more such effects. It switches to a texture one polygon at a time based on the time passage, I'll post that class after I submit this.
Title: Re: New Library And Game
Post by: KittenKoder on November 23, 2012, 10:06:20 pm
The texture "melter" I mentioned, in case anyone wants a cool and simple idea for a special effect on models. The class it extends is first, then the actual melter.

Code: [Select]
package kitt.com.jpct.fx;

import kitt.com.jpct.ext.Object3DEx;

/**
 * Like the animator but more useful for special effect type animations that do not loop.
 * There is no management system for these, they are up to the program to manage. This
 * is due to their intended purpose of being simple effects on objects that do not require a
 * lot of updates.
 *
 * @author kitten
 *
 */
abstract public class ModelEffector {
    protected boolean animating = false;
    protected boolean done = false;
   
    /**
     * Should be set to null when finished animating to prevent holding a reference that may need to be removed.
     */
    protected Object3DEx object = null;
   
    /**
     * @return If there is a current animation in effect.
     */
    public boolean isAnimating() {
        return this.animating;
    }
   
    /**
     * This is a state check, once it's checked the state is cleared.
     *
     * @return If finished.
     */
    public boolean isDone() {
        if(this.done) {
            this.done = false;
            return true;
        }
        return false;
    }
   
    /**
     * @return the object
     */
    public Object3DEx getObject() {
        return object;
    }

    /**
     * @param object the object to set
     */
    public void setObject(Object3DEx object) {
        this.object = object;
    }

    /**
     * @param millis Time passed.
     * @return If still animating.
     */
    abstract public boolean tick(int millis);
}

Code: [Select]
package kitt.com.jpct.fx;

import kitt.com.jpct.ext.Object3DEx;

import com.threed.jpct.PolygonManager;

/**
 * Makes the model appear to melt between textures by changing one polygon at a time.
 *
 * @author kitten
 *
 */
public class ModelTextureMelt extends ModelEffector {
    protected int polys = 0;
    protected int textureid = 0;
    protected int index = 0;
    protected float speed = 4.0f;
    protected float step = 0.0f;
    protected PolygonManager manager = null;
   
    /**
     * @param textureid The texture ID to initialize with.
     */
    public ModelTextureMelt(int textureid) {
        this.textureid = textureid;
    }
   
    /**
     * @return the textureid
     */
    public int getTextureID() {
        return textureid;
    }

    /**
     * @param textureid the textureid to set
     */
    public void setTextureID(int textureid) {
        this.textureid = textureid;
    }

    /* (non-Javadoc)
     * @see kitt.com.jpct.fx.ModelEffector#setObject(kitt.com.jpct.ext.Object3DEx)
     */
    @Override
    public void setObject(Object3DEx object) {
        this.object = object;
        if(object != null) {
            this.manager = object.getPolygonManager();
            this.polys = this.manager.getMaxPolygonID();
            this.index = 0;
        }
    }
   
    /**
     * Triggers a repeat of the exact same animation if an object is set.
     */
    public void trigger() {
        if(this.object != null) {
            this.animating = true;
        }
    }
    /* (non-Javadoc)
     * @see kitt.com.jpct.fx.ModelEffector#tick(int)
     */
    @Override
    public boolean tick(int millis) {
        if(this.animating) {
            this.step += ((float)millis / 10.0f) * this.speed;
            while(this.step >= 1.0f && this.animating) {
                this.step -= 1.0f;
                this.manager.setPolygonTexture(this.index, this.textureid);
                this.index++;
                if(this.index >= this.polys) {
                    this.animating = false;
                    this.done = true;
                    this.index = 0;
                }
            }
        }
        return this.animating;
    }

}
Title: Re: New Library And Game
Post by: KittenKoder on November 27, 2012, 01:25:29 am
I knew I was going to forget something important prior to an official version. Well, I forgot the all important loading thread, with callable interface. Plus a more simple animation for the canvas, figured I may as well add it into the library since lots of games us lots of looped animations for things. It's similar to the movie widget, it loads the sequence of images from a jar file then displays them, the difference is that instead of the images being loaded "as needed" to conserve memory at the expense of smoothness, it loads all the frames at once. Other than that the two widgets are almost identical, just lightweight image painters.
Title: Re: New Library And Game
Post by: KittenKoder on November 28, 2012, 06:08:21 am
It's a huge image, but I have to show off. Now I'm getting serious about the game models:

(http://digitalnoisegraffiti.com/wiki/images/0/0f/Block-1.jpg)
Title: Re: New Library And Game
Post by: KittenKoder on November 29, 2012, 01:35:19 am
Two more:

(http://digitalnoisegraffiti.com/wiki/images/8/84/Internet-block-2.jpg)

(http://digitalnoisegraffiti.com/wiki/images/a/a4/Internet-block-3.jpg)