📄 globaltime.java
字号:
// Use English city names by default cis = am.open("cities_en.dat"); } catch (FileNotFoundException e3) { throw e3; } } } cis = cache(cis); City.loadCities(cis); City[] cities; if (USE_RAW_OFFSETS) { cities = City.getCitiesByRawOffset(); } else { cities = City.getCitiesByOffset(); } mClockCities = new ArrayList<City>(cities.length); for (int i = 0; i < cities.length; i++) { mClockCities.add(cities[i]); } mCities = mClockCities; mCityIndex = 0; this.mWorld = new Object3D() { @Override public InputStream readFile(String filename) throws IOException { return cache(am.open(filename)); } }; mWorld.load("world.gles"); // lights.dat has the following format. All integers // are 16 bits, low byte first. // // width // height // N [# of lights] // light 0 X [in the range 0 to (width - 1)] // light 0 Y ]in the range 0 to (height - 1)] // light 1 X [in the range 0 to (width - 1)] // light 1 Y ]in the range 0 to (height - 1)] // ... // light (N - 1) X [in the range 0 to (width - 1)] // light (N - 1) Y ]in the range 0 to (height - 1)] // // For a larger number of lights, it could make more // sense to store the light positions in a bitmap // and extract them manually InputStream lis = am.open("lights.dat"); lis = cache(lis); int lightWidth = readInt16(lis); int lightHeight = readInt16(lis); sNumLights = readInt16(lis); sLightCoords = new int[3 * sNumLights]; int lidx = 0; float lightRadius = 1.009f; float lightScale = 65536.0f * lightRadius; float[] cosTheta = new float[lightWidth]; float[] sinTheta = new float[lightWidth]; float twoPi = (float) (2.0 * Math.PI); float scaleW = twoPi / lightWidth; for (int i = 0; i < lightWidth; i++) { float theta = twoPi - i * scaleW; cosTheta[i] = (float)Math.cos(theta); sinTheta[i] = (float)Math.sin(theta); } float[] cosPhi = new float[lightHeight]; float[] sinPhi = new float[lightHeight]; float scaleH = (float) (Math.PI / lightHeight); for (int j = 0; j < lightHeight; j++) { float phi = j * scaleH; cosPhi[j] = (float)Math.cos(phi); sinPhi[j] = (float)Math.sin(phi); } int nbytes = 4 * sNumLights; byte[] ilights = new byte[nbytes]; int nread = 0; while (nread < nbytes) { nread += lis.read(ilights, nread, nbytes - nread); } int idx = 0; for (int i = 0; i < sNumLights; i++) { int lx = (((ilights[idx + 1] & 0xff) << 8) | (ilights[idx ] & 0xff)); int ly = (((ilights[idx + 3] & 0xff) << 8) | (ilights[idx + 2] & 0xff)); idx += 4; float sin = sinPhi[ly]; float x = cosTheta[lx]*sin; float y = cosPhi[ly]; float z = sinTheta[lx]*sin; sLightCoords[lidx++] = (int) (x * lightScale); sLightCoords[lidx++] = (int) (y * lightScale); sLightCoords[lidx++] = (int) (z * lightScale); } mLights = new PointCloud(sLightCoords); } /** * Returns true if two time zone offsets are equal. We assume distinct * time zone offsets will differ by at least a few minutes. */ private boolean tzEqual(float o1, float o2) { return Math.abs(o1 - o2) < 0.001; } /** * Move to a different time zone. * * @param incr The increment between the current and future time zones. */ private void shiftTimeZone(int incr) { // If only 1 city in the current set, there's nowhere to go if (mCities.size() <= 1) { return; } float offset = getOffset(mCities.get(mCityIndex)); do { mCityIndex = (mCityIndex + mCities.size() + incr) % mCities.size(); } while (tzEqual(getOffset(mCities.get(mCityIndex)), offset)); offset = getOffset(mCities.get(mCityIndex)); locateCity(true, offset); goToCity(); } /** * Returns true if there is another city within the current time zone * that is the given increment away from the current city. * * @param incr the increment, +1 or -1 * @return */ private boolean atEndOfTimeZone(int incr) { if (mCities.size() <= 1) { return true; } float offset = getOffset(mCities.get(mCityIndex)); int nindex = (mCityIndex + mCities.size() + incr) % mCities.size(); if (tzEqual(getOffset(mCities.get(nindex)), offset)) { return false; } return true; } /** * Shifts cities within the current time zone. * * @param incr the increment, +1 or -1 */ private void shiftWithinTimeZone(int incr) { float offset = getOffset(mCities.get(mCityIndex)); int nindex = (mCityIndex + mCities.size() + incr) % mCities.size(); if (tzEqual(getOffset(mCities.get(nindex)), offset)) { mCityIndex = nindex; goToCity(); } } /** * Returns true if the city name matches the given prefix, ignoring spaces. */ private boolean nameMatches(City city, String prefix) { String cityName = city.getName().replaceAll("[ ]", ""); return prefix.regionMatches(true, 0, cityName, 0, prefix.length()); } /** * Returns true if there are cities matching the given name prefix. */ private boolean hasMatches(String prefix) { for (int i = 0; i < mClockCities.size(); i++) { City city = mClockCities.get(i); if (nameMatches(city, prefix)) { return true; } } return false; } /** * Shifts to the nearest city that matches the new prefix. */ private void shiftByName() { // Attempt to keep current city if it matches City finalCity = null; City currCity = mCities.get(mCityIndex); if (nameMatches(currCity, mCityName)) { finalCity = currCity; } mCityNameMatches.clear(); for (int i = 0; i < mClockCities.size(); i++) { City city = mClockCities.get(i); if (nameMatches(city, mCityName)) { mCityNameMatches.add(city); } } mCities = mCityNameMatches; if (finalCity != null) { for (int i = 0; i < mCityNameMatches.size(); i++) { if (mCityNameMatches.get(i) == finalCity) { mCityIndex = i; break; } } } else { // Find the closest matching city locateCity(false, 0.0f); } goToCity(); } /** * Increases or decreases the rotational speed of the earth. */ private void incrementRotationalVelocity(float incr) { if (mDisplayWorldFlat) { mWrapVelocity -= incr; } else { mRotVelocity -= incr; } } /** * Clears the current matching prefix, while keeping the focus on * the current city. */ private void clearCityMatches() { // Determine the global city index that matches the current city if (mCityNameMatches.size() > 0) { City city = mCityNameMatches.get(mCityIndex); for (int i = 0; i < mClockCities.size(); i++) { City ncity = mClockCities.get(i); if (city.equals(ncity)) { mCityIndex = i; break; } } } mCityName = ""; mCityNameMatches.clear(); mCities = mClockCities; goToCity(); } /** * Fade the clock in or out. */ private void enableClock(boolean enabled) { mClockFadeTime = System.currentTimeMillis(); mDisplayClock = enabled; mClockShowing = true; mAlphaKeySet = enabled; if (enabled) { // Find the closest matching city locateCity(false, 0.0f); } clearCityMatches(); } /** * Use the touchscreen to alter the rotational velocity or the * tilt of the earth. */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mMotionStartX = event.getX(); mMotionStartY = event.getY(); mMotionStartRotVelocity = mDisplayWorldFlat ? mWrapVelocity : mRotVelocity; mMotionStartTiltAngle = mTiltAngle; // Stop the rotation if (mDisplayWorldFlat) { mWrapVelocity = 0.0f; } else { mRotVelocity = 0.0f; } mMotionDirection = MOTION_NONE; break; case MotionEvent.ACTION_MOVE: // Disregard motion events when the clock is displayed float dx = event.getX() - mMotionStartX; float dy = event.getY() - mMotionStartY; float delx = Math.abs(dx); float dely = Math.abs(dy); // Determine the direction of motion (major axis) // Once if has been determined, it's locked in until // we receive ACTION_UP or ACTION_CANCEL if ((mMotionDirection == MOTION_NONE) && (delx + dely > MIN_MANHATTAN_DISTANCE)) { if (delx > dely) { mMotionDirection = MOTION_X; } else { mMotionDirection = MOTION_Y; } } // If the clock is displayed, don't actually rotate or tilt; // just use mMotionDirection to record whether motion occurred if (!mDisplayClock) { if (mMotionDirection == MOTION_X) { if (mDisplayWorldFlat) { mWrapVelocity = mMotionStartRotVelocity + dx * ROTATION_FACTOR; } else { mRotVelocity = mMotionStartRotVelocity + dx * ROTATION_FACTOR; } mClock.setCity(null); } else if (mMotionDirection == MOTION_Y && !mDisplayWorldFlat) { mTiltAngle = mMotionStartTiltAngle + dy * TILT_FACTOR; if (mTiltAngle < -90.0f) { mTiltAngle = -90.0f; } if (mTiltAngle > 90.0f) { mTiltAngle = 90.0f; } mClock.setCity(null); } } break; case MotionEvent.ACTION_UP: mMotionDirection = MOTION_NONE; break; case MotionEvent.ACTION_CANCEL: mTiltAngle = mMotionStartTiltAngle; if (mDisplayWorldFlat) { mWrapVelocity = mMotionStartRotVelocity; } else { mRotVelocity = mMotionStartRotVelocity; } mMotionDirection = MOTION_NONE; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -