(三)
今天有时间了,就再写一点。
Fruite-machine严格上来说,只是一个排列高低分的游戏,并不是真正意义上的网络游戏,但是它也实现了网络游戏的一些简单的功能。
Fruite-machine虽然用了HTTP协议,却并不轮循服务器,而是通过callback的方式,向服务器端发送一个报文后,再接受一个报文处理。这样在真正的网络游戏中就容易产生问题,因为在真正的网络游戏中,服务器可能会主动的给一个玩家发送报文。而在fruite-machine中,服务器是无法给玩家主动的发送报文的,它只是在用户发送报文给服务器端时,再回调函数处理response,这样一应一答的报文传输方式。
严格意义上来说,在真正的网络游戏中采用HTTP协议只能采用轮循服务器的方式来解决服务器主动发送报文给某个客户端的问题。就是所谓的心跳报文。
下面我们来看看实现callback功能的程序:
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
/**
* This class accepts and queues POST requests for a particular URL, and
* services them in first-in-first-out order. Using the queue allows it
* to be thread-safe without forcing its clients ever to block.
*/
public class HttpPoster
implements Runnable
{
private String url;
private volatile boolean aborting = false;
private Vector requestQueue = new Vector();
private Vector listenerQueue = new Vector();
public HttpPoster(String url)
{
this.url = url;
Thread thread = new Thread(this);
thread.start();
}
public synchronized void sendRequest(String request,
HttpPosterListener listener)
throws IOException
{
requestQueue.addElement(request);
listenerQueue.addElement(listener);
notify(); // wake up sending thread
}
public void run()
{
running:
while (!aborting)
{
String request;
HttpPosterListener listener;
synchronized (this)
{
while (requestQueue.size() == 0)
{
try
{
wait(); // releases lock
}
catch (InterruptedException e)
{
}
if (aborting)
break running;
}
request = (String)(requestQueue.elementAt(0));
listener = (HttpPosterListener)(listenerQueue.elementAt(0));
requestQueue.removeElementAt(0);
listenerQueue.removeElementAt(0);
}
// sendRequest must have notified us
doSend(request, listener);
}
}
private void doSend(String request,
HttpPosterListener listener)
{
HttpConnection conn = null;
InputStream in = null;
OutputStream out = null;
String responseStr = null;
String errorStr = null;
boolean wasError = false;
try
{
conn = (HttpConnection)Connector.open(url);
// Set the request method and headers
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Length",Integer.toString(request.length()));
// Getting the output stream may flush the headers
out = conn.openOutputStream();
int requestLength = request.length();
for (int i = 0; i < requestLength; ++i)
{
out.write(request.charAt(i));
}
// Opening the InputStream will open the connection
// and read the HTTP headers. They are stored until
// requested.
in = conn.openInputStream();
// Get the length and process the data
StringBuffer responseBuf;
long length = conn.getLength();
if (length > 0)
{
responseBuf = new StringBuffer((int)length);
}
else
{
responseBuf = new StringBuffer(); // default length
}
int ch;
while ((ch = in.read()) != -1)
{
responseBuf.append((char)ch);
}
responseStr = responseBuf.toString();
// support URL rewriting for session handling
String rewrittenUrl = conn.getHeaderField("X-RewrittenURL");
if (rewrittenUrl != null)
{
url = rewrittenUrl; // use this new one in future
}
}
catch (IOException e)
{
wasError = true;
errorStr = e.getMessage();
}
catch (SecurityException e)
{
wasError = true;
errorStr = e.getMessage();
}
finally
{
if (in != null)
{
try
{
in.close();
}
catch (IOException e)
{
}
}
if (out != null)
{
try
{
out.close();
}
catch (IOException e)
{
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (IOException e)
listener.receiveHttpResponse(responseStr);
{
}
}
}
if (wasError)
{
listener.handleHttpError(errorStr);
}
else
{
listener.receiveHttpResponse(responseStr);
}
}
// This is just for tidying up - the instance is useless after it has
// been called
public void abort()
{
aborting = true;
synchronized (this)
{
notify(); // wake up our posting thread and kill it
}
}
}
从HttpPoster类中我们可以看出来:HttpPoster类采用单独的一个线程,只要调用HttpPoster类的sendRequest(String request,HttpPosterListener listener)方法,线程就会运行,然后调用doSend(String request, HttpPosterListener listener)方法来把request传送到服务器端。
注意listener.receiveHttpResponse(responseStr);这句程序回调HttpPosterListener的receiveHttpResponse(String response)方法,这里也运用了多态性,listener会根据相应实现的类调用相应类的receiveHttpResponse(String reponse)方法来处理服务器返回的报文。
今天先写到这,总之,HttpPoster这个类写的很不错,值得大家细细品位。包括体会多线程的wait(),notify()机制。
这个话题给大家深入的讲解一下this关键字及其主要的功能。
大凡初次接触程序设计的人,都会对this关键字的用法和含义不太清楚。
那么我在这篇文章就给大家深刻的分析一下它的含义和作用。
从字面意义上看:this是指自己,那么它在程序里面也指自身的一个实例了。其实从本质上来说它是java类里面自身的一个隐含指针,但是在实例产生之前,它不指向具体的内存,这点也可以在类里面用
System.out.println(this);
输出查看,会发现输出的为null。
它随着具体实例的产生而指向具体的实例,并在内存中为其分配相应的存储单元。
恩!
现在不知道你到底明白了this的用法没,说到底它是一个指针,指向自己。随着对象的产生而指向具体的对象实例,随着对象的消失而消失。
既然是对象,可想而知,this是用在面向对象的程序设计中的。
下面看看this的用法:
1:区分全局变量和局部变量
我们知道,如果一个函数里面有个局部变量和全局变量的名称和类型一样,那么全局变量对于这个方法来说就为不可见的。
如下:
public class Test{
int a,b;
public void change(int a,int b){
a = a;
b = b;
}
}
我们原本的意思是想通过change()方法改变全局变量a和b的值,但是因为这个时候名称冲突,全局变量对chang()方法来说为不可见,也就是覆盖了。
但是如果改成这样呢?
public void change(int a,int b){
this.a = a;
this.b = b;
}
从而编译器就知道了我们要通过change()方法改变a和b的值,你不要以为编译器很聪明。其实它很笨,在你的程序摸棱两可的时候,它就傻了,不知道该怎么处理了!
而this关键字明白的指出了我们要改变的是全局变量a和b的值。
2:在一些启动类里充当实例的角色
我们知道,MIDlet是J2ME的启动类。
编译器会自动启动它,因此我们无法来new一个MIDlet出来。编译器是不允许这样做的!
因为你这样一做,它就不知道到底该从那个启动了!我说过,编译器很笨的,你不要认为它很聪明。在很多情况下,它是糊涂的!
这个时候,我们唯一的办法就是在需要MIDlet对象实例的地方传入this关键字,在编译器启动并产生MIDlet实例的时候,相应的this指向这个产生的实例,从而可以操纵我们的MIDlet对象以及调用它的方法。
例如:
public class SpaceShooter extends MIDlet {
private GameCanvasgameCanvas;
public SpaceShooter() {
gameCanvas = new GameCanvas(this);//传入当前类的隐含指针,在MIDlet产生时传入,从而在GameCanvas里可以调用MIDlet的方法
Display.getDisplay(this).setCurrent(gameCanvas);
}
/** MIDlet开始时所调用的方法 */
protected void startApp() throws MIDletStateChangeException {
gameCanvas.doStartApp();
}
/** MIDlet暂停时所调用的方法 */
protected void pauseApp() {
gameCanvas.doPauseApp();
}
/** MIDlet结束时所调用的方法 */
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {}
/** 结束MIDlet时所调用的方法 */
void doExit() {
try {
destroyApp(false);
notifyDestroyed();
}catch(MIDletStateChangeException e) {}
}
}
相关推荐
【J2ME手机游戏开发论文】的焦点在于探讨Java 2 Micro Edition(J2ME)在移动设备,特别是手机游戏开发中的应用。J2ME是一种针对消费类电子产品,特别是移动通信设备的开发技术,它的核心优势在于“一次编写,到处...
《J2ME手机游戏案例精编电子教程》是一份深入探讨Java 2 Micro Edition (J2ME)在手机游戏开发中的应用的宝贵资源。J2ME是Java平台的一个子集,专为嵌入式设备,如早期的智能手机和平板电脑设计,它提供了开发移动...
**J2ME手机游戏开发毕业论文** Java 2 Micro Edition(J2ME)是Java平台的一个子集,专为资源有限的嵌入式设备,如早期的移动电话和掌上设备设计。它提供了开发和部署应用程序的框架,包括手机游戏。这篇毕业论文...
CLDC定义了基本的运行环境,而MIDP提供了用户界面组件和网络功能,是开发J2ME手机游戏的关键。 2. **MIDlet**:MIDlet是J2ME应用程序的基本单元,相当于Java应用程序中的主类。MIDlet类负责初始化、暂停、恢复和...
J2ME游戏通常受限于设备性能,因此游戏引擎需要优化图形渲染、内存管理和网络通信等功能,以适应低资源环境。 2.1.4 其他要求 游戏引擎还需要考虑兼容性问题,支持不同品牌和型号的手机,以及不同版本的J2ME平台。...
J2ME为移动设备提供了丰富的应用程序开发环境,尤其是在手机游戏领域,它曾经是开发手机游戏的主流技术之一。 在"J2ME手机游戏编程入门"这个主题中,我们主要会学习以下几个核心知识点: 1. **J2ME架构**:J2ME由...
**J2ME手机游戏开发基础教程** Java 2 Micro Edition(J2ME)是Java平台的一个子集,专为资源有限的嵌入式设备,包括早期的智能手机和平板电脑,设计用于开发移动应用程序,尤其是手机游戏。本教程将引导开发者入门...
**J2ME手机游戏开发详解** Java 2 Micro Edition(J2ME)是Java平台的一个子集,专门设计用于资源有限的设备,如移动电话、PDA和其他嵌入式系统。J2ME在手机游戏开发领域曾占据重要地位,尤其在功能手机时代,许多...
j2me手机浏览器通常基于MIDP,它包含了必要的API来构建用户界面,如ChoiceGroup和Form,以及实现网络通信,如HttpConnection。此外,早期的移动互联网服务往往使用WAP(Wireless Application Protocol)协议,因此,...
《手游公司的J2ME手机游戏框架详解》 Java Micro Edition(J2ME)是一种轻量级的Java平台,主要用于移动设备、嵌入式系统和其他资源有限的设备上。在手游领域,J2ME曾是开发早期手机游戏的主流技术之一。本文将深入...
《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》《J2ME手机游戏开发技术详解》...
本压缩包文件提供了J2ME手机游戏开发的技术详解源码,旨在帮助开发者深入理解J2ME游戏开发的过程,通过实际的代码示例进行学习和实践。 在J2ME手机游戏开发中,有几个核心知识点: 1. **MIDP (Mobile Information ...
**J2ME手机游戏开发技术与实践** J2ME(Java 2 Micro Edition)是Java平台的一个子集,专门用于嵌入式设备和移动设备,包括智能手机和平板电脑。在2000年代中期,J2ME是开发手机游戏的主流技术之一,尤其在诺基亚、...
而profiles则进一步定义了特定设备或应用领域的能力,如Mobile Information Device Profile (MIDP)专为移动设备设计,包含了用户界面组件和网络功能,是开发手机游戏的基础。 在J2ME中开发游戏,你需要掌握MIDP的...
**J2ME手机程序开发** Java 2 Micro Edition(J2ME)是Java平台的一个子集,主要用于嵌入式设备和移动设备,如早期的智能手机和平板电脑。它提供了开发和部署小型应用程序,称为MIDlets,的能力。J2ME在手机程序...
在J2ME平台上开发应用程序,可以实现丰富的功能,如游戏、通信应用、信息管理等。本文将深入探讨如何在NetBeans集成开发环境中利用J2ME实现一个手机电话本功能。 首先,我们需要了解J2ME的基础架构。J2ME由配置...