libgdx学习笔记系列(四) Action动作及游戏开发的“MVC”
程序员文章站
2022-05-21 09:45:25
...
这篇笔记少写点。
因为学习到现在我发现了一个重要的问题。
问题稍后再说,先让我那个原地跑的小人会自己在屏幕中跑动吧。
查看官方开发者手册,按照示例写吧。然后被作者坑了。好像手册好久没更新了。(估计作者顾不上),我完全找不到手册中的方法。你妹的 ,还是直接API吧。先看下Actions类的API
长长的一串静态方法。好了,我也不贴API的东西了。大家可以自己去看。
大概看了下,其实主要三类action
关于动画的action,综合的action,还有一些其他的action
然后主要的就是对这些action的控制的一些类。
找找控制移动的Action,我看到了个MoveToAction,OK直接去源码看看
Moves an actor from its current position to a specific position
把一个演员从当前位置移动到一个指定的位置。找对了。就是我们需要的。
估计大家看方法名称就可以看出作用了。begin,end神马的。
好了修改下create的方法
因为action类主要作用是改变演员的一些状态,它不会自动帮我们把人物从左边移动到右边,所以我们还需要修改下演员类。注释都写的很清楚了。就不解释了。
只是简单的介绍了下动作类,如果还不是很清楚,建议看这篇文章。
http://blog.sina.com.cn/s/blog_940dd50a0101d0ho.html
介绍的很详细。
好了说下开发中的问题。
因为之前一直在做web开发,手机开发自己做着玩过,游戏是第一次。
经过几天的学习我发现一个很重要的问题。游戏代码写的很混乱。随着代码量不断膨胀,都不知道会写成什么样子。
想想以前web开发中一般会使用MVC模式开发。也就是模型,视图,控制三层结构。在这个结构上我们甚至会进一步解耦、分层。游戏中可不可以呢。答案当然是可以的。
MVC是一种软件模式。适用于大部分编程领域。怎么实现呢,如何分层呢。
先分析下libgdx游戏开发的特征,创建演员,加入舞台,然后显出给玩家,与玩家进行交互式操作。
然后我们和web MVC结构进行简单对比。演员,舞台,就像是pojo模型对象,当然实际上这并不是简单的pojo。渲染显示就相当于我们的web中的view层,交互操作。就类似于web开发中的控制层。
恩,大概就是这个样子。
很可能大家已经都这么做了,只是咱不是菜鸟吗,刚刚发现,明天整理下代码。
本篇代码改动很少,就不提供源码了。
因为学习到现在我发现了一个重要的问题。
问题稍后再说,先让我那个原地跑的小人会自己在屏幕中跑动吧。
查看官方开发者手册,按照示例写吧。然后被作者坑了。好像手册好久没更新了。(估计作者顾不上),我完全找不到手册中的方法。你妹的 ,还是直接API吧。先看下Actions类的API
长长的一串静态方法。好了,我也不贴API的东西了。大家可以自己去看。
大概看了下,其实主要三类action
关于动画的action,综合的action,还有一些其他的action
然后主要的就是对这些action的控制的一些类。
找找控制移动的Action,我看到了个MoveToAction,OK直接去源码看看
/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.scenes.scene2d.actions; /** Moves an actor from its current position to a specific position. * @author Nathan Sweet */ public class MoveToAction extends TemporalAction { private float startX, startY; private float endX, endY; protected void begin () { startX = actor.getX(); startY = actor.getY(); } protected void update (float percent) { actor.setPosition(startX + (endX - startX) * percent, startY + (endY - startY) * percent); } public void setPosition (float x, float y) { endX = x; endY = y; } public float getX () { return endX; } public void setX (float x) { endX = x; } public float getY () { return endY; } public void setY (float y) { endY = y; } }
Moves an actor from its current position to a specific position
把一个演员从当前位置移动到一个指定的位置。找对了。就是我们需要的。
估计大家看方法名称就可以看出作用了。begin,end神马的。
好了修改下create的方法
@Override public void create() { //加载字体文件从电脑上拷贝的华文琥珀字体,当然你可以使用任意一种中文字体。 FreeTypeFontGenerator freeTypeFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("data/font/STHUPO.TTF")); //关于字体的一些配置参数,详细的可以看官方API和FreeTypeFontGenerator的源码 FreeTypeFontGenerator.FreeTypeFontParameter fontParameter = new FreeTypeFontGenerator.FreeTypeFontParameter(); //注意这不是我们要显示的文字,其实相当于我们上篇使用的文字工具编辑的字符串内容, // 这里是默认的字符串加上了我们要使用的汉字。 fontParameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "你好"; //根据参数设置生成的字体数据,这就相当于上篇的myfont.fnt文件和myfont.png FreeTypeFontGenerator.FreeTypeBitmapFontData fontData = freeTypeFontGenerator.generateData(fontParameter); //及时释放资源,避免内存泄漏,因为中文字体文件一般都比较大 freeTypeFontGenerator.dispose(); //从字面看,其实也是加载的图片 bitmapFont = new BitmapFont(fontData, fontData.getTextureRegions(), false); batch = new SpriteBatch(); texture = new Texture(Gdx.files.internal("data/image/girl.png")); Texture[] girlTextures = new Texture[16]; //加载人物动作的16幅图片 for (int i = 0; i < 16; i++) { girlTextures[i] = new Texture(Gdx.files.internal("data/image/" + (i + 1) + ".png")); } //初始化演员类 GirlActor girlActor = new GirlActor(girlTextures); girlActor.setPosition(0,0); //初始化舞台,舞台大小为屏幕大小 stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true); //黑色显示 Label.LabelStyle labelStyle = new Label.LabelStyle(new BitmapFont(), Color.BLACK); //显示内容 fps = new Label("FPS:", labelStyle); fps.setName("fps"); //显示在左上角位置,减去显示字体的高度,要不然会跑到屏幕外面,根本看不到 fps.setY(Gdx.graphics.getHeight() - fps.getHeight()); fps.setX(0); //初始化下,反正是静态的,直接赋值吧,直接跑到屏幕右边,别忘了减去人物的宽度。要不然跑没影了。 //最后一个参数跑到目的地需要的时间,时间越短,移动越快 MoveToAction moveTo = Actions.moveTo(Gdx.graphics.getWidth()-texture.getWidth(), 0, 5); // SequenceAction是顺序执行,并且可以执行多个action,我们现在先让她跑到右边,然后倒退回起点 //往回跑 MoveToAction goBack = Actions.moveTo(0, 0, 5); //先执行跑到右边的action,然后执行跑回来的action SequenceAction sequenceAction = Actions.sequence(moveTo,goBack); sequenceAction.setActor(girlActor); //无限循环不停来回跑 RepeatAction repeatAction = Actions.repeat(RepeatAction.FOREVER, sequenceAction); girlActor.addAction(repeatAction); //把演员放入舞台 stage.addActor(girlActor); stage.addActor(fps); }
因为action类主要作用是改变演员的一些状态,它不会自动帮我们把人物从左边移动到右边,所以我们还需要修改下演员类。注释都写的很清楚了。就不解释了。
package com.me.mygdxgame; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; public class GirlActor extends Actor { TextureRegion[] girlRegion; float stateTime; //当前帧 TextureRegion currentFrame; Animation animation; public GirlActor(Texture[] texture) { girlRegion = new TextureRegion[16]; //把Texture转换下 for (int i = 0; i < 16; i++) { girlRegion[i] = new TextureRegion(texture[i]); } //动画播放,参数为动画播放速度。和纹理数组 //0.06*16=0.96 大概就是1秒钟播放完这个动画。 animation = new Animation(0.06f, girlRegion); } @Override public void draw(Batch batch, float parentAlpha) { stateTime += Gdx.graphics.getDeltaTime(); //下一帧 currentFrame = animation.getKeyFrame(stateTime, true); //2,3参数还记得吧,就是我注释掉的下边的代码,这个帧绘制的位置信息。我们现在修改为实时获取演员位置信息。这样才会动起来 //4,5参数这个是定义原点的。我还默认左下角为起始原点。 //6,7是对当前帧大小的改变,我用的还是原来大小,如果你修改它的值会发现,人物大小形状会发生变化 //8,9人物动态缩放,暂时我没用,其实就是逐渐放大或者缩小 //10,人物旋转暂时也不用 batch.draw(currentFrame,getX(),getY(),0,0,currentFrame.getRegionWidth(),currentFrame.getRegionHeight(),getScaleX(),getScaleY(),getRotation()); // batch.draw(currentFrame,0,0); } }
只是简单的介绍了下动作类,如果还不是很清楚,建议看这篇文章。
http://blog.sina.com.cn/s/blog_940dd50a0101d0ho.html
介绍的很详细。
好了说下开发中的问题。
因为之前一直在做web开发,手机开发自己做着玩过,游戏是第一次。
经过几天的学习我发现一个很重要的问题。游戏代码写的很混乱。随着代码量不断膨胀,都不知道会写成什么样子。
想想以前web开发中一般会使用MVC模式开发。也就是模型,视图,控制三层结构。在这个结构上我们甚至会进一步解耦、分层。游戏中可不可以呢。答案当然是可以的。
MVC是一种软件模式。适用于大部分编程领域。怎么实现呢,如何分层呢。
先分析下libgdx游戏开发的特征,创建演员,加入舞台,然后显出给玩家,与玩家进行交互式操作。
然后我们和web MVC结构进行简单对比。演员,舞台,就像是pojo模型对象,当然实际上这并不是简单的pojo。渲染显示就相当于我们的web中的view层,交互操作。就类似于web开发中的控制层。
恩,大概就是这个样子。
很可能大家已经都这么做了,只是咱不是菜鸟吗,刚刚发现,明天整理下代码。
本篇代码改动很少,就不提供源码了。