libGDX游戏开发之NPC敌人事件(六)
libGDX系列
,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm…国内用libgdx比较少,多数情况需要去官网和google找资料,相互学习的可以加我联系方式。
libGDX游戏开发之NPC敌人事件(六)
前面的文章提到在地图中添加敌人,这只时候不参与事件点击等一些操作的场景,不适合RPG游戏,因为RPG游戏会点击怪物或者点击NPC。
通过阅读代码我发现文理Texture
、精灵Sprite
等无法添加鼠标点击等事件。前面提到的舞台Stage
标签可以添加事件。通过阅读源码发现他们是继承Actor
实现的。那么我们的NPC、敌人也能通过继承它实现。
编写一个NPC、敌人Actor
NPC
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.Disposable;
/**
* @author lingkang
* @date 2021/10/10 15:01
* @description
*/
public class NPCActor extends Actor implements Disposable {
private Texture npc;
private float npcX = 200, npcY = 400; // NPC的位置
public NPCActor(SpriteBatch batch) {
// 任意找一张图片,我这里选择70*105 最好是2的幂大小
npc = new Texture(Gdx.files.internal("npc.png"));
// 设置npc演员的大小
setWidth(70);
setHeight(105);
}
/**
* 重写演员的绘制方法
*/
@Override
public void draw(Batch batch, float parentAlpha) {
// 将地图上的位置映射到相机上
Vector3 project = ActorEventApplicationAdapter.camera.project(new Vector3(npcX, npcY, 0));
batch.draw(npc, project.x, project.y,
// 将纹理设置绘制起点和大小
0, 0, 70, 105);
// 设置npc演员的位置
setPosition(project.x, project.y);
}
@Override
public void dispose() {
// 防止内存溢出
npc.dispose();
}
}
编写相机渲染
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
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.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.viewport.ScalingViewport;
/**
* @author lingkang
* @date 2021/10/10 15:12
* @description
*/
public class ActorEventApplicationAdapter extends ApplicationAdapter {
// 精灵批处理
private SpriteBatch batch;
// 地图相关
private TmxMapLoader maploader;
private TiledMap map;
// 公开这个相机
public static OrthographicCamera camera;// 相机
private OrthogonalTiledMapRenderer renderer;
private float mapX = 128f, mapY = 128f; // 地图的位置,用于相机观察这个位置
private float moveSpeed = 4f; // 相机移动的速度
// 舞台
public Stage stage;
// 玩家
private TextureRegion player;
@Override
public void create() {
batch = new SpriteBatch();
// 加载地图和地图渲染
maploader = new TmxMapLoader();
// 地图是 块=20 像素大小:1280x960 随意找个地图,不加也行
map = maploader.load("worldmap/worldmap.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1);// 将地图单元设置为 1
camera = new OrthographicCamera();
// 相机可看到的宽高
camera.setToOrtho(false, 800, 600);
camera.position.x = mapX;
camera.position.y = mapY;
camera.update();
// 玩家 大小 256*256 随意找一张图片
player = new TextureRegion(new Texture("worldmap/badlogic.jpg"), 256, 256);
ScalingViewport scalingViewport = new ScalingViewport(Scaling.stretch,
Gdx.graphics.getWidth(),
Gdx.graphics.getHeight(),
new OrthographicCamera()); // 舞台所在的相机与我们的相机不是同一个
// 必须保持舞台上的精灵批处理是同一个
stage = new Stage(scalingViewport, batch);
NPCActor npcActor = new NPCActor(batch);
// 添加npc点击事件
npcActor.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// 注意,这里的X,Y是NPC大小内的位置,不是相机的位置
System.out.println(String.format("NPC被点击!NPC身体上的位置:%f,%f ",
x, y));
return false;
}
});
stage.addActor(npcActor);
Gdx.input.setInputProcessor(stage); // 必须添加输入事件
}
@Override
public void render() {
// 清除相机内容
ScreenUtils.clear(225f, 225f, 225f, 0.4f);
// 用户的输入
userInput();
// 更新相机
camera.position.x = mapX;
camera.position.y = mapY;
camera.update();// 一定要记得更新这个相机的视图
// 摄影机查看并渲染内容
renderer.setView(camera);
renderer.render();
// 绘制玩家, -128 是因为绘制的原点是中央
batch.begin();
batch.draw(player, Gdx.graphics.getWidth() / 2 - 128, Gdx.graphics.getHeight() / 2 - 128);
batch.end();
stage.draw();
stage.act();// 演员事件
}
/**
* 轮询,用户输入
*/
private void userInput() {
if (Gdx.input.isKeyPressed(Input.Keys.LEFT) || Gdx.input.isKeyPressed(Input.Keys.A)) {
if (mapX < 64) {
mapX = 64; // 不给玩家走出屏幕外
} else
mapX -= moveSpeed;
}
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) || Gdx.input.isKeyPressed(Input.Keys.D)) {
if (mapX > 1280 - 64) {
mapX = 1280 - 64;// 不给玩家走出屏幕外
} else
mapX += moveSpeed;
}
if (Gdx.input.isKeyPressed(Input.Keys.UP) || Gdx.input.isKeyPressed(Input.Keys.W)) {
if (mapY > 960 - 64) {
mapY = 960 - 64;// 不给玩家走出屏幕外
} else
mapY += moveSpeed;
}
if (Gdx.input.isKeyPressed(Input.Keys.DOWN) || Gdx.input.isKeyPressed(Input.Keys.S)) {
if (mapY < 64) {
mapY = 64;// 不给玩家走出屏幕外
} else
mapY -= moveSpeed;
}
}
}
编写启动入口
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import top.lingkang.enemy.ActorEventApplicationAdapter;
/**
* @author lingkang
* @date 2021/10/10 15:21
* @description
*/
public class ActorEventApp {
public static void main(String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.width = 1280;
config.height = 960;
new LwjglApplication(new ActorEventApplicationAdapter(), config);
}
}
效果:
控制台输出我们的点击事件:
后记
类似地,我们将上面的NPC改为敌人,鼠标选择后,按技能键一顿输出就是RPG。
打赏
觉得内容不错就赏作者一杯咖啡吧!(恰饭)
后续我会出更多libgdx文章:寻路、寻路算法、打怪,以RPG的视角。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!