j2me商业手机游戏的技术及运作内幕!部分代码+Demo
我肯定来这里的朋友大部分都是做技术的,所以可以得出2个结论。第一,高品质商业手机游戏的内核对其据有很大吸引力。第二,相当多的程序员对技术了解多,对运作了解少,干了很多活,没拿多少钱。本来这些内容是我要保密的,但是我要讲出来,因为一个的原因——我有私事寻求帮助。不可否认我的动机,但是不论因为什么原因结识,我们有可能成为朋友或合作伙伴。
我打算按下面的顺序来说:
1.开发技术
2.商业运作
3.我写的ARPG游戏的demo下载
4.关于我和我寻求的帮助
一、游戏内核
我在学习j2me游戏编程的时候,在网上搜索了大量的资料,其中包括流传很广的《极品3D手机游戏开发过程全揭秘》(数位红自吹的广告)和《》(讲解太浅,完全属于最最最基础的内容基本上没有价值)。其实国内的高手不多,但也不少,只是没有人真正愿意把自己的开发经验和代码放出来砸自己的饭碗。我也如此,只是现在比不得以,所以讲部分出来。
先放一小段代码上来,再说说其他方面。
public class Core extends Canvas
implements Runnable , RecordFilter {
//////////////////////////////////////////////////////////////////
//Game core
//////////////////////////////////////////////////////////////////
//#ifndef Core.GameCanvas
//define constant to handle game key states
public static final int UP_PRESSED = 1 << UP;
public static final int DOWN_PRESSED = 1 << DOWN;
public static final int LEFT_PRESSED = 1 << LEFT;
public static final int RIGHT_PRESSED = 1 << RIGHT;
public static final int FIRE_PRESSED = 1 << FIRE;
public static final int GAME_A_PRESSED = 1 << GAME_A;
public static final int GAME_B_PRESSED = 1 << GAME_B;
public static final int GAME_C_PRESSED = 1 << GAME_C;
public static final int GAME_D_PRESSED = 1 << GAME_D;
//double buffer
private Image __bufferedImage;
//clip
private boolean __setClip;
private int __clipX, __clipY, __clipWidth, __clipHeight;
public void paint(Graphics g)
{
if (this.__setClip) {
g.clipRect( this.__clipX, this.__clipY, this.__clipWidth, this.__clipHeight);
this.__setClip = false;
}
g.drawImage(this.__bufferedImage, 0, 0, Graphics.TOP | Graphics.LEFT );
}
public void flushGraphics()
{
repaint();
serviceRepaints();
}
public void flushGraphics(int x, int y, int width, int height)
{
this.__setClip = true;
this.__clipX = x;
this.__clipY = y;
this.__clipWidth = width;
this.__clipHeight = height;
repaint();
serviceRepaints();
}
//#endif
//define constant to handle soft key states
public static final int SOFT_FIRST_PRESSED = GAME_A_PRESSED;
public static final int SOFT_LAST_PRESSED = GAME_B_PRESSED;
//MIDlet object
private MIDlet __midlet;
//key states and soft key states
private int __keyStates, __currentKeyStates, __lastKeyStates, __softKeyStates, __currentSoftKeyStates, __lastSoftKeyStates;
//used for sleep
private long __lastSystemTime, __elapsedTime;
//canvas Graphics object
private Graphics g;
//view window
private int viewX, viewY, viewWidth, viewHeight;
//running and pause flags
public boolean running = true;
public boolean pause;
//clock
private boolean clockRunning = true;
public long virtualTime;
//frame delay
private long frameDelay = 120;
//auto flushGraphics
public Core(MIDlet m) {
//#ifndef Core.GameCanvas
super();
//#else
//# super(false);
//# setFullScreenMode(true);
//#endif
//#ifdef Core.GameCanvas
this.viewWidth = getWidth();
this.viewHeight = getHeight();
//#else
//#if polish.FullCanvasSize:defined
//#= this.viewWidth = ${polish.FullCanvasWidth};
//#= this.viewHeight = ${polish.FullCanvasHeight};
//#else
//# this.viewWidth = getWidth();
//# this.viewHeight = getHeight();
//#endif
//#endif
//#ifndef Core.GameCanvas
this.__bufferedImage = Image.createImage(this.viewWidth, this.viewHeight );
this.g = this.__bufferedImage.getGraphics();
//#else
//# this.g = getGraphics();
//#endif
//midlet
this.__midlet = m;
}
protected void keyPressed(int keyCode) {
//#ifndef Core.GameCanvas
this.__keyStates |= 1 << getGameAction(keyCode);
//#endif
switch (keyCode) {
//#ifdef polish.key.LeftSoftKey
//# case ${polish.key.LeftSoftKey}:
//#else
case -6:
//#endif
this.__softKeyStates |= SOFT_FIRST_PRESSED;
break;
//#ifdef polish.key.RightSoftKey
//# case ${polish.key.RightSoftKey}:
//#else
case -7:
//#endif
this.__softKeyStates |= SOFT_LAST_PRESSED;
break;
}
}
protected void keyReleased(int keyCode) {
//#ifndef Core.GameCanvas
this.__keyStates &= ~(1 << getGameAction(keyCode));
//#endif
switch (keyCode) {
//#ifdef polish.key.LeftSoftKey
//# case ${polish.key.LeftSoftKey}:
//#else
case -6:
//#endif
this.__softKeyStates &= ~SOFT_FIRST_PRESSED;
break;
//#ifdef polish.key.RightSoftKey
//# case ${polish.key.RightSoftKey}:
//#else
case -7:
//#endif
this.__softKeyStates &= ~SOFT_LAST_PRESSED;
break;
}
}
/**
* detect user input
*
* @param keyPressedConstant
* XXX_PRESSED constant like FIRE_PRESSED
* @param detectsStroke
* set true to detect stroke action,false to detect key pressed
* state
* @param soft
* set true to detect soft key,false to detect game key.
* @param update
* set true to update key(soft key) state
* @return
*/
private final boolean detectInput(int keyPressedConstant, boolean detectsStroke,boolean soft,boolean update){
if(soft){
if(update){
this.__lastSoftKeyStates = this.__currentSoftKeyStates;
this.__currentSoftKeyStates = this.__softKeyStates;
}
if(detectsStroke){
return ((this.__lastSoftKeyStates & keyPressedConstant) != 0) && ((this.__softKeyStates & keyPressedConstant) == 0);
}else{
return ((this.__softKeyStates & keyPressedConstant) != 0);
}
}else{
if(update){
//#ifdef Core.GameCanvas
//# this.__keyStates = getKeyStates();
//#endif
this.__lastKeyStates = this.__currentKeyStates;
this.__currentKeyStates = this.__keyStates;
}
if(detectsStroke){
return ((this.__lastKeyStates & keyPressedConstant) != 0) && ((this.__keyStates & keyPressedConstant) == 0);
}else{
return ((this.__keyStates & keyPressedConstant) != 0);
}
}
}
//implements interface Runnable
public void run(){
try{
initialize();
while (running) {
this.__lastSystemTime = System.currentTimeMillis();
if(!pause){
//#ifndef Core.GameCanvas
this.g = this.__bufferedImage.getGraphics();
//#else
//# this.g = getGraphics();
//#endif
executeFrameTask();
if(clockRunning){
this.virtualTime += this.frameDelay;
}
}
this.__elapsedTime = System.currentTimeMillis() - this.__lastSystemTime;
if (this.__elapsedTime>0 && this.__elapsedTime < this.frameDelay) {
try{
Thread.sleep(this.frameDelay - this.__elapsedTime);
}catch(InterruptedException ie){}
}
//#mdebug benchmark
//# System.out.println("elapsed time: " + String.valueOf(this.__elapsedTime) +
//# " (" + String.valueOf(this.__elapsedTime*100/this.frameDelay) + "%)");
//#enddebug
}
this.__midlet.notifyDestroyed();
//#mdebug info
//# System.out.println("game stop normally.");
//#enddebug
}catch(Exception e){
//#mdebug fatal
//# System.out.println("a fatal error occured.");
//# e.printStackTrace();
//#enddebug
showSystemHint(Locale.get("Game.SystemError"));
this.__midlet.notifyDestroyed();
}
}
//略……
}