Factor protocol and gameTurn() loop
[troll.git] / src / main / java / com / codingame / game / View.java
1 package com.codingame.game;
2
3 import java.util.Random;
4
5 import com.codingame.gameengine.core.MultiplayerGameManager;
6 import com.codingame.gameengine.module.entities.GraphicEntityModule;
7 import com.codingame.gameengine.module.entities.Rectangle;
8 import com.codingame.gameengine.module.entities.Sprite;
9 import com.codingame.gameengine.module.entities.Text;
10 import com.codingame.gameengine.module.entities.Group;
11 import com.codingame.gameengine.module.entities.Curve;
12 import com.google.inject.Inject;
13
14 class View {
15     @Inject private MultiplayerGameManager<com.codingame.game.Player> gameManager;
16     @Inject private GraphicEntityModule graphicEntityModule;
17
18     class Player {
19         Model.Player model;
20
21         int colorToken;
22         String nicknameToken;
23         String avatarToken;
24
25         double frameRot;
26
27         Group avatar;
28         Text stoneCounter;
29         Text message;
30         Sprite castle;
31         Text stone;
32         Text stoneReminder;
33
34         void init(com.codingame.game.Player p) {
35             model = p.model;
36             colorToken = p.getColorToken();
37             nicknameToken = p.getNicknameToken();
38             avatarToken = p.getAvatarToken();
39
40             boolean p0 = model.index == 0;
41             int x = p0 ? 280 : 1920 - 280;
42             int y = 220;
43
44             Sprite frame = graphicEntityModule.createSprite()
45                 .setImage("frame.png")
46                 .setAnchor(0.5)
47                 .setRotation(frameRot)
48                 .setZIndex(22)
49                 .setTint(colorToken);
50
51             Sprite frameBg = graphicEntityModule.createSprite()
52                 .setImage("frame_bg.png")
53                 .setAnchor(0.5)
54                 .setRotation(frameRot)
55                 .setZIndex(20);
56
57             Sprite avatarSprite = graphicEntityModule.createSprite()
58                 .setZIndex(21)
59                 .setImage(avatarToken)
60                 .setAnchor(0.5)
61                 .setBaseHeight(116)
62                 .setBaseWidth(116);
63
64             avatar = graphicEntityModule
65                 .createGroup(frame, frameBg, avatarSprite)
66                 .setX(x).setY(y);
67
68             Text text = graphicEntityModule.createText(nicknameToken)
69                     .setX(x)
70                     .setY(y + 120)
71                     .setZIndex(20)
72                     .setFontSize(40)
73                     .setFillColor(0x7f3f00)
74                     .setAnchor(0.5);
75
76             stoneCounter = graphicEntityModule.createText()
77                 .setX(x)
78                 .setY(y+200)
79                 .setZIndex(20)
80                 .setFontSize(40)
81                 .setFillColor(0x7f3f00)
82                 .setAnchor(0.5);
83             updateStoneCounter();
84
85             message = graphicEntityModule.createText()
86                 .setX(p0 ? 15 : 1920-15)
87                 .setY(680)
88                 .setZIndex(1)
89                 .setFontSize(40)
90                 .setFillColor(0xffbf7f)
91                 .setAnchorX(p0 ? 0 : 1)
92                 .setAnchorY(1);
93
94             castle = graphicEntityModule.createSprite()
95                 .setImage("castle.png")
96                 .setTint(colorToken)
97                 .setX(p0 ? 160 : 1920-160)
98                 .setY(p0 ? 890 : 880)
99                 .setZIndex(1)
100                 .setAnchorX(0.5)
101                 .setAnchorY(1)
102                 .setScaleX(p0 ? 1 : -1);
103
104             stone = graphicEntityModule.createText()
105                 .setZIndex(3)
106                 .setFontSize(150)
107                 .setFillColor(0x12322a)
108                 .setAnchor(0.5)
109                 .setAlpha(0);
110
111             stoneReminder = graphicEntityModule.createText()
112                 .setX(p0 ? x + 100 : x - 100)
113                 .setY(y)
114                 .setZIndex(20)
115                 .setFontSize(75)
116                 .setFillColor(0x3f3f3f)
117                 .setAnchorX(p0 ? 0 : 1)
118                 .setAnchorY(0.5);
119         }
120
121         void updateStoneCounter() {
122             int stones = model.getStones();
123             if (stones <= 0) {
124                 stoneCounter.setText("Out of stones!");
125                 stoneCounter.setFillColor(0xff7777);
126             }
127             else if (stones == 1) {
128                 stoneCounter.setText("1 stone");
129                 stoneCounter.setFillColor(0xffbb77);
130             }
131             else {
132                 stoneCounter.setText(stones + " stones");
133             }
134         }
135
136         void animateStones(int stones) {
137             String stonesString = new Integer(stones).toString();
138             stone.setX(castle.getX());
139             stone.setY(castle.getY() - 100);
140             stone.setText(stonesString);
141             stone.setAlpha(1);
142             graphicEntityModule.commitEntityState(0, stone);
143     
144             int peakX = (castle.getX() + troll.getX()) / 2;
145             int peakY = 540;
146             stone.setX(peakX);
147             stone.setY(peakY, Curve.EASE_OUT);
148             graphicEntityModule.commitEntityState(0.25,
149                                                   stone,
150                                                   stoneCounter);
151     
152             stone.setX(troll.getX());
153             stone.setY(troll.getY() - 50, Curve.EASE_IN);
154             stone.setAlpha(0, Curve.EASE_IN);
155             graphicEntityModule.commitEntityState(0.5, stone);
156
157             stoneReminder.setText(stonesString);
158             graphicEntityModule.commitEntityState(0.25, stoneReminder);
159             stoneReminder.setAlpha(1);
160             graphicEntityModule.commitEntityState(0.5, stoneReminder);
161         }
162
163         void displayMessage(String msg) {
164             message.setText(msg);
165             graphicEntityModule.commitEntityState(0, message);
166         }
167
168         void destroy() {
169             graphicEntityModule.commitEntityState(0.5, avatar);
170             int dir = random.nextInt(2) == 1 ? 1 : -1;
171             avatar.setRotation(dir * 170 * Math.PI / 180, Curve.ELASTIC);
172
173             graphicEntityModule.commitEntityState(0.5, castle);
174             castle.setX(castle.getX(), Curve.ELASTIC);
175             castle.setScaleY(-0.2, Curve.EASE_IN);
176         }
177
178         void startTurn() {
179             stoneReminder.setAlpha(0);
180             graphicEntityModule.commitEntityState(0, stoneReminder);
181         }
182     }
183
184     Model model;
185     Random random = new Random();
186     Sprite troll;
187     Text trollPositionGauge;
188     Player p0 = new Player(), p1 = new Player();
189
190     void init(Model m) {
191         model = m;
192         drawBackground();
193
194         /*
195          * Random π/2-grained rotation of the avatar frames.  Avoid
196          * having them π/2 apart, though, as one of them is likely
197          * going to end upside-down and the trick would be revealed.
198          * And I'd have to "draw" a new frame. Ewww.
199          */
200         p0.frameRot = random.nextInt(4) * Math.PI / 2;
201         p0.init(gameManager.getPlayer(0));
202         p1.frameRot = p1.frameRot +
203             (random.nextInt(2) == 1 ? 1 : -1) * Math.PI / 2;
204         p1.init(gameManager.getPlayer(1));
205
206         drawTroll();
207     }
208
209     void startTurn() {
210         p0.startTurn();
211         p1.startTurn();
212     }
213
214     private void drawBackground() {
215         graphicEntityModule.createSprite()
216                 .setImage("background.png")
217                 .setAnchor(0);
218     }
219
220     private void drawTroll() {
221         troll = graphicEntityModule.createSprite()
222             .setImage("troll.png")
223             .setAnchorX(0.5)
224             .setAnchorY(1)
225             .setX(1920/2)
226             .setY(880)
227             .setZIndex(2);
228         trollPositionGauge = graphicEntityModule.createText()
229             .setZIndex(2)
230             .setAnchor(0.5)
231             .setFontSize(40)
232             .setX(1980/2)
233             .setY(980)
234             .setFillColor(0xffffff);
235
236         moveTroll();
237     }
238
239     void moveTroll() {
240         graphicEntityModule.commitEntityState(0.5, troll, trollPositionGauge);
241         int x0 = p0.castle.getX(), x1 = p1.castle.getX();
242         int y0 = p0.castle.getY(), y1 = p1.castle.getY();
243         troll.setX(x0 + model.trollPosition * (x1-x0) / model.roadLength,
244                    Curve.ELASTIC);
245         troll.setY(y0 + model.trollPosition * (y1-y0) / model.roadLength,
246                    Curve.ELASTIC);
247
248         trollPositionGauge.setX((trollPositionGauge.getX() + troll.getX()) / 2);
249         int delta = model.trollPosition - model.roadLength / 2;
250         if (delta < 0) {
251             trollPositionGauge.setText("← " + Math.abs(delta));
252         }
253         else if (delta > 0) {
254             trollPositionGauge.setText(Math.abs(delta) + " →");
255         }
256         else {
257             trollPositionGauge.setText("↔");
258         }
259         graphicEntityModule.commitEntityState(0.75, trollPositionGauge);
260         trollPositionGauge.setX(troll.getX());
261     }
262
263 }