source: advance-wars/src/com/medievaltech/advancewars/GameView.java@ b660017

Last change on this file since b660017 was b660017, checked in by dportnoy <devnull@…>, 14 years ago

Removed the AppState enum and a bunch of code associated with it. This was all from the demo app that was used as a starting point for blackjack and looks like it's only useful for games that run in real-time, as opposed to turn-based.

  • Property mode set to 100644
File size: 13.1 KB
Line 
1package com.medievaltech.advancewars;
2
3import java.io.*;
4
5import com.medievaltech.advancewars.Enum.*;
6import com.medievaltech.unit.*;
7import com.medievaltech.gui.*;
8
9import android.content.Context;
10import android.graphics.*;
11import android.os.*;
12import android.view.*;
13import android.util.AttributeSet;
14import android.util.Log;
15import android.widget.TextView;
16
17class GameView extends SurfaceView implements SurfaceHolder.Callback {
18
19 class DrawingThread extends Thread {
20 public GameState mGameState;
21
22 /*
23 * Member (state) fields
24 */
25
26 private int mCanvasHeight = 1;
27 private int mCanvasWidth = 1;
28
29 /** Paint to draw the lines on screen. */
30 private Paint mLinePaint, mTextPaint, mButtonPaint, mTilePaint1, mTilePaint2, mSelectionPaint,
31 mUnitPaint;
32
33 //maybe make this private and make an accessor for it
34 public Map mMap;
35
36 public Tile grassTile, oceanTile;
37
38 /** Indicate whether the surface has been created & is ready to draw */
39 private boolean mRun = false;
40
41 /** Handle to the surface manager object we interact with */
42 private SurfaceHolder mSurfaceHolder;
43
44 private com.medievaltech.gui.Window wndMainMenu;
45 private Unit selectedUnit;
46
47 public DrawingThread(SurfaceHolder surfaceHolder, Context context, Handler handler) {
48 mSurfaceHolder = surfaceHolder;
49
50 mLinePaint = new Paint();
51 mLinePaint.setAntiAlias(true);
52 mLinePaint.setARGB(255, 0, 255, 0);
53
54 mTextPaint = new Paint();
55 mTextPaint.setAntiAlias(true);
56 mTextPaint.setARGB(255, 255, 255, 255);
57 mTextPaint.setTextSize(12);
58 mTextPaint.setTextAlign(Paint.Align.CENTER);
59
60 mButtonPaint = new Paint();
61 mButtonPaint.setAntiAlias(true);
62 mButtonPaint.setARGB(255, 0, 0, 0);
63 mButtonPaint.setTextSize(20);
64 mButtonPaint.setTextAlign(Paint.Align.CENTER);
65
66 mTilePaint1 = new Paint();
67 mTilePaint1.setAntiAlias(true);
68 mTilePaint1.setARGB(255, 0, 255, 0);
69
70 mTilePaint2 = new Paint();
71 mTilePaint2.setAntiAlias(true);
72 mTilePaint2.setARGB(255, 0, 0, 255);
73
74 mUnitPaint = new Paint();
75 mUnitPaint.setAntiAlias(true);
76 mUnitPaint.setARGB(255, 255, 0, 0);
77
78 mSelectionPaint = new Paint();
79 mSelectionPaint.setAntiAlias(true);
80 mSelectionPaint.setARGB(255, 255, 127, 0);
81
82 wndMainMenu = new com.medievaltech.gui.Window(0, 0, 320, 450);;
83 wndMainMenu.addGUIObject("txtTitle", new Text("Main Menu", 100, 30, 120, 20, mTextPaint));
84 wndMainMenu.addGUIObject("btnNewGame", new Button("New Game", 100, 90, 120, 20, mLinePaint, mButtonPaint));
85 wndMainMenu.addGUIObject("btnLoadGame", new Button("Load Game", 100, 125, 120, 20, mLinePaint, mButtonPaint));
86 wndMainMenu.addGUIObject("btnMapEditor", new Button("Map Editor", 100, 160, 120, 20, mLinePaint, mButtonPaint));
87 wndMainMenu.addGUIObject("btnQuit", new Button("Quit", 100, 195, 120, 20, mLinePaint, mButtonPaint));
88
89 grassTile = new Tile(mTilePaint1, TerrainType.LAND);
90 oceanTile = new Tile(mTilePaint2, TerrainType.SEA);
91
92 mMap = new Map(grassTile, 6, 8, new Point(10, 25));
93
94 boolean land = true;
95
96 for(int x=0; x<mMap.getWidth(); x++) {
97 for(int y=0; y<mMap.getHeight(); y++) {
98 if(land)
99 mMap.setTile(x, y, new Tile(grassTile, new Point(x, y)));
100 else
101 mMap.setTile(x, y, new Tile(oceanTile, new Point(x, y)));
102 land = !land;
103 }
104 land = !land;
105 }
106
107 mMap.getTile(2, 3).addUnit(new Soldier(mUnitPaint));
108 mMap.getTile(5, 6).addUnit(new Soldier(mUnitPaint));
109
110 mGameState = GameState.MAIN_MENU;
111 }
112
113 /**
114 * Starts the game, setting parameters for the current difficulty.
115 */
116 // I don't think this gets called now. maybe we should call it in the thread constructor
117 public void doStart() {
118 synchronized (mSurfaceHolder) {
119 Log.i("AdvanceWars", "Player's turn starting now");
120 mGameState = GameState.MAIN_MENU;
121 }
122 }
123
124 @Override
125 public void run() {
126 while (mRun) {
127 Canvas c = null;
128 try {
129 c = mSurfaceHolder.lockCanvas(null);
130 synchronized(mSurfaceHolder) {
131 doDraw(c);
132 }
133 } finally {
134 // do this in a finally so that if an exception is thrown
135 // during the above, we don't leave the Surface in an
136 // inconsistent state
137 if (c != null) {
138 mSurfaceHolder.unlockCanvasAndPost(c);
139 }
140 }
141 }
142 }
143
144 /**
145 * Used to signal the thread whether it should be running or not.
146 * Passing true allows the thread to run; passing false will shut it
147 * down if it's already running. Calling start() after this was most
148 * recently called with false will result in an immediate shutdown.
149 *
150 * @param b true to run, false to shut down
151 */
152 public void setRunning(boolean b) {
153 mRun = b;
154 }
155
156 public void setGameState(GameState state) {
157 synchronized (mSurfaceHolder) {
158 mGameState = state;
159 }
160 }
161
162 /* Callback invoked when the surface dimensions change. */
163 public void setSurfaceSize(int width, int height) {
164 // synchronized to make sure these all change atomically
165 synchronized (mSurfaceHolder) {
166 mCanvasWidth = width;
167 mCanvasHeight = height;
168
169 Log.i("AdvanceWars", "width: "+mCanvasWidth+", height: "+mCanvasHeight);
170 }
171 }
172
173 /**
174 * Draws the ship, fuel/speed bars, and background to the provided
175 * Canvas.
176 */
177 private void doDraw(Canvas canvas) {
178 canvas.drawColor(Color.BLACK);
179
180 switch(mGameState) {
181 case MAIN_MENU:
182 wndMainMenu.draw(canvas);
183 break;
184 case BATTLE_MAP:
185 mTextPaint.setTextSize(12);
186
187 mMap.draw(canvas);
188
189 if(selectedUnit != null) {
190 for(Point p : selectedUnit.getMovementRange()) {
191 canvas.drawRect(p.x*50+10, p.y*50+25, p.x*50+50+10, p.y*50+50+25, mSelectionPaint);
192 }
193 }
194
195 mMap.drawUnits(canvas);
196
197 break;
198 }
199 }
200 }
201
202 /** Pointer to the text view to display "Paused.." etc. */
203 private TextView mStatusText;
204
205 /** The thread that actually draws the animation */
206 private DrawingThread thread;
207
208 public Game mGame;
209
210 public GameView(Context context, AttributeSet attrs) {
211 super(context, attrs);
212
213 // register our interest in hearing about changes to our surface
214 SurfaceHolder holder = getHolder();
215 holder.addCallback(this);
216
217 // create thread only; it's started in surfaceCreated()
218 thread = new DrawingThread(holder, context, new Handler() {
219 @Override
220 public void handleMessage(Message m) {
221 mStatusText.setVisibility(m.getData().getInt("viz"));
222 mStatusText.setText(m.getData().getString("text"));
223 }
224 });
225
226 setFocusable(true); // make sure we get key events
227 }
228
229 @Override public boolean onTouchEvent(MotionEvent event) {
230 Log.i("AdvanceWars", "Detected touch event");
231
232 if(event.getAction() == MotionEvent.ACTION_UP) {
233 Log.i("AdvanceWars", "Detected UP touch action");
234 switch(thread.mGameState) {
235 case MAIN_MENU:
236 Log.i("AdvanceWars", "Switching to battle map");
237 if(thread.wndMainMenu.getGUIObject("btnNewGame").isClicked(event.getX(), event.getY())) {
238 thread.mGameState = GameState.BATTLE_MAP;
239 }else if(thread.wndMainMenu.getGUIObject("btnLoadGame").isClicked(event.getX(), event.getY())) {
240 BufferedReader b;
241 try {
242 b = new BufferedReader(new FileReader(android.os.Environment.getExternalStorageDirectory()+"/save.txt"));
243
244 int width = Integer.parseInt(b.readLine());
245 int height = Integer.parseInt(b.readLine());
246
247 String offset = b.readLine();
248 Log.i("GameSave", offset);
249 int offsetX = Integer.parseInt(offset.substring(0, offset.indexOf("x")));
250 int offsetY = Integer.parseInt(offset.substring(offset.indexOf("x")+1));
251
252 thread.mMap = new Map(thread.grassTile, width, height, new Point(offsetX, offsetY));
253
254 Log.i("GameSave", "Created the map");
255
256 for(int x=0; x<width; x++) {
257 String line = b.readLine();
258 Log.i("GameSave", line);
259 String[] arr = line.split(",");
260 for(int y=0; y<arr.length; y++) {
261 TerrainType type = TerrainType.values()[Integer.parseInt(arr[y])];
262 if(type.equals(TerrainType.LAND))
263 thread.mMap.setTile(x, y, new Tile(thread.grassTile, new Point(10, 25)));
264 else
265 thread.mMap.setTile(x, y, new Tile(thread.oceanTile, new Point(10, 25)));
266 }
267 }
268
269 while(b.ready()) {
270 String unit = b.readLine();
271 Log.i("GameSave", unit);
272 int x = Integer.parseInt(unit.substring(0, unit.indexOf(",")));
273 int y = Integer.parseInt(unit.substring(unit.indexOf(",")+1));
274
275 mGame.mThread.mMap.getTile(x, y).addUnit(new Soldier(mGame.mThread.mUnitPaint));
276 }
277
278 b.close();
279 }catch(IOException ioe) {
280 ioe.printStackTrace();
281 }
282 thread.mGameState = GameState.BATTLE_MAP;
283 }else if(thread.wndMainMenu.getGUIObject("btnQuit").isClicked(event.getX(), event.getY())) {
284 mGame.finish();
285 }
286 break;
287 case BATTLE_MAP:
288 Log.i("AdvanceWars", "Touch event detected on battle map");
289
290 if(event.getX() >= thread.mMap.offset.x && event.getY() >= thread.mMap.offset.y) {
291 int x = ((int)event.getX() - thread.mMap.offset.x) / 50;
292 int y = ((int)event.getY() - thread.mMap.offset.y) / 50;
293
294 Unit target = thread.mMap.getTile(x, y).currentUnit;
295
296 if(thread.selectedUnit != null && thread.selectedUnit.getMovementRange().contains(new Point(x, y))) {
297 if(target == null || target == thread.selectedUnit) {
298 thread.mMap.getTile(thread.selectedUnit.location.x, thread.selectedUnit.location.y).removeUnit();
299 thread.mMap.getTile(x, y).addUnit(thread.selectedUnit);
300 }else {
301 // the target contains another unit. If the unit is enemy-controlled, attack it
302 }
303 thread.selectedUnit = null;
304 }else
305 thread.selectedUnit = target;
306 }
307
308 break;
309 }
310 }else if(event.getAction() == MotionEvent.ACTION_DOWN) {
311
312 }
313
314 return true;
315 }
316
317 /**
318 * Fetches the animation thread corresponding to this LunarView.
319 *
320 * @return the animation thread
321 */
322 public DrawingThread getThread() {
323 return thread;
324 }
325
326 /**
327 * Installs a pointer to the text view used for messages.
328 */
329 public void setTextView(TextView textView) {
330 mStatusText = textView;
331 }
332
333 /* Callback invoked when the surface dimensions change. */
334 public void surfaceChanged(SurfaceHolder holder, int format, int width,
335 int height) {
336 thread.setSurfaceSize(width, height);
337 }
338
339 /*
340 * Callback invoked when the Surface has been created and is ready to be
341 * used.
342 */
343 public void surfaceCreated(SurfaceHolder holder) {
344 thread.setRunning(true);
345 thread.start();
346 }
347
348 /*
349 * Callback invoked when the Surface has been destroyed and must no longer
350 * be touched. WARNING: after this method returns, the Surface/Canvas must
351 * never be touched again!
352 */
353 public void surfaceDestroyed(SurfaceHolder holder) {
354 // we have to tell thread to shut down & wait for it to finish, or else
355 // it might touch the Surface after we return and explode
356 boolean retry = true;
357 thread.setRunning(false);
358 while (retry) {
359 try {
360 thread.join();
361 retry = false;
362 } catch (InterruptedException e) {
363 }
364 }
365 }
366}
Note: See TracBrowser for help on using the repository browser.