MyGdxGame.java:
package com.mygdx.game;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.maps.MapLayer;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.MapProperties;
import com.badlogic.gdx.maps.objects.EllipseMapObject;
import com.badlogic.gdx.maps.objects.PolygonMapObject;
import com.badlogic.gdx.maps.objects.RectangleMapObject;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.objects.TiledMapTileMapObject;
import com.badlogic.gdx.maps.tiled.renderers.IsometricTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile;
import com.badlogic.gdx.math.Ellipse;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Polygon;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import org.w3c.dom.css.Rect;
public class MyGdxGame extends ApplicationAdapter {
private static final float SCALE = 0.5926f;
private static final int VIRTUAL_WIDTH = (int)(960 * SCALE);
private static final int VIRTUAL_HEIGHT = (int)(540 * SCALE);
private static final float CAMERA_SPEED = 100.0f;
private OrthographicCamera camera;
private Viewport viewport;
private SpriteBatch batch;
private TiledMap map;
private TmxMapLoader loader;
private OrthogonalTiledMapRenderer renderer;
private Vector2 direction;
private Array<Sprite> triggers;
private Music song;
Stage stage;
Major major;
@Override
public void create() {
int screenWidth = Gdx.graphics.getWidth();
int screenHeight = Gdx.graphics.getHeight();
Gdx.app.log("MyGdxGame", "create screenWidth:"+screenWidth+" screenHeight:"+screenHeight);
Gdx.app.log("MyGdxGame", "create Gdx.app.getType():"+Gdx.app.getType()+" Application.ApplicationType.Desktop:"+Application.ApplicationType.Desktop);
camera = new OrthographicCamera();
//camera.setToOrtho(false, 480, 336);
viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, camera);
batch = new SpriteBatch();
loader = new TmxMapLoader();
map = loader.load("data/maps/tiled/tiles.tmx");
renderer = new OrthogonalTiledMapRenderer(map, batch);
direction = new Vector2();
stage = new Stage(viewport);//new ScreenViewport());
Gdx.input.setInputProcessor(stage);
major = new Major(this, 0, 0, SCALE, map);
stage.addActor(major);
stage.addActor(major.buttonL);
stage.addActor(major.buttonR);
processMapMetadata();
}
@Override
public void dispose() {
map.dispose();
renderer.dispose();
stage.dispose();
batch.dispose();
if(song != null)
song.dispose();
}
@Override
public void render() {
Gdx.gl.glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
updateCamera();
renderer.setView(camera);
renderer.render();
stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
stage.draw();
}
@Override
public void resize(int width, int height) {
//viewport.update(width, height);
stage.getViewport().update(width, height, true);
}
int screenPage = -1;
int moveDir = 0;
public void updateCameraExtenal(int page, int dir){
if(screenPage != page)
screenPage = page;
moveDir = dir;
}
private void updateCamera() {
direction.set(0.0f, 0.0f);
int mouseX = Gdx.input.getX();
int mouseY = Gdx.input.getY();
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
if (Gdx.input.isKeyPressed(Input.Keys.LEFT) || (Gdx.input.isTouched() && mouseX < width * 0.25f && mouseY < height * 1.0f)) {
direction.x = -20;
}
else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) || (Gdx.input.isTouched() && mouseX > width * 0.75f && mouseY < height * 1.0f)) {
direction.x = 20;
}
int offset = 0;
if(moveDir == 1)
offset = 10;
else if(moveDir == -1)
offset = -10;
if(screenPage == 2){
if(moveDir == 1) {
if (camera.position.x < 864)
direction.x = offset;
else
screenPage = -1;
}else if(moveDir == -1) {
if (camera.position.x > 864)
direction.x = offset;
else
screenPage = -1;
}
}else if(screenPage == 3){
if(moveDir == 1) {
if (camera.position.x < 1824)
direction.x = offset;
else
screenPage = -1;
}else if(moveDir == -1) {
if (camera.position.x > 1824)
direction.x = offset;
else
screenPage = -1;
}
}else if(screenPage == 1){
if(moveDir == 1) {
if (camera.position.x < 0)
direction.x = offset;
else
screenPage = -1;
}else if(moveDir == -1) {
if (camera.position.x > 0)
direction.x = offset;
else
screenPage = -1;
}
}
//direction.nor().scl(CAMERA_SPEED).scl(Gdx.graphics.getDeltaTime());;
camera.position.x += direction.x;
camera.position.y += direction.y;
//Gdx.app.log("MyGdxGame", "updateCamera camera.position.x:"+camera.position.x);
TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get(0);
float cameraMinX = viewport.getWorldWidth() * 0.5f;
float cameraMinY = viewport.getWorldHeight() * 0.5f;
float cameraMaxX = layer.getWidth() * layer.getTileWidth() - cameraMinX;
float cameraMaxY = layer.getHeight() * layer.getTileHeight() - cameraMinY;
camera.position.x = MathUtils.clamp(camera.position.x, cameraMinX, cameraMaxX);
camera.position.y= MathUtils.clamp(camera.position.y, cameraMinY, cameraMaxY);
major.setXOffset(camera.position.x /*- (VIRTUAL_WIDTH/2)*/);
camera.update();
}
private void processMapMetadata() {
// Load music
String songPath = map.getProperties().get("music", String.class);
if(songPath != null) {
song = Gdx.audio.newMusic(Gdx.files.internal(songPath));
if(song != null) {
song.setLooping(true);
song.play();
}
}
MapLayer mapLayer = map.getLayers().get(0);
Gdx.app.log("MyGdxGame", "processMapMetadata mapLayer:" + mapLayer);
int width = ((TiledMapTileLayer)mapLayer).getWidth();
int height = ((TiledMapTileLayer)mapLayer).getHeight();
Gdx.app.log("MyGdxGame", "processMapMetadata width:"+width+" height:"+height);
float tileWidth = ((TiledMapTileLayer)mapLayer).getTileWidth();
float tileHeight = ((TiledMapTileLayer)mapLayer).getTileHeight();
Gdx.app.log("MyGdxGame", "processMapMetadata tileWidth:"+((TiledMapTileLayer)mapLayer).getTileWidth()+" tileHeight:"+((TiledMapTileLayer)mapLayer).getTileHeight());
major.setTileSize(tileWidth, tileHeight);
if(mapLayer instanceof TiledMapTileLayer){
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
if(((TiledMapTileLayer)mapLayer).getCell(x, y) != null) {
Gdx.app.log("MyGdxGame", "processMapMetadata x:"+x+" y:"+y);
}
}
}
}
}
}
Major.java:
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
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.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
public class Major extends Actor{
float iconWidth = 32.0f, iconHeight = 48.0f;
public static float x ;
public static float y ;
public float statetime;
private TiledMap map;
Texture texture;
TextureRegion currentFrame;
ImageButton buttonL;
ImageButton buttonR;
Animation aniRight;
Animation aniLeft;
Animation aniIdle;
STATE state;
float mapWidth, mapHeight;
float tileWidth, tileHeight;
float scaleSize = 0.0f;
float xOffset = 0.0f;
MyGdxGame gdxgame;
enum STATE {
Left,Right,Idel
};
public Major(MyGdxGame myGdxGame, float x,float y, float scale, TiledMap tiledMap) {
gdxgame = myGdxGame;
map = tiledMap;
scaleSize = scale;
this.x = x;
this.y = y;
this.statetime = 0;
this.show();
state = STATE.Idel;
}
public void setMapSize(float width, float height){
mapWidth = width;
mapHeight = height;
}
public void setTileSize(float width, float height){
tileWidth = width;
tileHeight = height;
this.y = tileHeight;
}
public void setXOffset(float offset){
xOffset = offset;
buttonL.setPosition(xOffset, 0);
buttonR.setPosition(xOffset + 32 / scaleSize, 0);
}
@Override
public void draw(Batch batch, float parentAlpha) {
// TODO Auto-generated method stub
statetime += Gdx.graphics.getDeltaTime();
this.update();
this.check();
batch.draw(currentFrame, x, y, 0.0f, 0.0f, iconWidth, iconHeight, 1.0f, 1.0f, 0.0f);
}
private boolean leftCheck(float x){
float startX = x;
int startRow = (int)(startX/32);
int startColumn = 1;
float endX = x+32;
int endRow = (int)(endX/32);
int endColumn = 1;
if(((TiledMapTileLayer)map.getLayers().get(0)).getCell(startRow, startColumn) != null
|| ((TiledMapTileLayer)map.getLayers().get(0)).getCell(endRow, endColumn) != null){
this.y = tileHeight * 2;
return true;
}else {
this.y = tileHeight;
return false;
}
}
private boolean rightCheck(float x){
float startX = x+32;
startX -= 1;
if(startX < 0.0f) startX = 0.0f;
int startRow = (int)(startX/32);
int startColumn = 1;
float endX = x;
int endRow = (int)(endX/32);
int endColumn = 1;
if(((TiledMapTileLayer)map.getLayers().get(0)).getCell(startRow, startColumn) != null
|| ((TiledMapTileLayer)map.getLayers().get(0)).getCell(endRow, endColumn) != null){
this.y = tileHeight * 2;
return true;
}else {
this.y = tileHeight;
return false;
}
}
public void update() {
if(state == STATE.Left){
if(this.x >= 544 && (this.x - 4) < 544){
gdxgame.updateCameraExtenal(1, -1);
}else if(this.x >= 928 && (this.x - 4) < 928){
gdxgame.updateCameraExtenal(2, -1);
}
leftCheck(this.x);
this.x -= 4;
if(this.x < 0) this.x = 0;
}else if (state == STATE.Right) {
if(this.x <= 544 && (this.x + 4) > 544){
gdxgame.updateCameraExtenal(2, 1);
}else if(this.x <= 1113 && (this.x + 4) > 1113){
gdxgame.updateCameraExtenal(3, 1);
}
rightCheck(this.x);
this.x +=4;
if(this.x >= (45*32-32)) this.x = (45*32-32);
}else {
gdxgame.updateCameraExtenal(-1, 0);
this.y = tileHeight;
}
this.x = x;
}
public void check() {
if(state == STATE.Left) {
currentFrame = aniLeft.getKeyFrame(statetime, true);
//state = STATE.Idel;
}else if (state == STATE.Right) {
currentFrame = aniRight.getKeyFrame(statetime, true);
//state = STATE.Idel;
}else if (state == STATE.Idel) {
currentFrame = aniIdle.getKeyFrame(statetime, true);
}
}
public void show() {
texture = new Texture(Gdx.files.internal("data/animation.png"));
TextureRegion[][] spilt = TextureRegion.split(texture, (int)iconWidth, (int)iconHeight);
TextureRegion[][] buttons = TextureRegion.split(texture, (int)iconWidth, (int)iconHeight);
TextureRegion[] regionR = spilt[2];
aniRight = new Animation(0.1f, regionR);
TextureRegion[] regionL = spilt[1];
aniLeft = new Animation(0.1f, regionL);
TextureRegion[] regionI = new TextureRegion[1];
regionI[0] = spilt[0][0];
aniIdle = new Animation(0.1f, regionI);
TextureRegion[] buttonsRegion = new TextureRegion[4];
buttonsRegion[0] = buttonsRegion[1] = new TextureRegion(texture, 0, 192, 64, 64);
buttonsRegion[2] = buttonsRegion[3] = new TextureRegion(texture, 64, 192, 64, 64);
buttonL = new ImageButton(new TextureRegionDrawable(buttonsRegion[0]), new TextureRegionDrawable(buttonsRegion[1]));
buttonR = new ImageButton(new TextureRegionDrawable(buttonsRegion[2]), new TextureRegionDrawable(buttonsRegion[3]));
buttonL.setOrigin(0, 0);
buttonL.setPosition(xOffset, 0);
buttonL.setSize(32, 32);
buttonL.setScale(1/scaleSize);
buttonL.getImage().setFillParent(true);
buttonR.setOrigin(0, 0);
buttonR.setPosition(xOffset + 32/scaleSize, 0);
buttonR.setSize(32, 32);
buttonR.setScale(1/scaleSize);
buttonR.getImage().setFillParent(true);
buttonL.addListener(new InputListener(){
@Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
state = STATE.Idel;
super.touchUp(event, x, y, pointer, button);
}
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
state = STATE.Left;
return true;
}
});
buttonR.addListener(new InputListener(){
@Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
state = STATE.Idel;
super.touchUp(event, x, y, pointer, button);
}
@Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
state = STATE.Right;
return true;
}
});
}
}
效果图:
tiles.tmx:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="45" height="10" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="tukuai" tilewidth="32" tileheight="32" spacing="1" margin="1">
<image source="tiles.png" width="512" height="256"/>
</tileset>
<layer name="块层 1" width="45" height="10">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,0,0,0,0,0,0,0,0,0,0,52,0,0,0,0,0,0,0,0,0,
37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37
</data>
</layer>
</map>
tiles.png:
animation.png:
本文详细介绍使用LibGDX框架进行2D游戏开发的过程,包括游戏初始化设置、地图加载渲染、角色动画处理及屏幕间平滑过渡等核心功能实现。
438

被折叠的 条评论
为什么被折叠?



