PageRenderTime 71ms CodeModel.GetById 58ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/androidsays/src/com/google/marvin/androidsays/WidgetGameService.java

http://eyes-free.googlecode.com/
Java | 222 lines | 162 code | 33 blank | 27 comment | 21 complexity | d0b7b1eb7849d55dd9ebd2682c8af2c2 MD5 | raw file
  1
  2package com.google.marvin.androidsays;
  3
  4import java.util.ArrayList;
  5
  6import com.google.marvin.androidsays.GameView.SequencePlayer;
  7
  8import android.app.Service;
  9import android.content.Context;
 10import android.content.Intent;
 11import android.os.IBinder;
 12import android.os.RemoteException;
 13import android.os.Vibrator;
 14import android.util.Log;
 15import android.widget.Toast;
 16
 17public class WidgetGameService extends Service {
 18
 19    private WidgetGameService self;
 20
 21    private boolean needReset = true;
 22
 23    private Vibrator vibe;
 24
 25    private long[] pattern = {
 26            0, 1, 40, 41
 27    };
 28
 29    private int currentIndex;
 30
 31    private ArrayList<Integer> sequence;
 32
 33    private int score;
 34
 35    private SfxController sfx;
 36
 37    // These are timings used to control pauses between actions
 38    // All times are specified in ms
 39    private int initialWaitTime = 550;
 40
 41    private int waitTimeBetweenTones = 310;
 42
 43    private int flashDuration = 250;
 44
 45    // Used for locking the screen
 46    private boolean screenActive;
 47
 48    private int inputCount;
 49    
 50    
 51
 52    public void onStart(Intent intent, int startId) {
 53        super.onStart(intent, startId);
 54        this.setForeground(true);
 55
 56        if (needReset) {
 57            self = this;
 58            sfx = new SfxController(this);
 59            // Hard code this for now
 60            sfx.loadSoundResource("[0]", R.raw.green_snd);
 61            sfx.loadSoundResource("[1]", R.raw.red_snd);
 62            sfx.loadSoundResource("[2]", R.raw.yellow_snd);
 63            sfx.loadSoundResource("[3]", R.raw.blue_snd);
 64            vibe = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
 65            sequence = new ArrayList<Integer>();
 66            currentIndex = 0;
 67            screenActive = false;
 68            score = 0;
 69            inputCount = 0;
 70            needReset = false;
 71            sfx.play("Android says:", 0);
 72            playSequence();
 73        } else {
 74            if (screenActive) {
 75                inputCount++;
 76                if (inputCount >= sequence.size()) {
 77                  screenActive = false;
 78                }
 79                String input = intent.getStringExtra("input");
 80                input = input.replaceAll("com.google.marvin.androidsays.0", "");
 81                sfx.play("[" + input + "]", 0);
 82                vibe.vibrate(pattern, -1);
 83                evalInput(Integer.parseInt(input));
 84            }
 85        }
 86    }
 87
 88    private void evalInput(final int input) {
 89        Thread t = new Thread() {
 90            @Override
 91            public void run() {
 92                try {
 93                    Thread.sleep(1000);
 94                } catch (InterruptedException e) {
 95                    // This should not get interrupted
 96                    e.printStackTrace();
 97                }
 98                Log.e("evalInput", "input is: " + input);
 99                if (currentIndex >= sequence.size()) {
100                    return;
101                }
102                if (input == sequence.get(currentIndex)) {
103                    currentIndex++;
104                    if (currentIndex >= sequence.size()) {
105                        currentIndex = 0;
106                        sfx.play("[right]", 1);
107                        score++;
108                        playSequence();
109                    }
110                } else {
111                    sfx.play("[wrong]", 1);
112                    gameOver();
113                }
114            }
115        };
116
117        t.start();
118    }
119
120    private void playSequence() {
121        (new Thread(new SequencePlayer())).start();
122    }
123
124    // Generates sequence either by adding one random number to the end
125    // (classic)
126    // or by generating a brand new sequence of a set length (challenge).
127    private void generateSequence() {
128        currentIndex = 0;
129        int random = ((int)(Math.random() * 100)) % 4;
130        sequence.add(random);
131    }
132
133    /**
134     * Plays back the sequence This needs to be done in a different thread
135     * because it uses sleep to keep the visual flashing in sync with the
136     * sounds.
137     */
138    public class SequencePlayer implements Runnable {
139        public void run() {
140            screenActive = false;
141            generateSequence();
142            try {
143                Thread.sleep(initialWaitTime);
144            } catch (InterruptedException e) {
145                // Nothing needs to be done if the sleep is interrupted.
146                e.printStackTrace();
147            }
148            for (int i = 0; i < sequence.size(); i++) {
149                // TODO(clchen): - find a more graceful way of stopping the
150                // sound
151                // if (parent.halt) {
152                // inputCount = 0;
153                // screenActive = true;
154                // return;
155                // }
156                // TODO: Use prefs here!
157                int delay = -1; // parent.speedPrefDelay;
158                // Negative speed_pref_delay means scaling
159                if (delay < 0) {
160                    delay = 300 - (sequence.size() * 10);
161                }
162                // Scaled delay must be 0 or positive
163                if (delay < 0) {
164                    delay = 0;
165                }
166                try {
167                    Thread.sleep(waitTimeBetweenTones + delay);
168                } catch (InterruptedException e) {
169                    // Nothing needs to be done if the sleep is interrupted.
170                    e.printStackTrace();
171                }
172
173                Log.e("SequencePlayer", sequence.get(i) + "");
174
175                Intent flashIntent;
176                if (sequence.get(i) == 0) {
177                    flashIntent = new Intent("com.google.marvin.androidsays.flash.00");
178                    sfx.play("[0]", 1);
179                } else if (sequence.get(i) == 1) {
180                    flashIntent = new Intent("com.google.marvin.androidsays.flash.01");
181                    sfx.play("[1]", 1);
182                } else if (sequence.get(i) == 2) {
183                    flashIntent = new Intent("com.google.marvin.androidsays.flash.02");
184                    sfx.play("[2]", 1);
185                } else {
186                    flashIntent = new Intent("com.google.marvin.androidsays.flash.03");
187                    sfx.play("[3]", 1);
188                }
189                self.sendBroadcast(flashIntent);
190
191                try {
192                    Thread.sleep(flashDuration);
193                } catch (InterruptedException e) {
194                    // Nothing needs to be done if the sleep is interrupted.
195                    e.printStackTrace();
196                }
197                Intent unflashIntent = new Intent("com.google.marvin.androidsays.unflash");
198                self.sendBroadcast(unflashIntent);
199
200            }
201            inputCount = 0;
202            screenActive = true;
203        }
204    }
205
206    private void gameOver() {
207        String scoreStr = Integer.toString(score);
208        sfx.play("Game over. Your score is:", 1);
209        sfx.play(scoreStr, 1);
210        Intent showScoreIntent = new Intent("com.google.marvin.androidsays.showScore");
211        showScoreIntent.putExtra("score", scoreStr);
212        self.sendBroadcast(showScoreIntent);
213        needReset = true;
214        screenActive = true;
215    }
216
217    @Override
218    public IBinder onBind(Intent arg0) {
219        // Not binding to the service
220        return null;
221    }
222}