libGDX游戏开发之NPC敌人事件(六)

23 篇文章 3 订阅
23 篇文章 8 订阅

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的视角。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌康ACG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值