??xml version="1.0" encoding="utf-8" standalone="yes"?> Android Studio 0.8.2+ and above, could easily import modules. Thanks to TGMCains answer, is simplified, by using Android Studio itself to import OpenCV as a module. Step (6) is since Android studio expects native libs in OpenCV written is in C/C++. Java wrappers are Waiting for device. Event LogH口昄: NoSuchMethodError: com.android.builder.model.AndroidArtifact.getOutputs()Ljava/util/Collection;: com.android.builder.model.AndroidArtifact.getOutputs()Ljava/util/Collection; 折腾?jin)很? 不得要领. 后来惌vAndroid Studio是采用解压安装包, q覆盖原有目录方式升U的, 那么可能?x)是某个文g存在'新旧冲突'的可? 于是一个个(g)查文件的旉? 发现只要在Android Studio目录下删除下??文g, 重启卛_. \android-studio\plugins\android\lib\builder-model-0.11.0.jar 因ؓ(f)Android Studio 0.8.1的Gradle用的?.12.+?. // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { // NOTE: Do not place your application dependencies here; they belong allprojects { <---- No Google Service ----> ? 何时Google Service才能畅快讉K?..app/src/main/jniLibs
instead of older libs
folder. For those new to Android OpenCV, don't miss below stepsstatic{ System.loadLibrary("opencv_java"); }
]]>
@ResponseBody
public ResponseEntity<Post.Response> post(HttpServletRequest request) {
Post.Response resp = null;
Post.Request req = null;
String file = null;
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
if (multipartResolver.isMultipart(request)) {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
try {
Collection<Part> parts = multiRequest.getParts();
boolean hasJSON = false;
boolean hasFile = false;
for (final Part p : parts) {
if (hasJSON) {
continue;
}
if (p.getContentType().contains("application/json")) {
ObjectMapper mapper = new ObjectMapper();
req = mapper.readValue(p.getInputStream(), Post.Request.class);
if (req != null) {
resp = new Post.Response();
resp.setX(100);
hasJSON = true;
}
} else if (p.getContentType().contains("image/jpeg")) {
++ index;
file = UPLOAD_ROOT + String.valueOf(index) + ".jpg";
InputStream is = p.getInputStream();
File localFile = new File(file);
OutputStream os = new FileOutputStream(localFile);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
hasFile = true;
}
if (hasJSON && hasFile) {
break;
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ServletException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
if (req != null && file != null) {
resp = calc.calc(req, file);
}
if (resp != null) {
return new ResponseEntity<Post.Response>(resp, HttpStatus.OK);
} else {
return new ResponseEntity<Post.Response>(resp, HttpStatus.BAD_REQUEST);
}
}
]]>
1. download opencv zip packageQ?br /> 2. download cmake source zipQ?br /> 3. download ant binary packageQ?br /> 4. install ant binary;
5. make cmake;
6. unzip opencv;
7. cmake opencv source;
#mkdir build
#cd build
#cmake -D BUILD_SHARED_LIBS=OFF ../
#make
8. install opencv library into Maven;
9. update pom.xml to add openvn dependency;
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>2.4.11</version>
<systemPath>/Users/Jie/Downloads/opencv-2.4.11/build/bin/opencv-2411.jar</systemPath>
<scope>system</scope>
</dependency>
10. run webapp;
11. done;
M(jin)无数++的页面,p些~
]]>
{
public:
class TParams
{
public:
TParams(int size);
virtual ~TParams();
private:
TParams(const TParams& params) {}
TParams& operator = (const TParams& params) { return *this; }
public:
void Add(const char* val, int size);
void Add(int val);
void Add(unsigned int val);
void Add(uint64_t val);
void Add(short val);
void Free();
int Size() const { return _size; }
const char * const * Value() const { return value; }
const int* Length() const { return length; }
const int* Format() const { return format; }
public:
char** value;
int* length;
int* format;
private:
int _size;
int _pos;
};
public:
DBConnection()
: conn(NULL)
{
}
virtual ~DBConnection();
public:
int Connect(const char* info);
void Disconnect();
int ExecCmd(const char* cmd);
PGresult* ExecQuery(const char* sql);
int ExecCmdWithParams(const char* cmd, const TParams& params);
PGresult* ExecQueryWithParams(const char* sql, const TParams& params);
int BeginTranscation();
int EndTranscation();
private:
PGconn* conn;
};
: _size(size), _pos(0)
{
value = new char*[_size];
length = new int[_size];
format = new int[_size];
}
DBConnection::TParams::~TParams()
{
Free();
}
void DBConnection::TParams::Free()
{
if (_size == 0)
{
return;
}
for (int i = 0; i < _size; ++ i)
{
if (format[i] == 0)
{
delete[] value[i];
}
else if (length[i] == sizeof(int) || length[i] == sizeof(unsigned int))
{
delete (int*)value[i];
}
else if (length[i] == sizeof(uint64_t))
{
delete (uint64_t*)value[i];
}
else
{
delete (short*)value[i];
}
}
delete[] value, value = NULL;
delete[] length, length = NULL;
delete[] format, format = NULL;
_size = 0;
DEBUG(DEBUG_ANY, "<DBConnection::TParams::Free()>"<< std::endl);
}
void DBConnection::TParams::Add(const char* val, int size)
{
char* char_val = new char[size + 1];
char_val[size] = '\0';
// char* char_val = new char[size];
memcpy(char_val, val, size);
value[_pos] = char_val;
length[_pos] = size + 1;
format[_pos] = 0;
++ _pos;
}
void DBConnection::TParams::Add(int val)
{
#ifdef __OS_MAC__
int* int_val = new (int)(val);
#else
int* int_val = new (int)(htonl(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(int);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(unsigned int val)
{
#ifdef __OS_MAC__
unsigned int* int_val = new (unsigned int)(val);
#else
unsigned int* int_val = new (unsigned int)(htonl(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(int);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(uint64_t val)
{
#ifdef __OS_MAC__
uint64_t* uint64_val = new uint64_t(val);
#else
uint64_t* uint64_val = new uint64_t(htobe64(val));
#endif
value[_pos] = (char*)(uint64_val);
length[_pos] = sizeof(uint64_t);
format[_pos] = 1;
++ _pos;
}
void DBConnection::TParams::Add(short val)
{
#ifdef __OS_MAC__
short* int_val = new (short)(val);
#else
short* int_val = new (short)(htons(val));
#endif
value[_pos] = (char*)(int_val);
length[_pos] = sizeof(short);
format[_pos] = 1;
++ _pos;
}
////
DBConnection::~DBConnection()
{
Disconnect();
}
int DBConnection::Connect(const char* info)
{
conn = PQconnectdb(info);
if (PQstatus(conn) != CONNECTION_OK)
{
DEBUG(DEBUG_ANY, "PQ connection failed.");
PQfinish(conn);
return -1;
}
return 0;
}
void DBConnection::Disconnect()
{
if (conn != NULL)
{
PQfinish(conn);
conn = NULL;
}
}
int DBConnection::ExecCmd(const char* cmd)
{
PGresult* res = PQexec(conn, cmd);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmd> failed - " << cmd << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecCmd> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return -1;
}
// int ret = ntohl(*PQcmdTuples(res));
int ret = *PQcmdTuples(res);
PQclear(res);
return ret;
}
PGresult* DBConnection::ExecQuery(const char* sql)
{
PGresult* res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecQuery> failed - " << sql << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecQuery> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return NULL;
}
return res;
}
int DBConnection::ExecCmdWithParams(const char* cmd, const DBConnection::TParams& params)
{
PGresult* res = PQexecParams(conn, cmd, params.Size(), NULL, params.Value(), params.Length(), params.Format(), 0);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmdWithParams> failed - " << cmd << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecCmdWithParams> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return -1;
}
// int ret = ntohl(*PQcmdTuples(res));
int ret = *PQcmdTuples(res);
PQclear(res);
DEBUG(DEBUG_ANY, "<DBConnection::ExecCmdWithParams> succ - " << cmd << std::endl);
return ret;
// return 0;
}
PGresult* DBConnection::ExecQueryWithParams(const char* sql, const TParams& params)
{
PGresult* res = PQexecParams(conn, sql, params.Size(), NULL, params.Value(), params.Length(), params.Format(), 0);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
DEBUG(DEBUG_ANY, "<DBConnection::ExecQueryWithParams> failed - " << sql << std::endl);
DEBUG(DEBUG_ANY, "DBConnection::ExecQueryWithParams> error - " << PQerrorMessage(conn) << std::endl);
PQclear(res);
return NULL;
}
return res;
}
int DBConnection::BeginTranscation()
{
return ExecCmd("BEGIN");
}
int DBConnection::EndTranscation()
{
return ExecCmd("END");
}
]]>
OSX升?0.10.1后,H然发现在OSX下看不到Bootcamp讑֤?jin)。想来这半个月就用过三次Win8.1Q而且也没做啥q分的操作,怎么q不见?jin)呢Q?br />
折腾一下午Q还是没有搞定,但发C片好?a >https://discussions.apple.com/thread/4871585Q其他提到的问题跟我q一P很是Ƣ喜?br />
“The problem is that the tool you used to resize the NTFS volume updated the MBR but didn't update the GPT. OS X only uses the GPT, and since the partition is invalid in the GPT, the NTFS volume doesn't mount. ”
没看太明白,意思应该是MBR跟GPT不一致了(jin)?br />
下面是正常的gpt数据Q?br />
gpt show: disk0: mediasize=1000204886016; sectorsize=512; blocks=1953525168
gpt show: disk0: Suspicious MBR at sector 0
gpt show: disk0: Pri GPT at sector 1
gpt show: disk0: Sec GPT at sector 1953525167
start size index contents
0 1 MBR
1 1 Pri GPT header
2 32 Pri GPT table
34 6
40 409600 1 GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B
409640 1451847864 2 GPT part - 48465300-0000-11AA-AA11-00306543ECAC
1452257504 1269536 3 GPT part - 426F6F74-0000-11AA-AA11-00306543ECAC
1453527040 499996672 4 GPT part - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
1953523712 1423
1953525135 32 Sec GPT table
1953525167 1 Sec GPT header
q个是有问题的:(x)Q我自己的忘记记录了(jin)Q这里是copy文章里面的)(j)
gpt show: disk0: mediasize=500107862016; sectorsize=512; blocks=976773168
gpt show: disk0: Suspicious MBR at sector 0
gpt show: disk0: Pri GPT at sector 1
gpt show: disk0: Sec GPT at sector 976773167
start size index contents
0 1 MBR
1 1 Pri GPT header
2 32 Pri GPT table
34 6
40 409600 1 GPT part - C12A7328-F81F-11D2-BA4B-00A0C93EC93B
409640 586340368 2 GPT part - 48465300-0000-11AA-AA11-00306543ECAC
586750008 1269536 3 GPT part - 426F6F74-0000-11AA-AA11-00306543ECAC
588019544 168
588019712 144130048 4
732149760 244623360 4 GPT part - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
976773120 15
976773135 32 Sec GPT table
976773167 1 Sec GPT header
可以发现GPT数据不连l,Dpȝ无法正常mount分区?br />
问题是这P但我搞不懂文章中的修复方式,望文兴叹?jin)半天。忽然想P既然是磁盘分区导致的问题Q那重新分区该就好了(jin)。于是就qv来。。?br /> 当然我不能删除原来的BootcampQ那上还有很多同学要的C#代码呢。所以呢Q走个旁?-- 用DiskUtil先从原来Machintosh HD分区再划分个分区来Q然后再删除掉这个小分区Q这L(fng)l就?x)重新刷新分区数据?br /> pȝ重启, sudo mount -t ntfs /dev/disk0s4 /Volumes/BOOTCAMP, 于是我又看见?jin)我的BOOTCAMP讑֤?jin)。bingoQ搞定了(jin)。。?br />
<---- 回头再说的分割线 ---->
q段日子Q很长的一D|子过M(jin)Q只是今天还是没?j)情做个说明Q下ơ吧。。。可以说?--- 我依然奋斗在敲字的第一Uѝ?br />
]]> 昨天Android Studio升?.8.1, 竟然没法执行App?jin)~
RunH口中显C?
Target device: lge-nexus_4-0262fa6d9d51c2e8
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
// in the individual module build.gradle files
}
}
repositories {
mavenCentral()
}
}
]]>
早上很意外地收到一个留a, 说是需要LAC (LingosHook Android Client)和数据文? 不知大家是否q记得这? LAC敲完发布都已l过Mq了(jin), 怎么使用看这?/a>, 需要的p里下载了(jin).
c46.db3 - http://1drv.ms/1r436SDLAC.apk - http://1drv.ms/VzfFso
q段旉Google的服务都不可讉K, 我把q两个文仉C到OneDrive上了(jin), q手把其中的广告给删了(jin), ? 反正在Android上一炚w子也见不? 索性真需要的拿d...
? 实际都忘记这个LAC? x(chng)自己在Android也敲?jin)三q半? 应用, 游戏敲了(jin)几个, 但现在想换䆾跟Android相关的工作竟然无? 各种阴差阳错DLd? 看来转行q是不对?..
周末同学说想弄个ZBaidu地图的应? 于是开始研I这个SDK? 其中应用有个需? 需要点d图上的标记时, 昄一l按? 于是按照常规的作法失业了(jin)InfoWindow, 如下.
//panel is a view, some buttons in it. final InfoWindow iw = new InfoWindow(panel, marker.getPosition(), null); //getMap() return BaiduMap activity.getMap().showInfoWindow(iw);
倒是不难, 但处理点M件时发现有问题(sh)(jin). Ҏ(gu)文档, 此时昄出来的InfoWindow实际是View的Bitmap囄, 也就意味着Ҏ(gu)没法区分View上的Buttons? 更别说能处理Button的点M件了(jin). 怪不? 文档中对于整个InfoWindow只有一个ClickListener, q(sh)含有View信息.
q样只能"曲线救国"? InfoWindow不能? 那就直接在MapView中弹ZPopupWindow? (手敲打试代码, p录用)
final View panel = UserPanel.make(activity); Point p = activity.getMap().getProjection().toScreenLocation(marker.getPosition()); final PopupWindow pw = new PopupWindow(panel); pw.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); pw.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); pw.setFocusable(true); pw.setOutsideTouchable(true); //getMapView() return MapView, not BaiduMap any more pw.showAtLocation(activity.getMapView(), Gravity.LEFT | Gravity.BOTTOM,p.x, p.y ); final Button btn = (Button) panel.findViewById(R.id.button2); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { pw.dismiss(); } });
搞定,人长个脑袋L有用?..
试中发C问题, 如果地图发生攄, Window弹出的位|会(x)不准? 很是奇? 按理MapView发生变化? 其Projection应该能够实时跟随变化? q个问题回头需要再看看.
<---- 回过头的分割U?---->
位置不准的问题是由于View和Screen坐标pM? 以及(qing)MapView自nsize共同影响? 错怪了(jin)Projection?.
今天H然U信?I;P怎么隐藏的系l虚拟键'? 样子如下图(Ҏ(gu)).
可以看到三个pȝ虚拟键变成三个极的点了(jin). 实际I;Pq没有达?隐藏'的效? q应该只能算?弱化'. 原因? 开始我没搞?隐藏', 后来想着如果真隐藏了(jin), 用户怎么操作pȝ按钮? 所? '弱化'对于I;P也就够了(jin)...q个一点不? 在libgdx的AndroidApplication的OnCreate()中点d下代码即?
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); cfg.useGL20 = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { WindowManager.LayoutParams params = getWindow().getAttributes(); params.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN;
getWindow().setAttributes(params); } initialize(new IPGame(setup, playService), cfg); }
'豆瓣阅读'q个app做到?jin)隐? 不知如何做到? 因ؓ(f)Ҏ(gu)Android官方文档上的内容? q个是不开攄. 很是奇? 回头再试试吧..
晚上查看一D资源xml文g? 发现View竟然有个'android:onClick'属?..q太'震惊'?..
刚开始敲Android? 想q这个问?-- android把资源文件用的如此灵z? 为啥View控g不能在资源文件中直接定义各类事g回调函数? 后来敲多? 发现如果直接在资源文件中定义事g处理属? q会(x)限制资源文g的? 像是同一份资源文件如果被两个不同的Activity使用, 那就必须各自写一个事件回调处理函? 如果没有, 一旦事件被触发, 那就是异常啊; 另外, 如果资源文g被一个Fragment使用, 且在Fragment实现?jin)事件处理函? 那当Fragment加入到Activity? 怕系l就找不到这个函C(jin). 因此, 觉得没有'android:onClick'q样的属性该是正常的, 后面也就没再惌q个? 每次都很老实的用View.setOnClickListener()?..
? 现在q个属性竟然真是存? 而且一直都? q太让我'崩溃'?..那感觉就像走在大街上, H然看到有h在遛 --- 恐龙一?..
于是, 赶紧写了(jin)代码试?jin)下~
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onButtonClick" android:text="Button" />
public void onButtonClick(View view) { Log.d(Tag, "onButtonClick()"); }
果然好用...但突然想? 如果q个跟View.setOnClickListener()共存? 调用q程该是如何?
Button btn = (Button) this.findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d(Tag, "onClickListener - onClick()"); } });
试l果?OnClilckListener()中的onClick()?x)被调? 而android:onClick定义的onButtonClick()完全被忽略了(jin).
如前面提到? q种属性设|的方式有些~陷, q是使用setOnClickListener()比较可控靠谱, 当然如果在布局文g使用比较固定的情况下, q种属性定义方式确实可以少敲很多代?
Z试l果, H然'抖机?地想CD代码来 -- 如果在onButtonClick()中调用setOnClickListener()?x)怎样?
public void onButtonClick(View view) { Log.d(Tag, "onButtonClick()"); Button btn = (Button) this.findViewById(R.id.button1); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d(Tag, "onClickListener - onClick()"); } }); }
q样W一ơ点?yn)L, 执行onButtonCllick(), q将View的点M件处理通过setOnClickListener()传到OnClickListener()? 当再ơ被点击? ׃(x)执行onClick()? q就可以实现一U需?-- 点一ơ没? 再点崩?..Ҏ(gu)不用加什么判断变量和语句? 嘿嘿, ?机智'?..
<---- 拖g症也?x)ƈ发的分割U?---->
q段旉, 各种借口D各种拖g症ƈ? 使得SnakeGo敲的甚是~慢..不表?..
昨晚把BaseScreen敲好了(jin), 也找C(jin)屏幕攄的最优和最方式. 不多? 看代?
public BaseScreen(final SnakeGo game) { super(new ScalingViewport(Scaling.fit, CommonConsts.Screen.WIDTH, CommonConsts.Screen.HEIGHT, new OrthographicCamera()), new SpriteBatch()); this.game = game; Gdx.input.setInputProcessor(this); }
BaseScreen直接l承与Stage是个好方? 很方便用Stage所提供的各U渲?输入相关的函? 但这样如果考虑MVC风格的话, M和Cg׃该在Screen存在, 但却又没地方攄...当然q样可能有些死脑{了(jin). (我在Snake对象中分M(jin)M和C).
在构造函C, 使用Scaling的fit方式来初始Stage, 可以保证屏幕'居中攄', q在resize()? 更新寸卛_.
@Override public void resize(int width, int height) { this.getViewport().update(width, height, true); }
q方法有些简单的让h不敢怿...
<---- LIBGDX众的分割线 ---->
q两天留意些Game相关的招聘(sh)? 发现Libgdx真是众? 一个都没有, N真的像朋友说?-- "也就你自q玩吧...". LIBGDX相对比较'?, 用v来虽说有?复杂', 但对于研I个'架构'什么的, 真的很不错的....? N我也转向cocos2d-x?
刚才使用LIBGDX的Stage? 发现1.0.1?.99的一个变?-- Stage内置Camera和Viewport(好用的ScalingViewportc?. 如此q样, 那放~屏q更方便?..
@Override public void resize(int width, int height) { Vector2 size = Scaling.fit.apply(CommonConsts.Screen.WIDTH, CommonConsts.Screen.HEIGHT, width, height); this.getViewport().update((int)size.x, (int)size.y, true);
// Vector2 screenScaling = new Vector2((size.x / CommonConsts.Screen.WIDTH), (size.y / CommonConsts.Screen.HEIGHT)); // this.getRoot().setScale(screenScaling.x, screenScaling.y); }
Stage内置的Camera和Viewport?原点'攑֜左下? 而不是常使用?居中', 另外q个q有个问? 当屏q羃放时, Viewport也不是一般习(fn)?居中'昄, 也是是靠左下. 我简单查看了(jin)下相应的Viewportc? 没有发现如何讄q个偏移? 只是SnakeGo'竖屏'模式在N4上正?铺满', q个问题再说? 如果需? 能预估最ȝ(ch)的就是重载ScalingViewportcM(jin).
代码? 后面注释掉的两句是用于等比例攄囑Ş? q没认真过, g不需要也可以? 需要再看看Viewportc?.
敲了(jin)几晚SnakeGo, 原型出来? 大家来看看不...
不错, q货是---贪吃?..哈哈...别? q还是原? 好玩的在后面?..(以我敲字速度, 大约再等不到六个月应该可以完成了(jin)...)
今天q里记录下用LIBGDXq程中碰到的两个问题:
1. 调整屏幕比例;
2. Ud观察镜头;
一, 调整屏幕比例
LIBGDX是跨q_? 一大好处就是直接在PC上测? 那是非常的方? 但这有两个问题需要考虑, 一, 手机?280x768, 但我PC只有1280x1024? 而且真要开个跟手机一样大的一样大的屏幕, 那还怎么看log输出? 二就是不同的手机有着不同的分辨率, 长宽比也不一? 那怎么保证囑Ş不变形呢?
q个问题?sh)难解? 只需要在屏幕寸发生变化? 即resize()(W一ơ启动也?x)调用此函?? 重新调整镜头(Camera)的参数即? 如下代码:
@Override public void resize(int width, int height) { Vector2 size = Scaling.fit.apply(WIDTH, HEIGHT, width, height); camera = new OrthographicCamera(size.x, size.y); camera.update(); batch.setProjectionMatrix(camera.combined); int viewportX = (int)(width - size.x) / 2; int viewportY = (int)(height - size.y) / 2; int viewportWidth = (int)size.x; int viewportHeight = (int)size.y; Gdx.gl.glViewport(viewportX, viewportY, viewportWidth, viewportHeight); super.resize(width, height); }
q里采用的是重新创徏camera实例的方? 另外用改变已有camera实例的参数方式也是一L(fng). 很简? 而且q样一ơ就解决?jin)上面两个问?-- PCZ使用M寸的窗? 都可以获得跟讄{比例的H口, 手机上亦是如? ?a href="http://www.shnenglu.com/codejie/category/20828.html">I;P是采用的这U方式来保持其在L手机上都?280:768的比?
q种Ҏ(gu)只是改变?sh)?视图'的大? 但ƈ不会(x)改变其中的图形的大小, q样Z(jin)保持囑Ş昄比例, 需要在输出囑Ş时做相应的比例放~? 可以在resize()获得q个比例, 染在囑Ş输出时用这个比?
screenScaling = new Vector2((size.x / WIDTH), (size.y / HEIGHT));
... ... batch.draw(img, (- WIDTH / 2) * screenScaling.x, (- HEIGHT / 2) * screenScaling.y, WIDTH * screenScaling.x, HEIGHT * screenScaling.y);
? Ud观察镜头
在SnakeGo? Z(jin)不让Snake'跑出'屏幕, 需要镜头camera跟Snake本n保持'同步'Ud, q样看v来Snake保持在屏q的中间, 但其它Object是移动的. Ҏ(gu)'相对q行'原理, 使整个看h像是Snake在Object中穿? 所? Udcamaera是必ȝ, 代码也简? 如下:
...
final OrthographicCamera camera = game.getCamera();
camera.translate(0.0f, 32.0f, 0.0f);
camera.update();
game.getSpriteBatch().setProjectionMatrix(camera.combined);
...
<----?j)?ch)意ؕ的分割线---->
q几天在扑ַ? 前面去面?jin)一? 其中没一个App或者Game的问? 倒全是C++相关? L傻g(jin)...虽说׃是C++'?gu)n'?不然Blog也不?x)在q里不是), 但也许真的是'?? 才三q不用C++,竟然忘记的只剩下个auto_ptr?..更?zhn)剧的是咱用的C++98标准已经变成C++11? auto_ptr变成smart_ptr?..
都说现在是个'跨界'的时? 但咱q还没有跨界, 只是同行转个方向而已, 为啥p么?zhn)剧?jin)...好吧, 估计学艺不精才是Ҏ(gu)...
同学"'大数?的博?周五来电(sh), 问我要不要跟她一起做?囑փ搜烦(ch)', 有些犹U, 要说三年? 也许干? 但现?..再{ơ嘛...
恰逢I;P敲完, ?j)?ch)意ؕ的一? 只好赶紧抓vSnakeGo? 夜夜疯敲, 来安抚砰砰躁动的?..是的, 臛_敲字可以让自己^?rn)?..
吐槽而已, q里惌 ---- E序员(sh)? 转行要趁着q轻赶紧?..
SnakeGo的基本模样在脑袋中勾ȝ差不多了(jin), 现在需要放?屏幕'上画个原型出来了(jin), 但突然就忘记该怎么用libgdx框架来画?..
敲完I;Pq才几天?..赶紧打开工程再看, 想起以前跟q?-- "libgdx不能?引擎', 多是一?cd'", 是啊, libgdxg没个固定的架子?.. 使用? 用vlibgdx来真的是要东拿西? 按照其中各类的功? 自己来搭q框架... 于是, 着脑袋q热, 赶紧M(jin)下面的类? 省的又忘?..
如何, ׃?
BaseScreen用到的ScreenCanvas和ActorStage功能是相同的, 只是前者用于放|Sprite, 而后者用于放|Actor/Group; 单说, ScreenCanvas里面攄?背景?贴图', 而ActorStage攄是可以响应Touch的Actors.
Screen下面的Manager和Render在每个Screen实例里面都有一套的, 前者用于存攑֒处理'数据', 而Render则根据前者的数据来渲染界? 两种之间通过怺注册的Listener来交换数据和事g. q架子像不像MVC风格? 嘿嘿...
老爷子心(j)不? 依然在勤勤恳恛_敲着书和代码...没错, 是source code. 像老爷子这L(fng)老一辈会(x)用电(sh)脑的都不? 而我亲爱的老爷子那是会(x)Turbo Basic的顶高手啊...每次惛_q个, 内心(j)都倍感自豪...
当年?H口"~程极其J琐, 如果不看看那一?lt;Win32 API大全>, 再加上个<Visual C++技术内q?gt;, 都不保证能敲个Window出来, 什么HWND, hInstance, 以及(qing)׃八糟的各cȝ口和消息的struct...反正我是早早忘光光?..x(chng)现在在的Android上弄?H口"出来, ?那真?太小儿科"?..
? 跑远?..我意思是 ---- 老爷子止步于Windows~程, 各类代码全部q行在DOS? 随着Windows的不断改q? l于, Windows下再也不能运行老爸手中的无敌神?-- Turbo Basic?..
曾跟老爷子说q? 他的代码都U至到Android? 但老爷子不同意, 因ؓ(f), 他老h家还要改些参数的, 改些参数, 些参? 参数...看着老爷子在Win7上装个VM跑XP再打开CommandH口q行Turbo Basic, 甚是辛苦. 作ؓ(f)知原? ?x)Google的程序员我来? 帮老爷子弄个DOS虚拟环境来跑TB.EXE, 那是必须?..
于是有?jin)下面的截?