gpt4 book ai didi

java - Actor 之间的事件

转载 作者:太空宇宙 更新时间:2023-11-04 15:08:15 25 4
gpt4 key购买 nike

我正在尝试使用事件对 actor 执行某些操作,但我不知道如何正确执行此操作。

我的屏幕上有一个按钮和一个文本(仅作为示例)。他们都是舞台上的 Actor 我的目的是:如果我点击按钮,我想更改文本

我在按钮上添加监听器,我得到了点击,但我不知道如何将事件(或其他任何内容)发送到我的文本来设置它。

具有阶段定义的主类及其

public class AGame implements ApplicationListener {
private WorldRendererTouchPad renderer;
private Stage stage;
private static Vector3 cameraVelocity=new Vector3(0,0,0);

private ButtonJump button;

public static final int SCREEN_WIDTH=800;
public static final int SCREEN_HEIGHT=480;

public void create() {
stage = new Stage();
stage.setViewport(SCREEN_WIDTH, SCREEN_HEIGHT, true);
stage.getCamera().translate(-stage.getGutterWidth(), -stage.getGutterHeight(), 0);

renderer = new MyRenderer(SCREEN_WIDTH, SCREEN_HEIGHT);
stage.addActor(renderer);
renderer.create();

button=new ButtonJump();
stage.addActor(button);
button.create();

Gdx.input.setInputProcessor(stage);
}
....
resize and other methods
}

MyRenderer 类(包含文本参与者):

public class MyRenderer  {
private TextTest text;

public MyRenderer(float screenWidth, float screenHeight) {
setBounds(0, 0, screenWidth, screenHeight);
}

public void create() {
this.initActors();
}

private void initActors() {
text=new TextTest("Hello world!");
addActor(text);
}


// is it usefull?
public void setText(String newText) {
text.setText(newText);

}

}

和 ButtonJump 类(在这里扩展 MyButton 以定义 Skin 和 ButtonStyle)

public class ButtonJump extends MyButton {
public boolean isJump=false;

private static InputListener buttonListener=new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("event" , "="+event.toString());

// do something to update text

return true;
}
};


public ButtonJump() {
super();
}

public void create() {
this.setPosition(getStage().getWidth()-60, 30);
this.addCaptureListener(buttonListener);
}

public void capture() {
if (this.isJump)
Gdx.app.log("jump button", "Jump is set");
else
Gdx.app.log("jump button", "No jump");

}
}

最佳答案

如果您使用点击监听器,则需要让其他参与者持有对其的引用以在点击时调用方法。让所有Actor都互相认识可不太好。使用匿名方式。

游戏中有一个“通用”系统。

如果您确实想使用事件,请实现一个事件系统。因此,您有一个接口(interface) Listen 和一个接口(interface) Event_Handler。在游戏开始时,您会初始化一个事件处理程序的实现。界面至少应该是这样的:

public interface Interface_EventHandler extends Disposable
{
public void handleEvent(final Event... e);
public void registerListener(final Interface_Listen listener,
final Event_Type... type);
public void unregisterListener(final Interface_Listen... listener);
public void unregisterAllListener();
public void unregisterAllListener(final Event_Type... type);
public void processEvents();
public void processEvents(final int maxTimeInMS);
}

好的,现在它是如何工作的。该处理程序有一个 HashMap ,其中所有事件类型作为键,监听器列表作为值。因此,如果有人想要注意到某个事件,他可以在处理程序中的 registerListerner 中注册正确的 Event_Type(枚举)。它需要有接口(interface) Listen 来获取事件。现在,每个人都可以使用 handleEvent(...) 方法将事件推送到处理程序中。甚至不止一个..(可变参数)..

好吧,这仍然没有解释它是如何工作的。我们现在有一个注册的监听器(例如参与者),并且我们有进入处理程序的事件。

每个渲染周期,您都会在处理程序中调用一次processEvents()。这意味着在某一帧中推送的每个事件都会在下一帧中处理。 (异步)同时他会迭代所有事件并将它们推送给监听器。此外,监听器也应该有一个队列,用于放置所有事件,并且当它们位于 .act() 时,它们会处理事件。 (更多异步)。

好的,这是我使用的处理程序:

包 com.portaaenigma.eventsystem;

导入java.util.ArrayList;导入java.util.HashMap;导入 java.util.LinkedList;导入 com.badlogic.gdx.utils.TimeUtils;导入 com.portaaenigma.managers.Logger;

公共(public)类EventHandler实现Interface_EventHandler{ 私有(private) HashMap> 监听器; 私有(private) LinkedList 事件;

public EventHandler()
{
listeners = new HashMap<Event_Type, ArrayList<Interface_Listen>>();
// add the arraylist for every Eventtype
for (Event_Type e : Event_Type.values())
{
listeners.put(e, new ArrayList<Interface_Listen>());
}
events = new LinkedList<Event>();
}

@Override
public void handleEvent(final Event... e)
{
for (Event event : e)
{
events.push(event);
}
}

@Override
public void unregisterListener(final Interface_Listen... listener)
{
for (Event_Type e : Event_Type.values())
{
for (Interface_Listen interface_Listen : listener)
{
listeners.get(e).remove(interface_Listen);
}
}
}

@Override
public void processEvents()
{
while (events.size() != 0)
{
// get the first element and delete it
Event e = events.pop();
for (Interface_Listen l : listeners.get(e.getType()))
{
l.handleEvent(e);
}
}
}

@Override
public void processEvents(final int maxTimeInMS)
{
int startSize = 0;
if (events.size() != 0)
{
startSize = events.size();
Logger.log("Processing Events: " + events.size());
}
long startTime = TimeUtils.millis();

while (events.size() != 0)
{
// get the first element and delete it
Event e = events.pop();
for (Interface_Listen l : listeners.get(e.getType()))
{
l.handleEvent(e);
}
// stop handling if time is up
if (startTime - TimeUtils.millis() > maxTimeInMS)
{
Logger.log("Handled " + (events.size() - startSize) + " Events");
break;
}
}
}

@Override
public void registerListener(final Interface_Listen listener,
Event_Type... type)
{
for (Event_Type event_Type : type)
{
listeners.get(event_Type).add(listener);
}
}

@Override
public void unregisterAllListener()
{
Logger.log("UnregisterAll");
for (Event_Type e : Event_Type.values())
{
listeners.get(e).clear();
}
}

@Override
public void unregisterAllListener(final Event_Type... type)
{
for (Event_Type event_Type : type)
{
listeners.get(event_Type).clear();
}
}

@Override
public void dispose()
{
unregisterAllListener();
events.clear();
listeners.clear();
}
}

所有监听器的界面都很简单,就是这样:公共(public)接口(interface)Interface_Listen

{
public void handleEvent(final Event e);
}

最后但并非最不重要的事件。现在如何发送不同的数据?安静简单。有一个由 Strings 和 Strings 组成的 hashmap,当然还有 EventType。

public class Event
{
private Event_Type type;
private HashMap<String, String> m_messages;

public Event(final Event_Type e, final Event_Message... m)
{
m_messages = new HashMap<String, String>();
for (Event_Message message : m)
{
m_messages.put(message.m_key, message.m_value);
}
type = e;
}


public Event_Type getType()
{
return type;
}

public void addMessages(final Event_Message... m)
{
for (Event_Message event_Message : m)
{
m_messages.put(event_Message.m_key, event_Message.m_value);
}
}

public String getMessage(final String name)
{
if (m_messages.get(name) == null)
{
Logger.error("Message not found: " + name);
}

// if null return an empty string
return m_messages.get(name) != null ? m_messages.get(name) : "";
}

public void clearMessages()
{
m_messages.clear();
}
}

好吧,我希望这确实解释了如何在游戏中实现事件系统。这可能不是其他软件的常规方式,但在游戏中,您将事件排队并在游戏循环周期中处理一次。听众也做同样的事情。

所以就你的情况而言。实现这样的处理程序并将参与者注册为监听器。当然,他们需要实现监听器接口(interface)并对事件执行某些操作。让一个参与者将一个事件推送到处理程序中,该处理程序会定向到另一个参与者,然后你就完成了。 而且他们不需要互相了解,而且它确实适用于您希望的尽可能多的 Actor 。您甚至可以为不同类别的不同 Actor 创建 1 个事件,依此类推。例如在 map 更改时很有用。你用通知推送一个事件..“changemap”..每个 Actor 都知道他需要停止移动,每个子系统都知道它确实需要因为 map 更改等而停止......

这似乎有点矫枉过正,但它有很多优点,即使在早期阶段也值得使用。我犯了一个错误,后来开始使用它,现在我后悔了。

抱歉支撑。这不是常规的java标准,但我认为更清楚......很抱歉当时有很多类似的可变参数。可能会令人困惑。

<小时/>

文学:

Game Coding Complete, Fourth Edition第11章

关于java - Actor 之间的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21696559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com