Hello there, I've been developing a 2D turn-based fighting game called THE SCND GENESIS:Legends in Java. Its story is based on my web-comic
http://scndgen.sourceforge.net. Its not out yet but development is proceeding smoothly. Though I'ld like to discuss some stuff with you guys

Firstly graphics. I love polygons as much as the next guy, but 3D has it's pitfalls. I t adds an extra dimension, no pun intended, of complexity. I believe more developers should give good old 2D a spin before going 3D. Commercial games like Muramasa: The Demon Blade (Wii) and Blaz Blue (HD Consoles) show that 2D games still have the ability to be visually spectacular. Here are some screens:






What do you think, several stages and characters aren't published but that should give you a general "feel" of its look. More screens are available on the site
http://scndgen.sourceforge.net/game.htmlPerformance. The game uses Java2D and Volatile Image, no fancy JOGL, Slick, LWJGL here >_<. Buffered Image was crazily slow, so I use standard images. Initially I had lame performance, but that's because I was drawing and filling several arcs, rectangles and polygons *facepalm*. After replacing them with static Images, performance became great. It uses 75% of a Celeron M 1.4GHz in Windows Vista. On my Pentium E2180, I get 13 % CPU utilisation, and 124 MB RAM usage on average. Trust me, that's A LOT better than before.
Multiplayer. The game already works on LAN. It has a lobby/matchmaking system that's fairly decent. The host machine acts as a server and the other as a client. Performance is great, no latency or anything. I've already created an online server and tested it numerously on local host, works good. But I havn't been able to do find any free online hosting (hey, I'm a student, and broke). Could you suggest some sites.
Lastly, Licensing. I want this game to have a Licence like that of Warsow. The code/engine shall be free to edit. But the art, story and other intellectual property related to my web-comic belongs to me. ow do I go around that. I want this game to be freely available, but I don't want my characters and Story to be changed by random people................................................................................SNAP!!!! I had an idea. Since its open source, the characters are mine, but people get a basic plot premise and create their own episodes...or outcomes. They could be combined to one game to make some kinda Mass Effect 2 conversation reel, multiple outcome thing *brain stromz*.
Oh well, that's it. Heres the code from my drawGame class, which renders graphics. It'll give you an idea of how the game is structured. Please comment and makes suggestions.
Code:
@Override
public void paintComponent(Graphics g)
{
/*
//----- Software DoubleBuffering -----// 67% cpu utilisation in ubuntu 10.4 / sun jre 6_21 / Pentium E2180 / 1GB Radeon 5670HD / 1.5GB RAM
Dimension currentSize=getSize();
if (offScreenImage == null || !currentSize.equals(offScreenDimension))
{
offScreenImage=createImage(currentSize.gameWidth,currentSize.gameHeight);
g2d=(Graphics2D)offScreenImage.getGraphics();
offScreenDimension=currentSize;
}
//----- Software DoubleBuffering -----// */
//----- hardware doublebuffer ------// 55% cpu usage in ubuntu 10.4 / sun jre 6_21 / Pentium E2180 / 1GB Radeon 5670HD / 1.5GB RAM
/* Fixed performance issues, got rid of geometry and replaced with static images -----facepalm*/
//
//super.paintComponent(g);
//createSoftBackBuffer();
createBackBuffer();
if (threadGameInstance.isGameOver==false && threadGameInstance.story==true)
{
g2d.setColor(Color.BLACK);
g2d.fillRect(0,0,gameWidth,gameHeight);
g2d.setComposite(makeComposite(opacityPic * 0.1F));
g2d.drawImage(storyPic,0,0,this);
g2d.setComposite(makeComposite(10*0.1F));
g2d.setComposite(makeComposite(5 * 0.1F));
g2d.fillRoundRect(0,424,gameWidth,48,48,48); //mid minus half the font size (430-6)
g2d.setComposite(makeComposite(10 * 0.1F));
g2d.setColor(Color.WHITE);
g2d.drawString("Press Enter to skip >>",680, 462);
g2d.setComposite(makeComposite(opacityTxt * 0.1F));
g2d.drawImage(charPort, 425-50-((battleInf.length()/2)*6), 424, this);
g2d.drawString(battleInf.toString(),425-((battleInf.length()/2)*6),450);
g2d.setComposite(makeComposite(10*0.1F));
}
if (threadGameInstance.isGameOver==false && threadGameInstance.story==false)
{
//g2d.translate(185.0, 185.0);
g2d.drawImage(bgPic,0, 0, this);
g2d.setFont(notSelected);
// draws char 1 sprite and lifeBar
if(menuGameRender.getCharLife()>=0)
{
if(animLayer.equalsIgnoreCase("back"))
{
g2d.drawImage(ambient1, amb1x, amb1y, this);
g2d.drawImage(ambient2, amb2x, amb2y, this);
}
if(attacksPlyr.isOverlayDisabled()==true)
{
g2d.drawImage(assSprite, charXcord+10, charYcord+15, this);
//g2d.drawImage(charSpec, charXcord+10, charYcord+15, this);
g2d.drawImage(charMeleeSprite, charXcord, charYcord, this);
}// character sprite on top of opp
g2d.drawImage(assOppSprite,gameWidth,oppYcord-15,oppXcord-10,gameHeight,oppYcord-15,oppXcord-10,gameWidth,gameHeight,this);
g2d.drawImage(oppMeleeSprite,gameWidth,oppYcord,oppXcord,gameHeight,oppYcord,oppXcord,gameWidth,gameHeight,this);
// opponent sprite
if(attacksPlyr.isOverlayDisabled()==false)
{
g2d.drawImage(assSprite, charXcord+10, charYcord+15, this);
// g2d.drawImage(charSpec, charXcord+10, charYcord+15, this);
g2d.drawImage(charMeleeSprite, charXcord, charYcord, this);
}
if(animLayer.equalsIgnoreCase("forg"))
{
g2d.drawImage(ambient1, amb1x, amb1y, this);
g2d.drawImage(ambient2, amb2x, amb2y, this);
}
// character sprite on below, opponent on top
// "Java Tip 32: You'll flip over Java images -- literally! - JavaWorld"
// http://www.javaworld.com/javaworld/javatips/jw-javatip32.html?page=2
if((menuGameRender.getCharLife()/menuGameRender.getCharMaxLife())<0.66)
{
damOpInc=6.66-((menuGameRender.getCharLife()/menuGameRender.getCharMaxLife())*10);
//BACK to transparency
}
if(specialEffect)
{
g2d.drawImage(foreGround,fgx,fgy,this);
}
g2d.setComposite(makeComposite((Float.parseFloat(""+damOpInc))*0.1f));
g2d.drawImage(damLayer,0,0, this);
g2d.setComposite(makeComposite(10*0.1f));
g2d.drawImage(menuHold,0,360,this);
//g2d.setColor(colors.getColor("blue"));
//g2d.drawRect(5,440,290,10);
//g2d.fillRect(5,440,(int)Math.round(characters.getPoints()*290),10);
for(int x=0; x<4; x++)
{
g2d.drawImage(quePic1,(x*70+5),440,this);
}
if(menuGameRender.comboCounter>=1)
{
for(int x=0; x<menuGameRender.comboCounter; x++)
{
g2d.drawImage(quePic2,(x*70+5),440,this);
}
}
g2d.drawImage(hpHolder,45+62+x2, (y+4+y2),this); // HOLDS hp
g2d.setColor(Color.WHITE);
g2d.drawString("HP: "+Math.round(menuGameRender.getOppLife())+" : "+menuGameRender.perCent2+"%", 55+64+x2,18+y2);
/*
g2d.setComposite(makeComposite(10*0.1F));//back to normal
}
}
*/
//if(menuGameRender.getOppLife()>=0)
//{
// g2d.setPaint(gradient2);
// g2d.fillRoundRect(64+x2, (y+2+y2), fLife-perCent2,5,5,5);
//}
//if(menuGameRender.getOppLife()<0)
//{
// g2d.setColor(Color.BLACK);
// g2d.fillRect(64+x2, y+y2, fLife-perCent2, 5);
//}
//opp damage pix
g2d.setComposite(makeComposite(numberOpac* 0.1F));
g2d.drawImage(figGuiSrc1,600,y2-180,this);
g2d.drawImage(figGuiSrc2,600+(spacer*1),y2-180, this);
g2d.drawImage(figGuiSrc3,600+(spacer*2),y2-180, this);
g2d.drawImage(figGuiSrc4,600+(spacer*3),y2-180, this);
//char damage pix
g2d.drawImage(figGuiSrc10,300,lby2-180, this);
g2d.drawImage(figGuiSrc20,300+(spacer*1),lby2-180, this);
g2d.drawImage(figGuiSrc30,300+(spacer*2),lby2-180, this);
g2d.drawImage(figGuiSrc40,300+(spacer*3),lby2-180, this);
g2d.setComposite(makeComposite(10 * 0.1F));
//-----------draws battle info messages--------------
//g2d.setColor(Color.BLACK);
//g2d.drawImage(infoPic,x, InfoBarYPose, this);
g2d.setComposite(makeComposite(opacityTxt * 0.1F));
g2d.setColor(Color.WHITE);
g2d.drawString(battleInf.toString(), 32, InfoBarYPose+YOffset);
g2d.setComposite(makeComposite(10*0.1F));
//-----------draws battle info messages--------------
//---opponrnt activity bar + text
g2d.setColor(Color.BLACK);
//g2d.fillRoundRect(x2-20, y2+18, 300, 15, 15, 15);
g2d.drawImage(oppBar,x2-20, y2+18,this);
g2d.setPaint(gradient1);
g2d.fillRoundRect(x2-17, y2+22, threadGameInstance.getRecoveryUnitsOpp(), 6, 6, 6);
//------------player 1 HUD---------------------//
//g2d.shear(0.25, 0.1);
g2d.drawImage(hpHolder,lbx2-438, lby2-410,this); // HOLDS hp
//outline
g2d.drawImage(hud1,lbx2-498, lby2-417,this);
//inner
g2d.setPaint(gradient3);
g2d.fillArc(lbx2-493, lby2-412, 90, 90, 0, phyAngle());
//inner loop
g2d.setColor(Color.BLACK);
g2d.drawImage(hud2,lbx2-488, lby2-407,this);
/**
g2d.setColor(Color.BLUE);
g2d.fillArc(lbx2-483, lby2-402, 70, 70, 0, phyAngle());
//inner loop
g2d.setColor(Color.BLACK);
g2d.fillArc(lbx2-478, lby2-397, 60, 60, 0, 360);
//
g2d.setColor(Color.GREEN);
g2d.fillArc(lbx2-472, lby2-392, 50, 50, 0, phyAngle());
//inner loop
g2d.setColor(Color.BLACK);
g2d.fillArc(lbx2-467, lby2-387, 40, 40, 0, 360);
//g2d.drawImage(charSprites[12], lbx2-487, lby2-406, this);
*/
{
g2d.setColor(Color.WHITE);
g2d.drawString("HP: "+Math.round(menuGameRender.getCharLife())+" : "+menuGameRender.perCent+"%",(lbx2-416),(lby2-398));
g2d.setComposite(makeComposite(10*0.1F)); //op back to normal for other drawings
}
}
//if(menuGameRender.getCharLife()>=0)
//{
// g2d.setPaint(gradient2);
// g2d.fillRoundRect((lbx2-436),(lby2-415), fLife-perCent, 5,5,5);
//}
//----------fps counter------------------
g2d.setColor(Color.black);
g2d.drawString("fps: "+fpsIntStat,800,10);
//-----------time area----------------
g2d.drawImage(counterPane,306,0,this);
if(threadGameInstance.time>180)
{
//infinity
g2d.drawImage(numberPix[11],381,0,this);
}
else
{
g2d.drawImage(times[threadGameInstance.time1],336+28,0,this);
g2d.drawImage(times[threadGameInstance.time2],336+28+28,0,this);
g2d.drawImage(times[threadGameInstance.time3],336+28+28+28,0,this);
}
{
g2d.setComposite(makeComposite(opac*0.1F));
g2d.setColor(CurrentColor);
g2d.drawImage(curr,215,360,this);
item1=new Font("SansSerif", Font.PLAIN, fontSizes[0]);
g2d.setFont(item1);
g2d.drawString(currentColumn[0],yTEST,366+fontSizes[0]);
item2=new Font("SansSerif", Font.PLAIN, fontSizes[1]);
g2d.setFont(item2);
g2d.drawString(currentColumn[1],yTEST,366+fontSizes[0]+2+fontSizes[1]);
item3=new Font("SansSerif", Font.PLAIN, fontSizes[2]);
g2d.setFont(item3);
g2d.drawString(currentColumn[2],yTEST,366+fontSizes[0]+2+fontSizes[1]+2+fontSizes[2]);
item4=new Font("SansSerif", Font.PLAIN, fontSizes[3]);
g2d.setFont(item4);
g2d.drawString(currentColumn[3],yTEST,366+fontSizes[0]+2+fontSizes[1]+2+fontSizes[2]+2+fontSizes[3]);
g2d.setComposite(makeComposite(10*0.1F));
}
//limit break stuff
g2d.drawImage(fury, 20, 190, this);
//g2d.setColor(Color.BLACK);
//g2d.fillRoundRect(10,130,16,204,16,16);
g2d.drawImage(furyBar,10,130,this);
g2d.setColor(Color.RED);
g2d.fillRoundRect(12,132,12,menuGameRender.getBreak()/5,12,12);
//status layer
g2d.setComposite(makeComposite(statusOpac*0.1F));
g2d.setFont(statusFont);
g2d.setColor(charStatColor);
g2d.drawString(statusChar,lbx2-350,100);
g2d.setColor(oppStatColor);
g2d.drawString(statusOpp,x2-10,100);
g2d.setComposite(makeComposite(10*0.1F));
g2d.setFont(notSelected);
}
//-----------ENDS ATTACKS QUEING UP--------------
//when paused
if (threadGameInstance.isPaused==true)
{
g2d.setColor(Color.BLACK);
g2d.setComposite(makeComposite(5*0.1F));//initial val between 1 and 10
g2d.fillRect(0,0, gameWidth, gameHeight);
g2d.setComposite(makeComposite(10*0.1F));
g2d.setColor(Color.WHITE);
g2d.drawString("Paused",400,240);
}
//when gameover
if (threadGameInstance.isGameOver==true)
{
g2d.setColor(Color.WHITE);
g2d.fillRect(0,0, gameWidth, gameHeight);
g2d.setColor(Color.BLACK);
g2d.setComposite(makeComposite(8*0.1F));//initial val between 1 and 10
g2d.fillRect(0,210, gameWidth, 121);
g2d.setComposite(makeComposite(10*0.1F));
g2d.drawImage(status,0,210,this);
g2d.setColor(Color.WHITE);
g2d.setFont(notSelected);
g2d.drawString(ach1,400,240); //+14
g2d.drawString(ach2,400,254);
g2d.drawString(ach3,400,268);
g2d.drawString(ach4,400,282);
g2d.drawString("<< press ENTER to proceed >>",400,296);
}
//--------------------STUF HERE IS ABOVE ALL----------------------
//------------notification area------
g2d.setColor(Color.black);
//bar 50% trans
g2d.setComposite(makeComposite((sysNotOpac/2)*0.1F));
g2d.fillRoundRect((835-14-(sysNot.length()*7)), 35, 14+(sysNot.length()*8), 20, 10, 10);
//text 100% trans
g2d.setComposite(makeComposite(sysNotOpac*0.1F));
g2d.setColor(Color.white);
g2d.drawImage(notPic,(840-14-(sysNot.length()*7)), 38,this);
g2d.drawString(sysNot,(840-(sysNot.length()*7)), 50);
g2d.setComposite(makeComposite(10*0.1F));
//--------------------------------VOLATILE BACK BUFFER -----------//
g.drawImage(volatileImg,0, 0, this);
//g.dispose();
//g2d.dispose();
}