新浪博客

36.游戏背景移动(二)

2013-08-28 14:45阅读:
本文使用的libgdx是0.98版本,可能和最新版有一些不同地方。全文内容仅供参考。

上一次我们讲解了如何实现“雷电类”游戏的背景移动,我们是通过游戏滚屏的方式,通过衔接2个不同的图片,最终共实现游戏背景的移动。在不同类型的游戏中,需要有不同的游戏背景滚动方式来实现,那么今天我们就来学习下第二章类型的游戏背景移动,也就是我们所说的“超级玛丽”类的游戏背景移动。
Libgdx游戏引擎(1群):187378034
Libgdx游戏引擎(2群):148848483
Libgdx游戏引擎(3群): 79168470


视频教程


1.需求分析


今天我们要实现一个超级玛丽的游戏背景移动,这个相对比较简单,在之前的博文中,我就实现过一个《碰撞检测》的超级马里奥和TiledMao地图图块的碰撞的实现,今天相对比较简单。


(1)首先,实现超级马里奥的人物移动的动画。
(2)其次,实现人物移动过程中的游戏背景移动

(3)最后,实现人物移动的按钮的触屏监听。


2.游戏素材


1.游戏图片。


(人物动画、按钮素材) (TiledMap的地图素材)
36.游戏背景移动(二) 36.游戏背景移动(二)
PS:这个游戏的素材,在之前的博文中都可以下载到,不过这个地图是后来在网上随便找的。毕竟只要是讲解原来,素材就不讲究那么精巧了。


3.算法实现

由于咱们这个例子是我的博文《碰撞检测》中的例子,所以这里就不做详细的介绍了,如果有有看不懂的同学,可以去我的博文《碰撞检测》中去详细的了解这个例子的内容,那么这里我就简单的介绍一下,实现我们这个例子的背景移动的部分代码。
1.更改马里奥的坐标,这个例子的是之前的,所以要修改y轴移动坐标,这里,要将带有碰撞检测的代码,修改为固定坐标。


如图:
36.游戏背景移动(二)


2.更改2个照相机的position位置,2D横版游戏重要是处理stage和tiledmap这个2个相机的观察点和人物移动坐标的关系就好了,这里简单的做一个赋值,但是原理是一样的,这里只是给大家一个简单的思路。


如图:


36.游戏背景移动(二)
3.舞台相机原理:不同的游戏元素,绘制是需要不同的相机,相机其实是一个投影矩形,根据不同的相机
可以实现,舞台和TiledMap的绘制。


如图:


36.游戏背景移动(二)
4.完整代码


1.TiledMapTest类代码。
package com.potato;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;
import com.badlogic.gdx.scenes.scene2d.Stage;
public class TiledMapTest implements ApplicationListener {
public static TiledMap map;
TileAtlas atlas;
TileMapRenderer render;
OrthographicCamera cam;
Stage stage;
Mario mario;
@Override
public void create() {
map = TiledLoader.createMap(Gdx.files.internal('data/level1.tmx'));
atlas = new TileAtlas(map, Gdx.files.internal('data/'));
render = new TileMapRenderer(map, atlas, 10, 10);
cam = new OrthographicCamera();
cam.setToOrtho(false, 800, 480);
stage = new Stage(480, 320, false);
mario = new Mario(0, 0);
setMario();
stage.addActor(mario);
stage.addActor(mario.buttonL);
stage.addActor(mario.buttonR);
Gdx.input.setInputProcessor(stage);
}
@Override
public void dispose() {
}
public void setMario() {
for (TiledObjectGroup group : map.objectGroups) {
for (TiledObject object : group.objects) {
if ('mario'.equals(object.name)) {
mario.x = object.x;
mario.y = render.getMapHeightUnits() - object.y;
}
}
}
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
cam.position.x = mario.x;

stage.getCamera().position.x = mario.x;
cam.update();
System.out.println('TiledMap的相机是: ' + cam.position.x);
System.out.println('stage 照相机是: '+ stage.getCamera().position.x);
System.out.println('马里奥的x坐标是: '+mario.x);

render.render(cam);

stage.act();
stage.draw();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
2.Mario类中代码。


package com.potato;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
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 Mario extends Actor {
public static float x;
public static float y;
public float statetime;
Texture texture;
TextureRegion currentFrame;
ImageButton buttonL;
ImageButton buttonR;
Animation aniRight;
Animation aniLeft;
Animation aniIdle;
STATE state;
enum STATE {
Left, Right, Idel
};
public Mario(float x, float y) {
this.x = x;
this.y = y;
this.statetime = 0;
this.show();
state = STATE.Idel;
}
@Override
public void act(float delta) {
statetime += delta;
this.update();
this.check();
super.act(delta);
}
@Override
public void draw(SpriteBatch batch, float parentAlpha) {
batch.draw(currentFrame, x, y);
}
public void update() {
// 能否像下走。
if (Collision.downEnable(this.x, this.y)) {
// this.y -=6.5*statetime;
this.y = 87;
}
// 能否像左走
if (state == STATE.Left && Collision.leftEnable(x, y, 64, 64)) {
this.x -= 1.5f;
}
if (state == STATE.Right) {
this.x += 1.5f;
}
}
public void check() {
if (state == STATE.Left) {
currentFrame = aniLeft.getKeyFrame(statetime, true);
} else if (state == STATE.Right) {
currentFrame = aniRight.getKeyFrame(statetime, true);
} else if (state == STATE.Idel) {
currentFrame = aniIdle.getKeyFrame(statetime, true);
}
}
public void show() {
texture = new Texture(Gdx.files.internal('data/Mario.png'));
TextureRegion[][] spilt = TextureRegion.split(texture, 64, 64);
TextureRegion[][] miror = TextureRegion.split(texture, 64, 64);
for (TextureRegion[] region1 : miror) {
for (TextureRegion region2 : region1) {
region2.flip(true, false);
}
}
// 右
TextureRegion[] regionR = new TextureRegion[3];
regionR[0] = spilt[0][1];
regionR[1] = spilt[0][2];
regionR[2] = spilt[0][0];
aniRight = new Animation(0.1f, regionR);
// 左
TextureRegion[] regionL = new TextureRegion[3];
regionL[0] = miror[0][1];
regionL[1] = miror[0][2];
regionL[2] = miror[0][0];
aniLeft = new Animation(0.1f, regionL);
// 空闲
TextureRegion[] regionI = new TextureRegion[1];
regionI[0] = spilt[0][0];
aniIdle = new Animation(0.1f, regionI);
buttonL = new ImageButton(new TextureRegionDrawable(spilt[1][0]),
new TextureRegionDrawable(spilt[1][1]));
buttonR = new ImageButton(new TextureRegionDrawable(miror[1][0]),
new TextureRegionDrawable(miror[1][1]));
buttonL.setPosition(20, 20);
buttonR.setPosition(100, 20);
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;
}
});
}
}
3.Colision类中代码。
package com.potato;
import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
import com.badlogic.gdx.math.MathUtils;
public class Collision {

public static int tile[][];
public static TiledMap map;
static{
map = TiledMapTest.map;
tile = map.layers.get(0).tiles;
}


public static boolean leftEnable (float x,float y,float width,float height) {
int m1 = MathUtils.ceilPositive((x) / map.tileWidth); //
int n1 = tile.length - MathUtils.ceilPositive((y) / map.tileHeight);
int m7 = MathUtils.ceilPositive((x) / map.tileWidth);
int n7 = tile.length
- MathUtils.ceilPositive((y + height / 2) / map.tileHeight);
int m8 = MathUtils.ceilPositive((x) / map.tileWidth);
int n8 = tile.length
- MathUtils.ceilPositive((y + height) / map.tileHeight);


if (tile[n1][m1 - 1] != 0 || tile[n7][m7 - 1] != 0
|| tile[n8][m8 - 1] != 0) {
return false;
} else
return true;
}
public static boolean downEnable(float x, float y) {
int m1 = MathUtils.ceilPositive((x + 12) / map.tileWidth);
int n1 = tile.length - MathUtils.ceilPositive((y - 1) / map.tileHeight);
int m2 = MathUtils.ceilPositive((x + 24) / map.tileWidth);
int n2 = tile.length - MathUtils.ceilPositive((y - 1) / map.tileHeight);
int m3 = MathUtils.ceilPositive((x + 40) / map.tileWidth);
int n3 = tile.length - MathUtils.ceilPositive((y - 1) / map.tileHeight);
if (tile[n3][m3 - 1] != 0 || tile[n2][m2 - 1] != 0
|| tile[n1][m1 - 1] != 0) {
return false;
} else {
return true;
}
}
}
效果图:
点击播放
源码下载:http://pan.baidu.com/share/link?shareid=2672238187&uk=3456175979


写在最后,关于libgdx中游戏背景移动,就暂时给大家介绍到这里,希望对大家有所帮助,下一篇是是关于libgdx框架中《Rectangle的使用》的博文,我会继续介绍Rectangle的使用。如果大家有什么问题可以加我QQ:316344618,一起讨论下。PS:请大家多多留言交流,大家的评论土豆都会看的,也欢迎大家来libgdx的中文论坛来发帖交流,土豆也是会给大家及时解答的。
------------奋斗小土豆丶
2013 年 8 月 28 日

我的更多文章

下载客户端阅读体验更佳

APP专享