- 浏览: 11433 次
- 性别:
- 来自: 珠海
最新评论
如何使用LGame中的LTexturePack(移值到其它环境也行……) 如何使用LGame中的LTexturePack(移值到其它环境也行……)
借写本例的机会,刚刚修正了某个【小】BUG。问题点在于LTexturePack的其中一个draw函数,本来在分图时需传入dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2等八个数值,结果小弟在接值时脑子进水,误将sx1,sx2,sy1,sy2写“扎堆”了(写错就是上述样子)……因为这是取图参数,即从sx1,sy1坐标开始取图,取到sx2,sy2的位置中止,弄错以后取出图立马变毕加索油画~所以小弟刚才将LGame-0.3.2-release这个包重新发了一遍,如果有用到LTexturePack的话请重新下载,抱歉抱歉(另外还改了3处问题)……
下载地址:http://loon-simple.googlecode.com/files/LGame-0.3.2-release.7z
关于TexturePack:
LGame中提供的LTexturePack类,是一个专门用于整合图像资源的辅助用类,它的最大作用是将许多零碎的图片画零为整,从而减少不必要的资源损耗。另一方面来讲,由于减少了渲染用纹理数量,避免了反复与图形系统交互,使用LTexturePack的速度通常会比单独使用零散LTexture为高。
最简单的使用方式:
- packageorg.loon.test;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.sprite.Arrow;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- LTexturePackimagePack;
- Arrowarrow;
- /**
- *无Transition效果。
- *
- *PS:目前LGame设定为,如果首个Screen没有加载特效,将强制运行一个随机特效。但是,返回Empty则不进行加载。
- */
- publicLTransitiononTransition(){
- returnLTransition.newEmpty();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- imagePack.putImage("assets/h_a.png");
- imagePack.putImage("assets/h_b.png");
- imagePack.putImage("assets/h_c.png");
- imagePack.putImage("assets/e_a.png");
- imagePack.putImage("assets/e_b.png");
- imagePack.putImage("assets/e_c.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理)
- imagePack.packed();
- }
- publicvoidalter(LTimerContexttimer){
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- intsize=32;
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- //LTexturePack中的数据可以按照索引加载
- imagePack.draw(0,32,size);
- //也可以按照文件名加载
- imagePack.draw("assets/h_b.png",32,size+=32);
- imagePack.draw(2,32,size+=32);
- size=32;
- imagePack.draw(3,256,size);
- imagePack.draw(4,256,size+=32);
- imagePack.draw(5,256,size+=32);
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- //实例化一个动态箭头精灵
- if(arrow==null){
- arrow=newArrow(212,212,188,188);
- add(arrow);
- }
- //显示实际纹理
- g.drawTexture(imagePack.getTexture(),32,size+50);
- g.drawString("Texture",235,size+124);
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
这时大家可以看到,在上述画面中,其实只有游戏中箭头指出的地方才是真正的纹理。而其余细分处,仅是大图纹理中的一部分罢了,然而在用户眼中,这些又有什么不同呢?不过,我们所能节省出的图像资源,却是非常巨大的。
当然,如果载入的是连续画面,那么仅仅能得到原画根本没用,不过没关系,我们也可以继续细分出我们满意的画面(上图具体代码和下例重复,故不再赘述)。
- packageorg.loon.test;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.collision.Gravity;
- importorg.loon.framework.javase.game.action.collision.GravityHandler;
- importorg.loon.framework.javase.game.action.sprite.Bind;
- importorg.loon.framework.javase.game.action.sprite.effect.SmashEffect;
- importorg.loon.framework.javase.game.core.geom.RectBox;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLColor;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimer;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- SmashEffectsmashEffect=newSmashEffect();
- //显示用精灵大小
- finalintshow_size=64;
- //实际精灵大小
- finalintreally_size=24;
- LTexturePackimagePack;
- /**
- *建立一个移动对象,用以管理LTexturePack中图像的移动
- */
- publicclassMove{
- RectBoxrect=newRectBox(0,0,show_size,show_size);
- LTimertimer=newLTimer(150);
- intid;
- floatx,y;
- intaction=1;
- inttype=-1;
- publicvoidsetX(floatx){
- this.x=x;
- rect.setX(x);
- }
- publicvoidsetY(floaty){
- this.y=y;
- rect.setY(y);
- }
- publicfloatgetX(){
- returnx;
- }
- publicfloatgetY(){
- returny;
- }
- publicbooleanintersects(Movem){
- returnrect.intersects(m.rect);
- }
- publicvoidupdate(){
- if(timer.action(elapsedTime)){
- action++;
- if(action>4){
- action=1;
- }
- }
- }
- }
- /**
- *无Transition效果。
- *
- *PS:目前LGame设定为,如果首个Screen没有加载特效,将强制运行一个随机特效。但是,返回Empty则不进行加载。
- */
- publicLTransitiononTransition(){
- returnLTransition.newEmpty();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- intheroId=imagePack.putImage("assets/h_a.png");
- intenemyId=imagePack.putImage("assets/e_a.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理)
- imagePack.packed();
- finalMovemoveHero=newMove();
- moveHero.id=heroId;
- moveHero.x=0;
- moveHero.y=128;
- moveHero.type=0;
- finalMovemoveEnemy=newMove();
- moveEnemy.id=enemyId;
- moveEnemy.x=getWidth()-show_size;
- moveEnemy.y=128;
- moveEnemy.type=1;
- /**
- *获得一个内置的重力管理器
- *
- *PS:所有具备setX、setY函数的公有类(必须公有,否则反射不到……),都可以被GravityHandler绑定
- */
- finalGravityHandlergravityHandler=getGravityHandler();
- //用重力控制器将moveHero对象打包,并且向右方匀速移动(速度100)
- Gravityg1=newGravity(moveHero);
- g1.setVelocityX(100);
- //用重力控制器将moveHero对象打包,并且向左方匀速移动(速度100)
- Gravityg2=newGravity(moveEnemy);
- g2.setVelocityX(-100);
- //添加重力干预
- gravityHandler.add(g1);
- gravityHandler.add(g2);
- //构建重力监控
- GravityHandler.Updateupdate=newGravityHandler.Update(){
- publicvoidaction(Gravityg,floatx,floaty){
- //让当前重力控制触边实效(具体到本例,人物也将消失)
- if(x<0){
- gravityHandler.remove(g);
- }
- if(x>getWidth()-show_size){
- gravityHandler.remove(g);
- }
- }
- };
- //添加监控(每次Gravity对象坐标发生变更时生效)
- gravityHandler.onUpdate(update);
- }
- publicvoidalter(LTimerContexttimer){
- smashEffect.update(timer.getTimeSinceLastUpdate());
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- smashEffect.draw(g);
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- //获得重力控制器(如果绑定为Sprite,Actor,LComponent等对象则不必额外处理显示步骤,
- //此处图像已统一打包入LTexturePack较为特殊)
- GravityHandlergravityHandler=getGravityHandler();
- //获得重力实例数量
- intsize=gravityHandler.getCount();
- //保存上一个Move实例
- Movefirst=null;
- for(inti=0;i<size;i++){
- //获得实例
- Gravitygravity=gravityHandler.get(i);
- Bindbind=gravity.getBind();
- //反射回绑定的对象
- Moveo=(Move)bind.ref();
- //判定两个图像的移动位置是否发生了碰撞(这里使用了比较流氓(就俩,省了-_-)的方式,实际应该建立一个精灵预警区,
- //然后搜索该区域内是否存在精灵,有的话再让移动中精灵与该精灵进行碰撞比较)
- if(first!=null&&first.intersects(o)){
- //碰撞后象征性的显示一个粉碎特效
- if(first.action!=5){
- smashEffect.createSmallExplosionEffect(getHalfWidth(),
- getHalfHeight());
- }
- o.action=5;
- first.action=5;
- g.setColor(GLColor.red);
- }
- switch(o.type){
- case0:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- (o.action-1)*really_size,0,o.action
- *really_size,really_size);
- break;
- case1:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- o.action*really_size,0,(o.action-1)
- *really_size,really_size);
- break;
- }
- first=o;
- o.update();
- }
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
让LTexturePack中的两个精灵进行单挑
多个图像移动:
- packageorg.loon.test;
- importjava.util.ArrayList;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.collision.Gravity;
- importorg.loon.framework.javase.game.action.collision.GravityHandler;
- importorg.loon.framework.javase.game.core.LSystem;
- importorg.loon.framework.javase.game.core.geom.RectBox;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimer;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- ArrayList<Move>moveList;
- //显示用精灵大小
- finalintshow_size=64;
- //实际精灵大小
- finalintreally_size=24;
- LTexturePackimagePack;
- /**
- *建立一个移动对象,用以管理LTexturePack中图像的移动
- */
- publicclassMove{
- RectBoxrect=newRectBox(0,0,show_size,show_size);
- LTimertimer=newLTimer(150);
- intid;
- floatx,y;
- intaction=1;
- inttype=-1;
- publicMove(intid,inttype,floatx,floaty){
- this.id=id;
- this.type=type;
- this.x=x;
- this.y=y;
- }
- publicvoidsetX(floatx){
- this.x=x;
- rect.setX(x);
- }
- publicvoidsetY(floaty){
- this.y=y;
- rect.setY(y);
- }
- publicfloatgetX(){
- returnx;
- }
- publicfloatgetY(){
- returny;
- }
- publicbooleanintersects(Movem){
- returnrect.intersects(m.rect);
- }
- publicvoidupdate(){
- if(timer.action(elapsedTime)){
- action++;
- if(action>4){
- action=1;
- }
- }
- }
- }
- publicLTransitiononTransition(){
- returnLTransition.newCrossRandom();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- intheroImgId=imagePack.putImage("assets/h_a.png");
- intenemyImgId=imagePack.putImage("assets/e_a.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理;如果不调用此函数,
- //LTexturePack将允许动态增减图像,但是已加载的小图资源不会自动释放(可手动释放,或者dispose全部清空))
- imagePack.packed();
- //构建一个Move集合,用以控制图像移动与显示
- this.moveList=newArrayList<Move>(10);
- moveList.add(newMove(heroImgId,0,0,32));
- moveList.add(newMove(heroImgId,0,0,136));
- moveList.add(newMove(heroImgId,0,0,220));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,32));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,136));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,220));
- /**
- *获得一个内置的重力管理器
- *
- *PS:所有具备setX、setY函数的公有类(必须公有,否则反射不到……),都可以被GravityHandler绑定
- */
- finalGravityHandlergravityHandler=getGravityHandler();
- //批量载入重力控制
- for(Movem:moveList){
- Gravityg=newGravity(m);
- if(m.type==0){
- g.setVelocityX(LSystem.getRandom(50,80));
- }elseif(m.type==1){
- g.setVelocityX(-LSystem.getRandom(50,100));
- }
- gravityHandler.add(g);
- }
- //构建重力监控
- GravityHandler.Updateupdate=newGravityHandler.Update(){
- publicvoidaction(Gravityg,floatx,floaty){
- synchronized(moveList){
- Movesrc=(Move)g.getBind().ref();
- //仅让我方与敌人产生碰撞
- if(src.type==0&&src.action!=5){
- for(Moveobj:moveList){
- if(src.type!=obj.type&&!src.equals(obj)
- &&src.intersects(obj)){
- src.action=5;
- obj.action=6;
- }
- }
- }
- if(src.action<5){
- //让移动有一定几率上下浮动(比较贴近真实行走)
- g.setVelocityY(LSystem.getRandom(-100,100));
- }else{
- //打人或挨打时不能上下浮动
- g.setVelocityY(0);
- }
- //让当前重力控制触边实效(更上例不同,此方式仅暂停重力控制,而非删除,这意味着可以唤醒)
- if(x<0){
- g.setEnabled(false);
- }
- if(x>getWidth()-show_size){
- g.setEnabled(false);
- }
- }
- }
- };
- //添加监控(每次Gravity对象坐标发生变更时生效)
- gravityHandler.onUpdate(update);
- }
- publicvoidalter(LTimerContexttimer){
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- synchronized(moveList){
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- for(Moveo:moveList){
- switch(o.type){
- case0:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- (o.action-1)*really_size,0,o.action
- *really_size,really_size);
- break;
- case1:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- o.action*really_size,0,(o.action-1)
- *really_size,really_size);
- break;
- }
- o.update();
- }
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- }
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
让单独纹理中的多个精灵进行混战
——————————
除了动态加载小图为统一纹理外,LTexturePack工具也允许根据XML设定来分解单独的大图为指定格式小图。
以上例为准,当我们执行下列代码:
System.out.println(imagePack.toString());
将可以在控制台见到如下输出:
<?xml version="1.0" standalone="yes" ?>
<pack file="null">
<block id="0" name="assets/h_a.png" left="0" top="0" right="144" bottom="24"/>
<block id="1" name="assets/e_a.png" left="0" top="24" right="144" bottom="48"/>
</pack>
这一输出,其实就是LTexturePack工具的XML文档解析格式。如果有单独的复合素材图(所有小图合成一张大图的那种),只要我们构建一个符合上述格式的XML文档,就能直接导入LTexturePack中使用。具体来说,<pack file="null">这项必须存在,其中file需要填写为素材图所在路径;id、left、top、right、bottom这五项也必须存在,否则无法定位和获取小图;name项如果想根据name取小图时必须存在,如果无此要求可不填。
另外,在LAE和LSE包中并无此工具类及类似工具存在。原因在于,使用LTexturePack工具虽然可以有效的节约图像资源,可惜调用方法不够直观,与LAE和LSE包的Easy特性并不相符。而且在Bitmap分图时,效率损耗要大于Texture,虽然能节约一定的显存空间,却会使本就不快的Canvas绘图变得更慢。因此,没有为LAE和LSE包提供相关扩展。
____________________
示例中用到了一些MD版梦幻模拟战的素材,资源在此(用什么图原理都一样):
http://115.com/file/dnr4wd6b#
临时想到的一些杂项:
1、关于LGame屏幕设置:
LGame默认提供有的Activity子类LGameAndroid2DActivity,只要继承该类的Activity就可以获得onMain、onGamePaused、onGameResumed三个接口。通常来说,在onMain中就足以完成我们所有的游戏初始化设置。
下面是一个最典型的基本设置:
- publicvoidonMain(){
- //横屏,全屏显示
- this.initialization(true,LMode.Fill);
- //不显示logo
- this.setShowLogo(false);
- //显示实际fps
- this.setShowFPS(true);
- //注入游戏Screen
- this.setScreen(newMyScreen());
- //显示画面
- this.showScreen();
- }
如果我们设置initialization(true),这时游戏屏幕为横屏显示,而initialization(false)为竖屏显示,在布尔值后还可追加一项LMode,通过该类可以设定屏幕的显示方式,如全屏、自适屏、默认大小等等。而在调用initialization之前,我们可以调用maxScreen函数设定默认的屏幕大小,屏幕缩放以此作为依据,如果不进行设置,则默认游戏屏幕大小为480x320。
2、怎样提高游戏速度:
单以效率论,除了能起到缓存(或跳过冗余步骤)的模块外,绝大多数Java类在游戏开发中只能起到减速作用,游戏模块越多,意味着速度被放缓的可能性也就越大。所以游戏引擎也并不一定在所有场景都是快速的,因使用者不同,引擎即可能成为游戏加速的工具,也可能沦为游戏减速的利器。
仅以小弟愚见,提高速度的最简便诀窍在于——“能够执行一次的地方,就绝不给他第二次执行的机会”,真能做到这样,足矣。
借写本例的机会,刚刚修正了某个【小】BUG。问题点在于LTexturePack的其中一个draw函数,本来在分图时需传入dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2等八个数值,结果小弟在接值时脑子进水,误将sx1,sx2,sy1,sy2写“扎堆”了(写错就是上述样子)……因为这是取图参数,即从sx1,sy1坐标开始取图,取到sx2,sy2的位置中止,弄错以后取出图立马变毕加索油画~所以小弟刚才将LGame-0.3.2-release这个包重新发了一遍,如果有用到LTexturePack的话请重新下载,抱歉抱歉(另外还改了3处问题)……
下载地址:http://loon-simple.googlecode.com/files/LGame-0.3.2-release.7z
关于TexturePack:
LGame中提供的LTexturePack类,是一个专门用于整合图像资源的辅助用类,它的最大作用是将许多零碎的图片画零为整,从而减少不必要的资源损耗。另一方面来讲,由于减少了渲染用纹理数量,避免了反复与图形系统交互,使用LTexturePack的速度通常会比单独使用零散LTexture为高。
最简单的使用方式:
- packageorg.loon.test;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.sprite.Arrow;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- LTexturePackimagePack;
- Arrowarrow;
- /**
- *无Transition效果。
- *
- *PS:目前LGame设定为,如果首个Screen没有加载特效,将强制运行一个随机特效。但是,返回Empty则不进行加载。
- */
- publicLTransitiononTransition(){
- returnLTransition.newEmpty();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- imagePack.putImage("assets/h_a.png");
- imagePack.putImage("assets/h_b.png");
- imagePack.putImage("assets/h_c.png");
- imagePack.putImage("assets/e_a.png");
- imagePack.putImage("assets/e_b.png");
- imagePack.putImage("assets/e_c.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理)
- imagePack.packed();
- }
- publicvoidalter(LTimerContexttimer){
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- intsize=32;
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- //LTexturePack中的数据可以按照索引加载
- imagePack.draw(0,32,size);
- //也可以按照文件名加载
- imagePack.draw("assets/h_b.png",32,size+=32);
- imagePack.draw(2,32,size+=32);
- size=32;
- imagePack.draw(3,256,size);
- imagePack.draw(4,256,size+=32);
- imagePack.draw(5,256,size+=32);
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- //实例化一个动态箭头精灵
- if(arrow==null){
- arrow=newArrow(212,212,188,188);
- add(arrow);
- }
- //显示实际纹理
- g.drawTexture(imagePack.getTexture(),32,size+50);
- g.drawString("Texture",235,size+124);
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
这时大家可以看到,在上述画面中,其实只有游戏中箭头指出的地方才是真正的纹理。而其余细分处,仅是大图纹理中的一部分罢了,然而在用户眼中,这些又有什么不同呢?不过,我们所能节省出的图像资源,却是非常巨大的。
当然,如果载入的是连续画面,那么仅仅能得到原画根本没用,不过没关系,我们也可以继续细分出我们满意的画面(上图具体代码和下例重复,故不再赘述)。
- packageorg.loon.test;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.collision.Gravity;
- importorg.loon.framework.javase.game.action.collision.GravityHandler;
- importorg.loon.framework.javase.game.action.sprite.Bind;
- importorg.loon.framework.javase.game.action.sprite.effect.SmashEffect;
- importorg.loon.framework.javase.game.core.geom.RectBox;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLColor;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimer;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- SmashEffectsmashEffect=newSmashEffect();
- //显示用精灵大小
- finalintshow_size=64;
- //实际精灵大小
- finalintreally_size=24;
- LTexturePackimagePack;
- /**
- *建立一个移动对象,用以管理LTexturePack中图像的移动
- */
- publicclassMove{
- RectBoxrect=newRectBox(0,0,show_size,show_size);
- LTimertimer=newLTimer(150);
- intid;
- floatx,y;
- intaction=1;
- inttype=-1;
- publicvoidsetX(floatx){
- this.x=x;
- rect.setX(x);
- }
- publicvoidsetY(floaty){
- this.y=y;
- rect.setY(y);
- }
- publicfloatgetX(){
- returnx;
- }
- publicfloatgetY(){
- returny;
- }
- publicbooleanintersects(Movem){
- returnrect.intersects(m.rect);
- }
- publicvoidupdate(){
- if(timer.action(elapsedTime)){
- action++;
- if(action>4){
- action=1;
- }
- }
- }
- }
- /**
- *无Transition效果。
- *
- *PS:目前LGame设定为,如果首个Screen没有加载特效,将强制运行一个随机特效。但是,返回Empty则不进行加载。
- */
- publicLTransitiononTransition(){
- returnLTransition.newEmpty();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- intheroId=imagePack.putImage("assets/h_a.png");
- intenemyId=imagePack.putImage("assets/e_a.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理)
- imagePack.packed();
- finalMovemoveHero=newMove();
- moveHero.id=heroId;
- moveHero.x=0;
- moveHero.y=128;
- moveHero.type=0;
- finalMovemoveEnemy=newMove();
- moveEnemy.id=enemyId;
- moveEnemy.x=getWidth()-show_size;
- moveEnemy.y=128;
- moveEnemy.type=1;
- /**
- *获得一个内置的重力管理器
- *
- *PS:所有具备setX、setY函数的公有类(必须公有,否则反射不到……),都可以被GravityHandler绑定
- */
- finalGravityHandlergravityHandler=getGravityHandler();
- //用重力控制器将moveHero对象打包,并且向右方匀速移动(速度100)
- Gravityg1=newGravity(moveHero);
- g1.setVelocityX(100);
- //用重力控制器将moveHero对象打包,并且向左方匀速移动(速度100)
- Gravityg2=newGravity(moveEnemy);
- g2.setVelocityX(-100);
- //添加重力干预
- gravityHandler.add(g1);
- gravityHandler.add(g2);
- //构建重力监控
- GravityHandler.Updateupdate=newGravityHandler.Update(){
- publicvoidaction(Gravityg,floatx,floaty){
- //让当前重力控制触边实效(具体到本例,人物也将消失)
- if(x<0){
- gravityHandler.remove(g);
- }
- if(x>getWidth()-show_size){
- gravityHandler.remove(g);
- }
- }
- };
- //添加监控(每次Gravity对象坐标发生变更时生效)
- gravityHandler.onUpdate(update);
- }
- publicvoidalter(LTimerContexttimer){
- smashEffect.update(timer.getTimeSinceLastUpdate());
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- smashEffect.draw(g);
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- //获得重力控制器(如果绑定为Sprite,Actor,LComponent等对象则不必额外处理显示步骤,
- //此处图像已统一打包入LTexturePack较为特殊)
- GravityHandlergravityHandler=getGravityHandler();
- //获得重力实例数量
- intsize=gravityHandler.getCount();
- //保存上一个Move实例
- Movefirst=null;
- for(inti=0;i<size;i++){
- //获得实例
- Gravitygravity=gravityHandler.get(i);
- Bindbind=gravity.getBind();
- //反射回绑定的对象
- Moveo=(Move)bind.ref();
- //判定两个图像的移动位置是否发生了碰撞(这里使用了比较流氓(就俩,省了-_-)的方式,实际应该建立一个精灵预警区,
- //然后搜索该区域内是否存在精灵,有的话再让移动中精灵与该精灵进行碰撞比较)
- if(first!=null&&first.intersects(o)){
- //碰撞后象征性的显示一个粉碎特效
- if(first.action!=5){
- smashEffect.createSmallExplosionEffect(getHalfWidth(),
- getHalfHeight());
- }
- o.action=5;
- first.action=5;
- g.setColor(GLColor.red);
- }
- switch(o.type){
- case0:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- (o.action-1)*really_size,0,o.action
- *really_size,really_size);
- break;
- case1:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- o.action*really_size,0,(o.action-1)
- *really_size,really_size);
- break;
- }
- first=o;
- o.update();
- }
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
让LTexturePack中的两个精灵进行单挑
多个图像移动:
- packageorg.loon.test;
- importjava.util.ArrayList;
- importorg.loon.framework.javase.game.GameScene;
- importorg.loon.framework.javase.game.action.collision.Gravity;
- importorg.loon.framework.javase.game.action.collision.GravityHandler;
- importorg.loon.framework.javase.game.core.LSystem;
- importorg.loon.framework.javase.game.core.geom.RectBox;
- importorg.loon.framework.javase.game.core.graphics.Screen;
- importorg.loon.framework.javase.game.core.graphics.opengl.GLEx;
- importorg.loon.framework.javase.game.core.graphics.opengl.LTexturePack;
- importorg.loon.framework.javase.game.core.input.LTouch;
- importorg.loon.framework.javase.game.core.input.LTransition;
- importorg.loon.framework.javase.game.core.timer.LTimer;
- importorg.loon.framework.javase.game.core.timer.LTimerContext;
- publicclassLTexturePackTestextendsScreen{
- ArrayList<Move>moveList;
- //显示用精灵大小
- finalintshow_size=64;
- //实际精灵大小
- finalintreally_size=24;
- LTexturePackimagePack;
- /**
- *建立一个移动对象,用以管理LTexturePack中图像的移动
- */
- publicclassMove{
- RectBoxrect=newRectBox(0,0,show_size,show_size);
- LTimertimer=newLTimer(150);
- intid;
- floatx,y;
- intaction=1;
- inttype=-1;
- publicMove(intid,inttype,floatx,floaty){
- this.id=id;
- this.type=type;
- this.x=x;
- this.y=y;
- }
- publicvoidsetX(floatx){
- this.x=x;
- rect.setX(x);
- }
- publicvoidsetY(floaty){
- this.y=y;
- rect.setY(y);
- }
- publicfloatgetX(){
- returnx;
- }
- publicfloatgetY(){
- returny;
- }
- publicbooleanintersects(Movem){
- returnrect.intersects(m.rect);
- }
- publicvoidupdate(){
- if(timer.action(elapsedTime)){
- action++;
- if(action>4){
- action=1;
- }
- }
- }
- }
- publicLTransitiononTransition(){
- returnLTransition.newCrossRandom();
- }
- publicvoidonLoad(){
- imagePack=newLTexturePack();
- //加载小图到LTexturePack
- intheroImgId=imagePack.putImage("assets/h_a.png");
- intenemyImgId=imagePack.putImage("assets/e_a.png");
- //宣布所有图像加载完毕(如果调用此函数,则释放所有已加载的资源,仅保留一块主纹理;如果不调用此函数,
- //LTexturePack将允许动态增减图像,但是已加载的小图资源不会自动释放(可手动释放,或者dispose全部清空))
- imagePack.packed();
- //构建一个Move集合,用以控制图像移动与显示
- this.moveList=newArrayList<Move>(10);
- moveList.add(newMove(heroImgId,0,0,32));
- moveList.add(newMove(heroImgId,0,0,136));
- moveList.add(newMove(heroImgId,0,0,220));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,32));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,136));
- moveList.add(newMove(enemyImgId,1,getWidth()-show_size,220));
- /**
- *获得一个内置的重力管理器
- *
- *PS:所有具备setX、setY函数的公有类(必须公有,否则反射不到……),都可以被GravityHandler绑定
- */
- finalGravityHandlergravityHandler=getGravityHandler();
- //批量载入重力控制
- for(Movem:moveList){
- Gravityg=newGravity(m);
- if(m.type==0){
- g.setVelocityX(LSystem.getRandom(50,80));
- }elseif(m.type==1){
- g.setVelocityX(-LSystem.getRandom(50,100));
- }
- gravityHandler.add(g);
- }
- //构建重力监控
- GravityHandler.Updateupdate=newGravityHandler.Update(){
- publicvoidaction(Gravityg,floatx,floaty){
- synchronized(moveList){
- Movesrc=(Move)g.getBind().ref();
- //仅让我方与敌人产生碰撞
- if(src.type==0&&src.action!=5){
- for(Moveobj:moveList){
- if(src.type!=obj.type&&!src.equals(obj)
- &&src.intersects(obj)){
- src.action=5;
- obj.action=6;
- }
- }
- }
- if(src.action<5){
- //让移动有一定几率上下浮动(比较贴近真实行走)
- g.setVelocityY(LSystem.getRandom(-100,100));
- }else{
- //打人或挨打时不能上下浮动
- g.setVelocityY(0);
- }
- //让当前重力控制触边实效(更上例不同,此方式仅暂停重力控制,而非删除,这意味着可以唤醒)
- if(x<0){
- g.setEnabled(false);
- }
- if(x>getWidth()-show_size){
- g.setEnabled(false);
- }
- }
- }
- };
- //添加监控(每次Gravity对象坐标发生变更时生效)
- gravityHandler.onUpdate(update);
- }
- publicvoidalter(LTimerContexttimer){
- }
- publicvoiddraw(GLExg){
- if(isOnLoadComplete()){
- synchronized(moveList){
- //当执行glBegin后,将在GLEx触发一个渲染批处理事件,仅在执行glEnd后提交
- //渲染内容到窗体。如果不调用此函数,则LTexturePack依旧可以执行,但是效率
- //可能会受到一定影响(每次渲染都单独提交)。
- imagePack.glBegin();
- for(Moveo:moveList){
- switch(o.type){
- case0:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- (o.action-1)*really_size,0,o.action
- *really_size,really_size);
- break;
- case1:
- imagePack.draw(o.id,o.x,o.y,show_size,show_size,
- o.action*really_size,0,(o.action-1)
- *really_size,really_size);
- break;
- }
- o.update();
- }
- //提交渲染结果到游戏画面
- imagePack.glEnd();
- }
- }
- }
- publicvoidtouchDown(LTouche){
- }
- publicvoidtouchDrag(LTouche){
- }
- publicvoidtouchMove(LTouche){
- }
- publicvoidtouchUp(LTouche){
- }
- publicvoiddispose(){
- if(imagePack!=null){
- imagePack.dispose();
- imagePack=null;
- }
- }
- publicstaticvoidmain(String[]args){
- GameScenegame=newGameScene("LTexturePackTest",480,320);
- game.setShowFPS(true);
- game.setShowLogo(false);
- game.setScreen(newLTexturePackTest());
- game.showScreen();
- }
- }
让单独纹理中的多个精灵进行混战
——————————
除了动态加载小图为统一纹理外,LTexturePack工具也允许根据XML设定来分解单独的大图为指定格式小图。
以上例为准,当我们执行下列代码:
System.out.println(imagePack.toString());
将可以在控制台见到如下输出:
<?xml version="1.0" standalone="yes" ?>
<pack file="null">
<block id="0" name="assets/h_a.png" left="0" top="0" right="144" bottom="24"/>
<block id="1" name="assets/e_a.png" left="0" top="24" right="144" bottom="48"/>
</pack>
这一输出,其实就是LTexturePack工具的XML文档解析格式。如果有单独的复合素材图(所有小图合成一张大图的那种),只要我们构建一个符合上述格式的XML文档,就能直接导入LTexturePack中使用。具体来说,<pack file="null">这项必须存在,其中file需要填写为素材图所在路径;id、left、top、right、bottom这五项也必须存在,否则无法定位和获取小图;name项如果想根据name取小图时必须存在,如果无此要求可不填。
另外,在LAE和LSE包中并无此工具类及类似工具存在。原因在于,使用LTexturePack工具虽然可以有效的节约图像资源,可惜调用方法不够直观,与LAE和LSE包的Easy特性并不相符。而且在Bitmap分图时,效率损耗要大于Texture,虽然能节约一定的显存空间,却会使本就不快的Canvas绘图变得更慢。因此,没有为LAE和LSE包提供相关扩展。
____________________
示例中用到了一些MD版梦幻模拟战的素材,资源在此(用什么图原理都一样):
http://115.com/file/dnr4wd6b#
临时想到的一些杂项:
1、关于LGame屏幕设置:
LGame默认提供有的Activity子类LGameAndroid2DActivity,只要继承该类的Activity就可以获得onMain、onGamePaused、onGameResumed三个接口。通常来说,在onMain中就足以完成我们所有的游戏初始化设置。
下面是一个最典型的基本设置:
- publicvoidonMain(){
- //横屏,全屏显示
- this.initialization(true,LMode.Fill);
- //不显示logo
- this.setShowLogo(false);
- //显示实际fps
- this.setShowFPS(true);
- //注入游戏Screen
- this.setScreen(newMyScreen());
- //显示画面
- this.showScreen();
- }
如果我们设置initialization(true),这时游戏屏幕为横屏显示,而initialization(false)为竖屏显示,在布尔值后还可追加一项LMode,通过该类可以设定屏幕的显示方式,如全屏、自适屏、默认大小等等。而在调用initialization之前,我们可以调用maxScreen函数设定默认的屏幕大小,屏幕缩放以此作为依据,如果不进行设置,则默认游戏屏幕大小为480x320。
2、怎样提高游戏速度:
单以效率论,除了能起到缓存(或跳过冗余步骤)的模块外,绝大多数Java类在游戏开发中只能起到减速作用,游戏模块越多,意味着速度被放缓的可能性也就越大。所以游戏引擎也并不一定在所有场景都是快速的,因使用者不同,引擎即可能成为游戏加速的工具,也可能沦为游戏减速的利器。
仅以小弟愚见,提高速度的最简便诀窍在于——“能够执行一次的地方,就绝不给他第二次执行的机会”,真能做到这样,足矣。 cping1982原文:http://blog.csdn.net/cping1982/article/details/7002541
相关推荐
此外,项目中包含了24个可以直接运行的游戏示例,这些示例位于Java/Examples文件夹下,开发者可以将这些示例代码复制到自己的项目中运行,以快速体验LGame的功能。 5. LGame引擎编程实践 LGame引擎编程实践涉及到了...
### LGame-Android 版本 0.2.9 中文使用文档概览 #### 一、概述 本文档旨在详细介绍 LGame-Android 版本 0.2.9 的功能特性和使用方法。LGame-Android 是 LGame-J2SE(即 PC 版)针对 Android 平台进行优化后的精简...
总结起来,通过"Android飞机游戏(基于LGame引擎)"这个实例,我们可以学习到如何使用LGame引擎进行Android游戏开发,包括游戏循环的构建、图形和音频的处理、碰撞检测的应用等关键技能。同时,它也提醒我们注意在...
这个版本包含了LGame的开发文档、源码和其他必要的依赖库,为开发者提供了全面的开发环境。 1. **LGame核心特性** - **跨平台支持**:LGame基于Java语言,可以轻松实现JavaSE(Java标准版)和Android平台的游戏...
1. **库文件**:这些可能是LGame框架的jar或aar文件,开发者需要将它们添加到Android项目的依赖中,以便在项目中使用LGame的功能。 2. **示例代码**:可能包含一些示例游戏或教程代码,供初学者了解如何使用LGame...
3. **跨平台**:虽然主要针对Android,但LGame也支持Java SE环境,理论上可以移植到其他Java支持的平台。 4. **丰富的库支持**:LGame提供了大量的内置库,包括音频处理、图像绘制、物理引擎等,帮助开发者快速实现...
LGame-Android-0.2.9版是该系列的一个重要版本,包含了240个类和超过6万行代码,支持多种功能,包括但不限于底层图形接口、游戏控制、物理引擎、重力感应、资源存储和加密、地图绘制、精灵绘制、组件绘制、脚本操作...
LGame源码part4
4. **障碍物处理**:如果消除过程中有其他棋子挡路,需要考虑如何绕过或消除障碍。 5. **游戏状态管理**:记录当前游戏的状态,如剩余棋子数量、是否游戏结束等。 在LGame框架中,游戏的主循环(main loop)负责...
例如,`BattleManager`类负责整个战斗流程的控制,`Unit`接口定义了游戏中的角色单位,包含生命值、攻击力、防御力等相关属性,以及移动、攻击等基本行为。 2. 角色移动:在SRPG游戏中,角色的移动是非常关键的一...
4. **脚本语言支持**:LGAME可能支持使用脚本语言进行游戏逻辑编写,这使得非专业程序员也能相对容易地进行游戏逻辑设计,比如使用JavaScript或Lua等轻量级脚本语言。 5. **资源管理**:引擎应该有一个资源管理系统...
1. **环境配置**:首先,需要安装Android SDK并设置好开发环境,然后将LGame库导入到项目中,进行必要的配置。 2. **代码移植**:将已有的J2ME代码移植到LGame,需要注意一些API的细微差别,如事件处理、线程管理等...
4. **跨平台**:虽然主要面向Android,但LGame也有潜力支持其他平台,这对于希望扩大游戏覆盖范围的开发者来说是个不错的选择。 5. **丰富的游戏组件**:LGame提供了游戏所需的常用组件,如游戏场景管理、动画系统...
通过实践和研究提供的实例,开发者不仅可以掌握LGame的使用,也能深入理解游戏开发的基本原理和技巧。无论你是游戏开发的新手还是经验丰富的程序员,LGame都能为你提供一个高效且有趣的开发环境。
*支持多语言开发,LGame同时支持Java、C#、C++等多种语言,并且可以让Java语法向其它版本自动转化,能满足任意环境的语言需求。 *有完善的组件库支持,时间轴动画,缓动、UI系统、粒子动画、物理系统等并且针对不同...
标准LGame包由于使用OpenGL编程,在不同屏幕手机中进行缩放时,可以较为有效的减少甚至消除画面失真,而LSE与LAE包则难以避免这种现象的产生(特别是大画面的游戏,在较小屏幕的手机上运行时)。
【LGame入门学堂002】HelloWorld之搭建环境 教程的附件下载。 文章地址: http://blog.csdn.net/musicvs/article/details/7530117
对于初学者,建议先从基础教程入手,学习如何设置项目环境,导入Lgame库,并创建一个简单的Hello World程序。然后,逐步接触图形绘制、音频播放、物理模拟等高级特性。在实践中不断探索和积累,才能真正掌握Lgame的...
LGame引擎支持Eclipse IDE的集成,标签`eclipse_lgame_src`表明它提供了与Eclipse的无缝对接,使得开发者可以在熟悉的开发环境中高效地编写游戏代码。而`lgame_android_source`则表明LGame的Android源代码已经包含...
《LGame游戏引擎详解:0.5 Beta fix1版本解析》 LGame是一款开源的游戏开发框架,专为Java开发者设计,旨在简化游戏开发过程,提高开发效率。LGame-LGame-0.5-Beta-fix1.zip是该引擎的0.5 Beta版本的修复更新,针对...