我正在尝试使用事件对演员做些什么,但我不明白如何正确地做到这一点。
我的屏幕上有一个按钮和一个文本(例如)。他们都是舞台上的演员 我的目的是:如果我点击按钮,我想改变文字
我在我的按钮上添加了监听器,我得到了点击,但我不知道如何将事件(或其他任何内容)发送到我的文本来设置它。
主要课程有阶段定义和他的
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类(包含文本actor):
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");
}
}
答案 0 :(得分:0)
如果使用clicklistener,则需要让另一个actor保持对它的引用,以便在单击时调用方法。让所有演员互相了解并不是一件好事。使用匿名方式。
游戏中有一个“常用”系统。
如果您确实想使用事件,请实施事件系统。因此,您有一个接口Listen
和一个接口Event_Handler
。在游戏开始时,您启动一个Eventhandler的实现。界面至少应如下所示:
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,其中所有事件类型为Key,侦听器列表为Value。因此,如果有人想要注意一个事件,他会在权限registerListerner
(Enum)的处理程序中向Event_Type
注册。它需要具有接口侦听获取事件。现在,每个人都可以使用handleEvent(...)
方法将事件推送到处理程序中。甚至不止一个..(varargs)..
好的,仍然没有解释它是如何工作的。我们现在有一个注册的监听器(例如actor),我们有进入处理程序的事件。
每个Rendercycle都会在hanlder上调用processEvents()
一次。这意味着在帧中推入的每个事件都会在下一帧处理。 (Asynchronus)虽然他迭代所有事件并将它们推送给听众。此外,监听器也应该有一个队列,他们放置所有事件,当他们在.act()
他们处理事件时。 (更多asynchronus)。
好的,这是我使用的Handler:
package com.portaaenigma.eventsystem;
import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import com.badlogic.gdx.utils.TimeUtils; import com.portaaenigma.managers.Logger;
public class EventHandler实现Interface_EventHandler { private HashMap>听众; 私人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();
}
}
所有听众的界面都很简单就是这样: 公共接口Interface_Listen
{
public void handleEvent(final Event e);
}
最后但并非最不重要的事件。你现在怎么发送不同的数据?安静简单。从字符串和字符串中获取一个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();
}
}
好的,我希望这能解释如何在游戏中实现EventSystem。这种高度不是其他软件的常规方式,但在游戏中,您可以将事件排队并在Gameloop循环中处理它们一次。听众也这样做。
所以在你的情况下。实现这样的处理程序并将actor注册为侦听器。当然,他们需要实现侦听器接口并对事件执行某些操作。让一个演员将事件推送到处理程序中,该处理程序指向另一个演员并完成。 他们的活动不需要彼此了解,而且它确实适用于和你一样多的演员。您甚至可以为不同类别的不同演员创建1个事件,依此类推。例如在mapchange中有用。你通过通知推送一个事件。“changemap”..并且每个演员都知道他需要停止移动,并且每个子系统都知道它确实需要停止因为mapchange等等...
它似乎有点矫枉过正,但它有很多优点,即使在早期阶段也很有用。我做了一些错误,后来开始使用它,现在我后悔了。
抱歉。这不是常规的java标准,但我认为更清楚......对于很多类似的varargs抱歉。可能会让人感到困惑。
Literatur: