25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GameActor.java 4.4 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package actors;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Set;
  5. import com.fasterxml.jackson.databind.JsonNode;
  6. import com.fasterxml.jackson.databind.ObjectMapper;
  7. import com.fasterxml.jackson.databind.node.ObjectNode;
  8. import akka.actor.AbstractActor;
  9. import akka.actor.ActorRef;
  10. import events.CardClicked;
  11. import events.EndTurnClicked;
  12. import events.EventProcessor;
  13. import events.Heartbeat;
  14. import events.Initalize;
  15. import events.OtherClicked;
  16. import events.TileClicked;
  17. import events.UnitMoving;
  18. import events.UnitStopped;
  19. import play.libs.Json;
  20. import structures.GameState;
  21. import utils.ImageListForPreLoad;
  22. import play.libs.Json;
  23. /**
  24. * The game actor is an Akka Actor that receives events from the user front-end UI (e.g. when
  25. * the user clicks on the board) via a websocket connection. When an event arrives, the
  26. * processMessage() method is called, which can be used to react to the event. The Game actor
  27. * also includes an ActorRef object which can be used to issue commands to the UI to change
  28. * what the user sees. The GameActor is created when the user browser creates a websocket
  29. * connection to back-end services (on load of the game web page).
  30. * @author Dr. Richard McCreadie
  31. *
  32. */
  33. public class GameActor extends AbstractActor {
  34. private ObjectMapper mapper = new ObjectMapper(); // Jackson Java Object Serializer, is used to turn java objects to Strings
  35. private ActorRef out; // The ActorRef can be used to send messages to the front-end UI
  36. private Map<String,EventProcessor> eventProcessors; // Classes used to process each type of event
  37. private GameState gameState; // A class that can be used to hold game state information
  38. /**
  39. * Constructor for the GameActor. This is called by the GameController when the websocket
  40. * connection to the front-end is established.
  41. * @param out
  42. */
  43. @SuppressWarnings("deprecation")
  44. public GameActor(ActorRef out) {
  45. this.out = out; // save this, so we can send commands to the front-end later
  46. // create class instances to respond to the various events that we might recieve
  47. eventProcessors = new HashMap<String,EventProcessor>();
  48. eventProcessors.put("initalize", new Initalize());
  49. eventProcessors.put("heartbeat", new Heartbeat());
  50. eventProcessors.put("unitMoving", new UnitMoving());
  51. eventProcessors.put("unitstopped", new UnitStopped());
  52. eventProcessors.put("tileclicked", new TileClicked());
  53. eventProcessors.put("cardclicked", new CardClicked());
  54. eventProcessors.put("endturnclicked", new EndTurnClicked());
  55. eventProcessors.put("otherclicked", new OtherClicked());
  56. // Initalize a new game state object
  57. gameState = new GameState();
  58. // #hack: give the game state a reference to the game actor so AIPlayer can send messages
  59. gameState.gameActor = this;
  60. // Get the list of image files to pre-load the UI with
  61. Set<String> images = ImageListForPreLoad.getImageListForPreLoad();
  62. try {
  63. ObjectNode readyMessage = Json.newObject();
  64. readyMessage.put("messagetype", "actorReady");
  65. readyMessage.put("preloadImages", mapper.readTree(mapper.writeValueAsString(images)));
  66. out.tell(readyMessage, out);
  67. } catch (Exception e) {
  68. e.printStackTrace();
  69. }
  70. }
  71. /**
  72. * This method simply farms out the processing of the json messages from the front-end to the
  73. * processMessage method
  74. * @return
  75. */
  76. public Receive createReceive() {
  77. return receiveBuilder()
  78. .match(JsonNode.class, message -> {
  79. System.out.println(message);
  80. processMessage(message.get("messagetype").asText(), message);
  81. }).build();
  82. }
  83. /**
  84. * This looks up an event processor for the specified message type.
  85. * Note that this processing is asynchronous.
  86. * @param messageType
  87. * @param message
  88. * @return
  89. * @throws Exception
  90. */
  91. @SuppressWarnings({"deprecation"})
  92. public void processMessage(String messageType, JsonNode message) throws Exception{
  93. EventProcessor processor = eventProcessors.get(messageType);
  94. if (processor==null) {
  95. // Unknown event type received
  96. System.err.println("GameActor: Recieved unknown event type "+messageType);
  97. } else {
  98. processor.processEvent(out, gameState, message); // process the event
  99. }
  100. }
  101. public void reportError(String errorText) {
  102. ObjectNode returnMessage = Json.newObject();
  103. returnMessage.put("messagetype", "ERR");
  104. returnMessage.put("error", errorText);
  105. out.tell(returnMessage, out);
  106. }
  107. }