Torque2D MIT 2.0 自2013年2月份开始正式公开,源代码可以下载供广大程序猿学习,使用.
官方: http://www.garagegames.com/products/torque-2d
GitHub: https://github.com/GarageGames/Torque2D
MIT:开源软件许可协议
MIT许可证之名源自麻省理工学院(Massachusetts Institute of Technology, MIT),又称「X条款」(X License)或「X11条款」(X11 License)
也就是说后续的其他平台支持会相继出现的.
使用的编程语言:
1: 核心: C++
2: Windows: C++
3: OS X: Objective-C, and Cocoa API
4: iOS: C++, Objective-C, and Cocoa touch API
脚本TorqueScript:
首先这个脚本系统很完善,功能也强大,灵活的编辑,习惯的编程方式能让程序猿很快的掌握并开始HelloWorld.
还有一个原因就是Torque2D在不修改代码的情况下,是直接生成EXE的,这就限制了众多的功能都需要使用脚本来书写,执行.
物理系统Box2D:
C++写的开源物理引擎,直接在Torque中开源包含编译.
音效系统OpenAL
总结:Torque2D的开源,对于众多喜欢2D跨平台游戏开发的朋友来说真是福音啊~ 但愿更多的朋友一起加入进来,完善这款大名鼎鼎的引擎~
在ScrollView中嵌套使用ListView,ListView只会显示一行到两行的数据。起初我以为是样式的问题,一直在对XML文件的样式进行尝试性设置,但始终得不到想要的效果。后来在网上查了查,ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起了冲突,一般不建议两者套用。
下面说说具体。方案的主要思路就是根据ListView子项重置其高度。
代码如下:
java代码:
/** * 重新计算ListView的高度,解决ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起冲突的问题 * @param listView */ public void setListViewHeight(ListView listView) { // 获取ListView对应的Adapter ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目 View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); // 计算子项View 的宽高 totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度 } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); }
在设置LIstView的Adapter后调用此方法便可。
但是要注意的是,子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。
原文: http://www.devx.com/wireless/Article/43551
在上一章,我们讨论了如何在iPhoneapp中调用web服务以及如何解析服务器返回的XML。在Web服务大行其道的当今,调用web服务的代价是高昂的,尤其是你仅仅是抓取少量数据的时候尤其如此——光SOAP封皮就占据了大部分字节。一个更好的办法是使用sockets,仅传送数据本身而不用进行XML封装。而且socket允许使用长连接,这样你的app可以运行在异步模式,只有在需要的时候才接收数据。
在本文当中,你将学习如何与服务器进行TCP/IP通信,并创建一个简单的聊天程序。
首先,用Xcode(3.2)创建一个View-basedApplication并命名为Network。
使用流进行网络通信
使用socket进行网络编程的最简单方式是使用NSStream。NSStream类对流操作进行了抽象,包括对各种流数据的读和写:内存流、网络流或文件流。当然,通过NSStream也可以与服务器进行通信。 无论是通过NSStream向服务器写数据,还是从NStream对象中读取服务器数据,都是一件简单的事情。
在Mac OS X中,使用NSHost和NSStream与服务器进行连接的代码如下:
NSInputStream *iStream;
NSOutputStream *oStream;
uint portNo = 500;
NSURL *website = [NSURLURLWithString:urlStr];
NSHost *host = [NSHost hostWithName:[websitehost]]; [NSStream getStreamsToHost:host
port:portNo
inputStream:&iStream
outputStream:&oStream];
NSStream的getStreamsToHost:port:inputStream:outputStream:方法用于连接服务器并创建一对输入输出流用于向服务器读写数据。问题是iOS中并没有这个方法。因此上述代码无法用于iPhoneapp中。
要解决这个问题,需要为NSStream增加新的类别以增加getStreamToHost:Port:inputstream:outputStream:方法。在Xcode中新建文件NSStreamAdditions.m。然后在NSStreamAdditions.h中编写代码如下:
@interface NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString*)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr;
@end
在NSStreamAdditions.m文件中加入下列代码。
#import "NSStreamAdditions.h"
@implementation NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString*)hostName
port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
assert(hostName != nil);
assert( (port > 0) && (port <65536) );
assert( (inputStreamPtr != NULL) ||(outputStreamPtr != NULL) );
readStream = NULL;
writeStream = NULL;
CFStreamCreatePairWithSocketToHost(
NULL,
(CFStringRef) hostName,
port,
((inputStreamPtr != nil) ?&readStream : NULL),
((outputStreamPtr != nil) ? &writeStream : NULL)
);
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream)autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr =[NSMakeCollectable(writeStream) autorelease];
}
}
@end
以上代码为NSStream类增加了一个类方法叫做:
getStreamsToHostNamed:port:inputStream:outputStream:
现在你可以在iPhone app中,使用该方法了。
作者注:该类别代码基于苹果文档 Apple’s Technical Q&A1652。
在NetworkViewController.m中,加入如下代码:
#import "NetworkViewController.h"
#import "NSStreamAdditions.h"
@implementation NetworkViewController
NSMutableData *data;
NSInputStream *iStream;
NSOutputStream *oStream;
定义connectToServerUsingStream:portNo:方法如下。在方法中我们连接了服务器并创建了一对输入/输出流:
-(void) connectToServerUsingStream:(NSString*)urlStr portNo: (uint) portNo {
if (![urlStrisEqualToString:@""]) {
NSURL *website =[NSURL URLWithString:urlStr];
if (!website) {
NSLog(@"%@ is not a valid URL");
return;
} else {
[NSStream getStreamsToHostNamed:urlStr
port:portNo
inputStream:&iStream
outputStream:&oStream];
[iStreamretain];
[oStream retain];
[iStreamsetDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStreamopen];
[iStream open];
}
}
}
在方法中,我们将input和output放到了runloop中以便接收事件。这样做,是为了防止流中没有有效数据时代码产生阻塞。input和output的委托属性都设置为self,因此我们还应该在NetworkViewController类中实现委托方法以便接收流数据。
使用 CFNetwork 进行网络通信
另一种TCP通信的方法是使用CFNetwork框架。CFNetwork属于核心服务框架(C语言库),提供了对HTTP、FTP、BSDsockets等网络协议的封装。
为了演示如何使用CFNetwork框架,在NetworkViewController.m文件中加入如下语句:
#import "NetworkViewController.h"
#import "NSStreamAdditions.h"
@implementation NetworkViewController
NSMutableData *data;
NSInputStream *iStream;
NSOutputStream *oStream;
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
定义 connectToServerUsingCFStream:portNo: 方法如下:
-(void) connectToServerUsingCFStream:(NSString *)
urlStr portNo: (uint) portNo{
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef) urlStr,
portNo,
&readStream,
&writeStream);
if (readStream &&writeStream){
CFReadStreamSetProperty(readStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
iStream =(NSInputStream *)readStream;
[iStream retain];
[iStream setDelegate:self];
[iStreamscheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
oStream = (NSOutputStream *)writeStream;
[oStreamretain];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoopcurrentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream open];
}
}
首先,我们使用CFStreamCreatePairWithSocketToHost()方法创建了一个到服务器的TCP/IP连接,以及一对输入输出流。然后将它们转换为等价的O-C对象——NSInputStream和NSOutputStream。接下来跟前面一样,设置delegate属性并放到runloop中运行。
发送数据
要想服务器发送数据,请使用NSOutputStream对象:
-(void) writeToServer:(const uint8_t *) buf {
[oStream write:bufmaxLength:strlen((char*)buf)];
}
这段代码发送了一个无符号整型数组到服务器。
读取数据
当服务器有数据到达,stream:handleEvent:方法被触发。因此我们只需在这个方法中读取数据即可。
- (void)stream:(NSStream *)streamhandleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if (data == nil) {
data = [[NSMutableData alloc] init];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[data appendBytes:(const void *)buf length:len];
int bytesRead;
bytesRead += len;
} else {
NSLog(@"No data.");
}
NSString *str =[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(str);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Fromserver"
message:str
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[str release];
[data release];
data = nil;
} break;
}
}
该方法有两个参数。一个NSStream对象和一个NSStreamEvent常量。NSStreamEvent常量可能包含以下取值:
- NSStreamEventNone -- 没有任何事件
- NSStreamEventOpenCompleted -- 流打开成功.
- NSStreamEventHasBytesAvailable -- 此时流中有字节待读取
- NSStreamEventHasSpaceAvailable -- 此时可向流中写入数据
- NSStreamEventErrorOccurred -- 有错误发生
- NSStreamEventEndEncountered -- 到达流的末尾
对于输入流,你应当检测NSStreamEventHasBytesAvailable 常量。在这里,我们从输入流中读取了数据并显示在UIAlertView中。
在stream:handleEvent:方法中,很容易检查到连接错误。在本例中,如果connectToServerUsingStream:portNo:方法连接服务器失败,则在stream:handleEvent方法将被调用并在NSStreamEvent参数中传递一个NSStreamEventErrorOccured错误。