سورس بازی AnEggs در اندروید
یکشنبه 7 خرداد 1396در این بازی قرار است تخم مرغ هایی که از بالا به سمت پایین می آید داخل سبد برود و اگر کاربر سرعتش بالا نباشد و تخم مرغ ها بشکند امتیاز از آن کم خواهد شد و نمی تواند به مرحله ی بعد برود این بازی دو نفره هم انجام می شود.
در لایه layout قطعه کد زیر را می نویسیم:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/widget_rel1"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:qwad="http://schemas.android.com/apk/res/i4napps.theeggs"
>
<AbsoluteLayout android:id="@+id/widget1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
>
<!-- background -->
<ImageView android:id="@+id/background"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="0dp" android:layout_y="0dp" android:src="@drawable/background">
</ImageView>
<!-- buttons -->
<ImageButton android:id="@+id/infoButton"
android:layout_width="98dp" android:layout_height="59dp"
android:layout_x="0dp" android:layout_y="0dp" android:src="@drawable/btn_info_black"
android:background="#0000"
>
</ImageButton>
<!-- catcher views -->
<!-- catcher left -->
<ImageView android:id="@+id/catcherLeft"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="203dp" android:layout_y="144dp" android:src="@drawable/catcher_left">
</ImageView>
<!-- catcher right -->
<ImageView android:id="@+id/catcherRight"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="238dp" android:layout_y="149dp" android:src="@drawable/catcher_right">
</ImageView>
<!-- catcher ltop -->
<ImageView android:id="@+id/catcherLTop"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="181dp" android:layout_y="142dp" android:src="@drawable/catcher_ltop">
</ImageView>
<!-- catcher lbottom -->
<ImageView android:id="@+id/catcherLBottom"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="179dp" android:layout_y="178dp" android:src="@drawable/catcher_lbottom">
</ImageView>
<!-- catcher rtop -->
<ImageView android:id="@+id/catcherRTop"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="271dp" android:layout_y="149dp" android:src="@drawable/catcher_rtop">
</ImageView>
<!-- catcher rbottom -->
<ImageView android:id="@+id/catcherRBottom"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="267dp" android:layout_y="181dp" android:src="@drawable/catcher_rbottom">
</ImageView>
<!-- catcher helper -->
<ImageView android:id="@+id/helper"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="154dp" android:layout_y="84dp" android:src="@drawable/helper">
</ImageView>
<!-- sound -->
<ImageView android:id="@+id/sound"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="198dp" android:layout_y="92dp"
android:src="@drawable/sound">
</ImageView>
<!-- pause -->
<ImageView android:id="@+id/pause"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="227dp" android:layout_y="90dp" android:src="@drawable/pause">
</ImageView>
<!-- direction buttons -->
<ImageButton android:id="@+id/btnLTop"
android:layout_width="wrap_content" android:layout_y="168dip"
android:layout_x="0dip" android:layout_height="wrap_content"
android:src="@drawable/btn_ltop_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnLBottom"
android:layout_width="wrap_content" android:layout_y="244dip"
android:layout_x="0dip" android:layout_height="wrap_content"
android:src="@drawable/btn_lbottom_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnRTop"
android:layout_width="wrap_content" android:layout_y="168dip"
android:layout_x="368dip" android:layout_height="wrap_content"
android:src="@drawable/btn_rtop_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnRBottom"
android:layout_width="wrap_content" android:layout_y="244dip"
android:layout_x="365dip" android:layout_height="wrap_content"
android:src="@drawable/btn_rbottom_states"
android:background="#0000"
>
</ImageButton>
<!-- sound, game 1 and 2, stats, pause? -->
<ImageButton android:id="@+id/btnSound"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="-5dp" android:layout_y="49dp"
android:src="@drawable/btn_sound_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnPause"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="-5dp" android:layout_y="88dp"
android:src="@drawable/btn_pause_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnGameI"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="376dp" android:layout_y="20dp"
android:src="@drawable/btn_game1_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnGameII"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="376dp" android:layout_y="73dp"
android:src="@drawable/btn_game2_states"
android:background="#0000"
>
</ImageButton>
<ImageButton android:id="@+id/btnStats"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="376dp" android:layout_y="108dp"
android:src="@drawable/btn_stats_states"
android:background="#0000"
>
</ImageButton>
<!-- Projectiles -->
<!-- Trajectory 0 -->
<ImageView android:id="@+id/proj00"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="144dp" android:layout_y="164dp"
android:src="@drawable/proj00">
</ImageView>
<ImageView android:id="@+id/proj01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="153dp" android:layout_y="166dp"
android:src="@drawable/proj01">
</ImageView>
<ImageView android:id="@+id/proj02"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="159dp" android:layout_y="174dp"
android:src="@drawable/proj02">
</ImageView>
<ImageView android:id="@+id/proj03"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="169dp" android:layout_y="179dp"
android:src="@drawable/proj03">
</ImageView>
<ImageView android:id="@+id/proj04"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="177dp" android:layout_y="184dp"
android:src="@drawable/proj04">
</ImageView>
<!-- Trajectory 1 -->
<ImageView android:id="@+id/proj10"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="145dp" android:layout_y="128dp"
android:src="@drawable/proj10">
</ImageView>
<ImageView android:id="@+id/proj11"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="153dp" android:layout_y="132dp"
android:src="@drawable/proj11">
</ImageView>
<ImageView android:id="@+id/proj12"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="160dp" android:layout_y="139dp"
android:src="@drawable/proj12">
</ImageView>
<ImageView android:id="@+id/proj13"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="168dp" android:layout_y="143dp"
android:src="@drawable/proj13">
</ImageView>
<ImageView android:id="@+id/proj14"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="175dp" android:layout_y="150dp"
android:src="@drawable/proj14">
</ImageView>
<!-- Trajectory 2 -->
<ImageView android:id="@+id/proj20"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="326dp" android:layout_y="128dp"
android:src="@drawable/proj20">
</ImageView>
<ImageView android:id="@+id/proj21"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="319dp" android:layout_y="132dp"
android:src="@drawable/proj21">
</ImageView>
<ImageView android:id="@+id/proj22"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="310dp" android:layout_y="138dp"
android:src="@drawable/proj22">
</ImageView>
<ImageView android:id="@+id/proj23"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="302dp" android:layout_y="145dp"
android:src="@drawable/proj23">
</ImageView>
<ImageView android:id="@+id/proj24"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="296dp" android:layout_y="150dp"
android:src="@drawable/proj24">
</ImageView>
<!-- Trajectory 3 -->
<ImageView android:id="@+id/proj30"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="325dp" android:layout_y="165dp"
android:src="@drawable/proj30">
</ImageView>
<ImageView android:id="@+id/proj31"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="318dp" android:layout_y="169dp"
android:src="@drawable/proj31">
</ImageView>
<ImageView android:id="@+id/proj32"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="309dp" android:layout_y="174dp"
android:src="@drawable/proj32">
</ImageView>
<ImageView android:id="@+id/proj33"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="301dp" android:layout_y="181dp"
android:src="@drawable/proj33">
</ImageView>
<ImageView android:id="@+id/proj34"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="293dp" android:layout_y="184dp"
android:src="@drawable/proj34">
</ImageView>
<!-- points -->
<ImageView android:id="@+id/points0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="294dp" android:layout_y="92dp"
android:src="@drawable/digit0">
</ImageView>
<ImageView android:id="@+id/points1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="279dp" android:layout_y="92dp"
android:src="@drawable/digit1">
</ImageView>
<ImageView android:id="@+id/points2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="264dp" android:layout_y="92dp"
android:src="@drawable/digit2">
</ImageView>
<ImageView android:id="@+id/points3"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="249dp" android:layout_y="92dp"
android:src="@drawable/digit3">
</ImageView>
<!-- penalties -->
<ImageView android:id="@+id/penalty1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="280dp" android:layout_y="122dp"
android:src="@drawable/penalty1">
</ImageView>
<ImageView android:id="@+id/penalty2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="263dp" android:layout_y="122dp"
android:src="@drawable/penalty2">
</ImageView>
<ImageView android:id="@+id/penalty3"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="247dp" android:layout_y="122dp"
android:src="@drawable/penalty3">
</ImageView>
<!-- game labels -->
<ImageView android:id="@+id/lblGame1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="139dp" android:layout_y="224dp"
android:src="@drawable/lbl_game1">
</ImageView>
<ImageView android:id="@+id/lblGame2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="313dp" android:layout_y="224dp"
android:src="@drawable/lbl_game2">
</ImageView>
<!-- crash views -->
<!-- left -->
<ImageView android:id="@+id/lcrash0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="170dp" android:layout_y="212dp"
android:src="@drawable/lcrash0">
</ImageView>
<ImageView android:id="@+id/lcrash1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="165dp" android:layout_y="192dp"
android:src="@drawable/lcrash1">
</ImageView>
<ImageView android:id="@+id/lcrash2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="159dp" android:layout_y="205dp"
android:src="@drawable/lcrash2">
</ImageView>
<ImageView android:id="@+id/lcrash3"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="148dp" android:layout_y="205dp"
android:src="@drawable/lcrash3">
</ImageView>
<ImageView android:id="@+id/lcrash4"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="135dp" android:layout_y="205dp"
android:src="@drawable/lcrash4">
</ImageView>
<!-- right -->
<ImageView android:id="@+id/rcrash0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="273dp" android:layout_y="215dp"
android:src="@drawable/rcrash0">
</ImageView>
<ImageView android:id="@+id/rcrash1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="297dp" android:layout_y="194dp"
android:src="@drawable/rcrash1">
</ImageView>
<ImageView android:id="@+id/rcrash2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="313dp" android:layout_y="207dp"
android:src="@drawable/rcrash2">
</ImageView>
<ImageView android:id="@+id/rcrash3"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="323dp" android:layout_y="207dp"
android:src="@drawable/rcrash3">
</ImageView>
<ImageView android:id="@+id/rcrash4"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_x="336dp" android:layout_y="208dp"
android:src="@drawable/rcrash4">
</ImageView>
<!-- ads -->
<!-- -->
<com.qwapi.adclient.android.view.QWAdView
android:id="@+id/QWAd"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_x="90dp" android:layout_y="0dp"
qwad:siteId="anEggs-g6jdmcgw"
qwad:publisherId="fb936e4c62ed40fd8514f9737fa5a980"
qwad:mediaType="banner"
qwad:placement="top"
qwad:adInterval="30"
qwad:animation="slide"
qwad:adEventListenerClass="i4napps.theeggs.MainActivity"
/>
<!-- qwad:adEventListenerClass="MainActivity" -->
<!-- qwad:testMode="true" -->
<!-- qwad:displayMode="autoRotate" -->
<!-- qwad:renderAdOnCreate="true" -->
</AbsoluteLayout>
</RelativeLayout>
در کلاس جاوا قطعه کد زیر را قرار دهید:
package i4napps.theeggs;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import com.qwapi.adclient.android.data.Ad;
import com.qwapi.adclient.android.data.Status;
import com.qwapi.adclient.android.requestparams.AdRequestParams;
import com.qwapi.adclient.android.view.AdEventsListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
public class MainActivity extends Activity implements AdEventsListener {
static final int DIALOG_INFO_ID = 0;
static final int DIALOG_STATS_ID = 1;
static final int DIALOG_UNLOCK_ID = 2;
static final int CATCHER_LBOTTOM = 0;
static final int CATCHER_LTOP = 1;
static final int CATCHER_RTOP = 2;
static final int CATCHER_RBOTTOM = 3;
static final int GAME_MODE_I = 0;
static final int GAME_MODE_II = 1;
static final int STATE_READY = 0;
static final int STATE_RUNNING = 1;
static final int STATE_PAUSED = 2;
private Random mRandom = new Random(System.currentTimeMillis());
private boolean mUnlocked = false;
private int mScoreGameI = 0;
private int mScoreGameII = 0;
private int mCatcherPosition = CATCHER_LTOP;
private boolean mHelperVisible = false;
private boolean mSoundOn = true;
private boolean mCatchAll = false;
private int mPenaltiesLimit = 6;
private Timer mHelperTimer = null;
private void updateCatcher() {
// hide/show catcher parts using current catcher position
((ImageView)findViewById(R.id.catcherLeft)).setVisibility((mCatcherPosition == CATCHER_LTOP || mCatcherPosition == CATCHER_LBOTTOM ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.catcherRight)).setVisibility((mCatcherPosition == CATCHER_RTOP || mCatcherPosition == CATCHER_RBOTTOM ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.catcherLTop)).setVisibility((mCatcherPosition == CATCHER_LTOP ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.catcherLBottom)).setVisibility((mCatcherPosition == CATCHER_LBOTTOM ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.catcherRTop)).setVisibility((mCatcherPosition == CATCHER_RTOP ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.catcherRBottom)).setVisibility((mCatcherPosition == CATCHER_RBOTTOM ? View.VISIBLE : View.INVISIBLE));
}
// Need handler for callbacks to the UI thread
final Handler mHandler = new Handler();
/* Helper */
// Create runnable for posting helper updates
final Runnable mToggleHelper = new Runnable() {
public void run() {
mHelperVisible = !mHelperVisible;
updateHelper();
}
};
private void updateHelper() {
// hide/show helper
((ImageView)findViewById(R.id.helper)).setVisibility((mHelperVisible == true ? View.VISIBLE : View.INVISIBLE));
}
private class HelperTask extends TimerTask {
@Override
public void run() {
mHandler.post(mToggleHelper);
}
}
// game update
private int mDigitViewIds[] = null;
private void initDigitViewIds() {
mDigitViewIds = new int[10];
mDigitViewIds[0] = R.drawable.digit0;
mDigitViewIds[1] = R.drawable.digit1;
mDigitViewIds[2] = R.drawable.digit2;
mDigitViewIds[3] = R.drawable.digit3;
mDigitViewIds[4] = R.drawable.digit4;
mDigitViewIds[5] = R.drawable.digit5;
mDigitViewIds[6] = R.drawable.digit6;
mDigitViewIds[7] = R.drawable.digit7;
mDigitViewIds[8] = R.drawable.digit8;
mDigitViewIds[9] = R.drawable.digit9;
}
private ImageView mPointsViews[] = null;
private void initPointsViews() {
mPointsViews = new ImageView[4];
mPointsViews[0] = (ImageView) findViewById(R.id.points0);
mPointsViews[1] = (ImageView) findViewById(R.id.points1);;
mPointsViews[2] = (ImageView) findViewById(R.id.points2);;
mPointsViews[3] = (ImageView) findViewById(R.id.points3);;
}
private ImageView[][] mProjectileViews = null;
private void initProjectileViews() {
mProjectileViews = new ImageView[4][5];
mProjectileViews[0][0] = (ImageView)findViewById(R.id.proj00);
mProjectileViews[0][1] = (ImageView)findViewById(R.id.proj01);
mProjectileViews[0][2] = (ImageView)findViewById(R.id.proj02);
mProjectileViews[0][3] = (ImageView)findViewById(R.id.proj03);
mProjectileViews[0][4] = (ImageView)findViewById(R.id.proj04);
mProjectileViews[1][0] = (ImageView)findViewById(R.id.proj10);
mProjectileViews[1][1] = (ImageView)findViewById(R.id.proj11);
mProjectileViews[1][2] = (ImageView)findViewById(R.id.proj12);
mProjectileViews[1][3] = (ImageView)findViewById(R.id.proj13);
mProjectileViews[1][4] = (ImageView)findViewById(R.id.proj14);
mProjectileViews[2][0] = (ImageView)findViewById(R.id.proj20);
mProjectileViews[2][1] = (ImageView)findViewById(R.id.proj21);
mProjectileViews[2][2] = (ImageView)findViewById(R.id.proj22);
mProjectileViews[2][3] = (ImageView)findViewById(R.id.proj23);
mProjectileViews[2][4] = (ImageView)findViewById(R.id.proj24);
mProjectileViews[3][0] = (ImageView)findViewById(R.id.proj30);
mProjectileViews[3][1] = (ImageView)findViewById(R.id.proj31);
mProjectileViews[3][2] = (ImageView)findViewById(R.id.proj32);
mProjectileViews[3][3] = (ImageView)findViewById(R.id.proj33);
mProjectileViews[3][4] = (ImageView)findViewById(R.id.proj34);
}
private void updateTrajectories() {
// projectiles
for (int i = 0; i < mProjectileViews.length; i++) {
for (int j = 0; j < mProjectileViews[i].length; j++) {
boolean hasProjectile = mGameThread.hasProjectileOn(i, j);
mProjectileViews[i][j].setVisibility((hasProjectile ? View.VISIBLE : View.INVISIBLE));
}
}
}
private void updatePoints() {
// update points views
boolean leadintZero = true;
int points = mGameThread.points;
int divider = 1000;
for (int i = 3; i >= 0; i--) {
int digit = points / divider;
if (digit == 0 && leadintZero && i > 0) {
mPointsViews[i].setVisibility(View.INVISIBLE);
} else {
leadintZero = false;
mPointsViews[i].setImageResource(mDigitViewIds[digit]);
mPointsViews[i].setVisibility(View.VISIBLE);
}
points %= divider;
divider /= 10;
}
}
private ImageView mPenaltyViews[] = null;
private void initPenalties() {
mPenaltyViews = new ImageView[3];
mPenaltyViews[0] = (ImageView) findViewById(R.id.penalty1);
mPenaltyViews[1] = (ImageView) findViewById(R.id.penalty2);
mPenaltyViews[2] = (ImageView) findViewById(R.id.penalty3);
}
private void updatePenalties() {
// update penalties views
if (mGameThread.penalties == 0) {
for (int i = 0; i < mPenaltyViews.length; i++) {
mPenaltyViews[i].setVisibility(View.INVISIBLE);
}
return;
}
for (int i = mGameThread.penalties, idx = 0; i > 0; i -= 2) {
int oddVisibility = (mPenaltyViews[idx].getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
mPenaltyViews[idx].setVisibility((i == 1) ? oddVisibility : View.VISIBLE);
idx++;
}
}
private MediaPlayer mCatchSnd = null;
private MediaPlayer mCrashSnd = null;
private MediaPlayer mGameOverSnd = null;
private MediaPlayer mResetSnd = null;
private MediaPlayer mMoveSounds[] = null;
private void initSounds() {
mCatchSnd = MediaPlayer.create(this, R.raw.snd_catch);
mCrashSnd = MediaPlayer.create(this, R.raw.snd_crash);
mGameOverSnd = MediaPlayer.create(this, R.raw.snd_game_over);
mResetSnd = MediaPlayer.create(this, R.raw.snd_reset);
mMoveSounds = new MediaPlayer[4];
mMoveSounds[0] = MediaPlayer.create(this, R.raw.snd_move0);
mMoveSounds[1] = MediaPlayer.create(this, R.raw.snd_move1);
mMoveSounds[2] = MediaPlayer.create(this, R.raw.snd_move2);
mMoveSounds[3] = MediaPlayer.create(this, R.raw.snd_move3);
}
private ImageView mLeftCrashViews[] = null;
private ImageView mRightCrashViews[] = null;
private void initCrashViews() {
mLeftCrashViews = new ImageView[5];
mLeftCrashViews[0] = (ImageView) findViewById(R.id.lcrash0);
mLeftCrashViews[1] = (ImageView) findViewById(R.id.lcrash1);
mLeftCrashViews[2] = (ImageView) findViewById(R.id.lcrash2);
mLeftCrashViews[3] = (ImageView) findViewById(R.id.lcrash3);
mLeftCrashViews[4] = (ImageView) findViewById(R.id.lcrash4);
for (int i = 0; i < mLeftCrashViews.length; i++) {
mLeftCrashViews[i].setVisibility(View.INVISIBLE);
}
mRightCrashViews = new ImageView[5];
mRightCrashViews[0] = (ImageView) findViewById(R.id.rcrash0);
mRightCrashViews[1] = (ImageView) findViewById(R.id.rcrash1);
mRightCrashViews[2] = (ImageView) findViewById(R.id.rcrash2);
mRightCrashViews[3] = (ImageView) findViewById(R.id.rcrash3);
mRightCrashViews[4] = (ImageView) findViewById(R.id.rcrash4);
for (int i = 0; i < mRightCrashViews.length; i++) {
mRightCrashViews[i].setVisibility(View.INVISIBLE);
}
}
private boolean mSaved = false;
private int mCrashStepIdx = -1;
final static int SIDE_LEFT = 0;
final static int SIDE_RIGHT = 1;
private int mCrashSide = SIDE_LEFT;
private class CrashThread extends Thread {
@Override
public void run() {
// do the crash "animation"
int crashSteps = (mSaved ? 5 : 1);
long delay = (mSaved ? 500 : 1000); // need at least 500, otherwise sound gets skipped (iphone os works fine though...)
mCrashStepIdx = 0;
for (int i = 0; i < crashSteps; i++) {
mHandler.post(mCrashStep);
try {
sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
mCrashStepIdx++;
}
// clear crashes with no sound
mCrashStepIdx = -1;
mHandler.post(mCrashStep);
// resume after crash
mHandler.post(mResumeAfterCrash);
}
}
private final Runnable mCrashStep = new Runnable() {
public void run() {
// play sound if not hiding
if (mSoundOn && mCrashStepIdx >= 0) {
mCrashSnd.start();
}
ImageView[] crashViews = (mCrashSide == SIDE_LEFT ? mLeftCrashViews : mRightCrashViews);
// show one crash view, hide others or hide all
for (int i = 0; i < crashViews.length; i++) {
crashViews[i].setVisibility((i == mCrashStepIdx ? View.VISIBLE : View.INVISIBLE));
}
}
};
private final Runnable mResumeAfterCrash = new Runnable() {
public void run() {
// animation completed, update penalties now
updatePenalties();
// update projectiles (trajectory views) on the screen (they've been just reset)
updateTrajectories();
if (mGameThread.penalties >= 6) {
mGameThread.state = STATE_READY;
// game over
if (mSoundOn) {
// play game over sound
mGameOverSnd.start();
}
// update score
if (mGameThread.gameMode == GAME_MODE_I) {
mScoreGameI = (mScoreGameI < mGameThread.points ? mGameThread.points : mScoreGameI);
} else {
mScoreGameII = (mScoreGameII < mGameThread.points ? mGameThread.points : mScoreGameII);
}
} else {
// forget such stuff as pause during crash and just resume
mGameThread.resumeGame();
}
}
};
private class ResetThread extends Thread {
@Override
public void run() {
// do the reset "animation"
mPenaltiesHidden = true;
for (int i = 0; i < 6; i++) {
mHandler.post(mBlinkPenalties);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
mPenaltiesHidden = !mPenaltiesHidden;
}
mHandler.post(mResumeAfterReset);
}
};
private boolean mPenaltiesHidden = false;
private final Runnable mBlinkPenalties = new Runnable() {
public void run() {
if (mSoundOn && !mPenaltiesHidden) {
mResetSnd.start();
}
int visibility = (mPenaltiesHidden ? View.INVISIBLE : View.VISIBLE);
int lastPenIdx = mGameThread.penalties / 2 + mGameThread.penalties % 2;
for (int i = 0; i < lastPenIdx; i++) {
mPenaltyViews[i].setVisibility(visibility);
}
}
};
private final Runnable mResumeAfterReset = new Runnable() {
public void run() {
// set new penalties value
mGameThread.penalties = 0;
// clear penalties
updatePenalties();
// can go on now
mGameThread.resumeGame();
//updatePause();
}
};
final Runnable mGameUpdate = new Runnable() {
public void run() {
// update projectiles, points on UI
Log.d("x", "update game");
updateTrajectories();
updatePenalties();
// check fell down projectiles
int fellDownId = mGameThread.getFellDownId();
if (fellDownId >= 0) { // projectile fell
// check if fallen projectile has been caught or not
// by checking current catcher position
if (mCatchAll) {
// need to perform on main thread, to see result on screen immediately
mCatcherPosition = fellDownId;
updateCatcher();
}
if (fellDownId == mCatcherPosition) {
if (++mGameThread.points > 9999) {
mGameThread.points = 0;
}
// the projectile is caught
if (mSoundOn) {
// play catch sound
mCatchSnd.start();
}
// update points
updatePoints();
// check the milestones, if one of them is reached, reset penalties (if any)
int pointsRem = mGameThread.points % 1000;
if (mGameThread.penalties > 0
&& (pointsRem == 0 /* test */ || pointsRem == 200 || pointsRem == 500))
{
// pause game thread
mGameThread.suspendGame();
//updatePause();
// reset penalties animation (run in a thread)
new ResetThread().start();
}
} else {
// projectile fell down
// pause game thread
mGameThread.suspendGame();
//updatePause();
mCrashSide = (fellDownId < 2 ? SIDE_LEFT : SIDE_RIGHT);
// add penalty points and check the half penalty point condition
// NOTE: the hidden property of the helperWorker is changed in advance,
// so the "old" value should be checked
mSaved = mHelperVisible;
mGameThread.penalties += (mSaved ? 1 : 2);
if (mGameThread.penalties > mPenaltiesLimit) mGameThread.penalties = mPenaltiesLimit;
// update projectile worker delegate and current time frame
// before starting animation, to allow correct recovery if power goes off
// during that animation
mGameThread.resetProjectiles();
// submit fall down animation to observer view controller
// the animation will happen in another thread posting ui updates to main thread
new CrashThread().start();
}
} else { // no fallen projectile
if (mSoundOn) {
// play sound corresponding to moved trajectory
mMoveSounds[mGameThread.activeTrajId].start();
}
}
}
};
/* Game Thread */
private GameThread mGameThread = null;
private class GameThread extends Thread {
private long mTick;
private boolean suspended = true;
public int state = STATE_READY;
public int gameMode = GAME_MODE_I;
public int points = 0;
public int penalties = 0;
private int maxTraj = 0;
private int activeTrajId = 0;
private int trajectoriesNumber = 4;
private int trajectoryLength = 6;
private int lengthMask = 0xFF << trajectoryLength;
private int addNewMask = 0x3;
private int newProjectileMask = 0x1;
private int lastActivePositionMask = 0x1 << (trajectoryLength - 2);
private int emptyTrajectoryMask = 0xFF << (trajectoryLength - 1);
private int gapCnt = 0;
private byte trajectories[] = new byte[4];
private int trajectoryQueueIdx = -1;
private int trajectoryQueueCnt = 0;
private byte trajectoriesQueue[] = new byte[4];
@Override
public void run() {
while (true) {
try {
sleep(sleepInterval());
synchronized(this) {
while (suspended)
wait();
}
} catch (InterruptedException e){
}
// update projectiles and post to UI thread
udpateProjectiles(mTick);
// notify to UI thread
mHandler.post(mGameUpdate);
mTick++;
}
}
private long sleepInterval() {
float nextTick = 1000;
long pointsDiv = points % 1000;
long pointsRem = points % 100;
// just hardcode it for now
if (maxTraj == 3) {
nextTick = (float) ((pointsDiv < 200 ? 0.6 : 0.5) - 0.1 * (points / 1000));
if (pointsDiv < 200 && pointsRem > 5) {
nextTick -= (pointsRem < 20 ? 0.1 : 0.15);
} else if (pointsDiv >= 200 && pointsRem > 5) {
nextTick -= (pointsRem < 20 ? 0.05 : 0.1);
}
} else {
nextTick = (float) (0.505 - 0.1 * (points / 1000));
if (pointsRem > 10) {
nextTick -= (pointsRem < 30 ? 0.05 : 0.1);
}
nextTick -= 0.005 * (pointsDiv / 100);
}
long result = (long) (1000 * (nextTick <= 0.1 ? 0.1 : nextTick));
//result = (points < 10 || points > 500 ? 100 : 5);
//result = (points < 9990 ? 1 : 300);
return result;
}
private int curGap(long tick) {
if (tick == 0) return 0;
int gapMin = (points % 100 <= 5 ? 6 : 1);
int gapMax = (points % 100 <= 20 ? 9 : 6);
int gap;
do {
gap = mRandom.nextInt(10);
} while(gap < gapMin && gap > gapMax);
return (gap <= 1 ? 1 : gap);
}
private int modeCnt() {
int cnt = 0;
for (int i = 0; i < trajectoriesNumber; i++) {
if ((trajectories[i] & (~emptyTrajectoryMask)) != 0) cnt++;
}
return cnt;
}
private boolean canAddNew() {
int tightCount = 0;
for (int i = 0; i < trajectoriesNumber; i++) {
if ((trajectories[i] & addNewMask) != 0) tightCount++;
}
return (tightCount == maxTraj ? false : true);
}
private int nextTrajectoryId() {
if (trajectoryQueueCnt == 0) return -1;
do {
trajectoryQueueIdx = (trajectoryQueueIdx + 1) % trajectoryQueueCnt;
} while (trajectoriesQueue[trajectoryQueueIdx] < 0);
return trajectoriesQueue[trajectoryQueueIdx]; // don't forget to increase idx
}
private void queueTrajectory(int trajId) {
// add trajectory to the queue
// check duplicates
for (int i = 0; i < trajectoryQueueCnt; i++) {
if (trajectoriesQueue[i] == trajId) {
return; // already queued
}
}
// not yet queued: add
trajectoriesQueue[trajectoryQueueCnt] = (byte) trajId;
trajectoryQueueCnt++; // increase count
if (trajectoryQueueCnt > trajectoriesNumber) {
Log.e("Error", "Trajectory queueing error");
}
}
private void dequeueTrajectory(int trajId) {
// remove trajectory from the queue (also shift elements if needed)
for (int i = 0; i < trajectoryQueueCnt; i++) {
if (trajectoriesQueue[i] == trajId) {
// found in queue, remove now
// shift to the left
for (int j = i; j < trajectoryQueueCnt - 1; j++) {
trajectoriesQueue[j] = trajectoriesQueue[j + 1];
}
// clear last queue element
trajectoriesQueue[trajectoryQueueCnt - 1] = 0xF; // (-1)
trajectoryQueueCnt--; // decrease count
// if dequeued element's index is less or equal to current index, then current index must
// by cycled one position back (to the last position in case of 0th element)
// this correction is required, because getNextTrajId makes increment (+1) first (do...while loop)
if (i <= trajectoryQueueIdx) {
trajectoryQueueIdx = (trajectoryQueueIdx == 0 ? (trajectoriesNumber - 1) : (trajectoryQueueIdx - 1));
}
break;
}
}
}
private void udpateProjectiles(long tick) {
clearFallenProjectiles();
// find out which trajectory has to be updated
activeTrajId = nextTrajectoryId();
if (activeTrajId >= 0) {
// move a projectiles on that trajectory
// if last projectile will move to the last position (fall)
// then update only that projectile and don't touch others
if ((trajectories[activeTrajId] & lastActivePositionMask) != 0) {
// a projectile is about to fall, update only this projectile
// on given trajectory
trajectories[activeTrajId] &= ~lastActivePositionMask; // remove from last active position
trajectories[activeTrajId] |= (lastActivePositionMask << 1); // add to fallen position
} else {
// nobody falls now, so move all projectiles on this trajectory
trajectories[activeTrajId] <<= 1; // move projectiles
trajectories[activeTrajId] &= (~lengthMask); // clear moved out projectiles
}
}
// if it's time to add a new projectile, then look up
// for trajectory, which will accept it (must have enough space to
// put new projectile, also the mode condition must be kept,
// which means no more than "mode" trajectories can have projectiles
// at one moment
int addTo = -1;
if (gapCnt >= curGap(tick) && canAddNew() || activeTrajId < 0) {
gapCnt = -1; // reset gap count (the very next operation is "++")
do {
addTo = mRandom.nextInt(trajectoriesNumber);
} while ((trajectories[addTo] & addNewMask) != 0 // 2 first positions in traj are empty
|| trajectories[addTo] == 0 && modeCnt() == maxTraj // check mode
// already "mode" trajs busy, can't add to an empty one
);
// set new projectile bit
trajectories[addTo] |= newProjectileMask;
// add this trajectory to trajectory queue (duplicates are checked)
queueTrajectory(addTo);
}
if (activeTrajId >= 0) {
// if active trajectory is empty (don't cout fallen projectiles), then dequeue it
if ((trajectories[activeTrajId] & (~emptyTrajectoryMask)) == 0) {
dequeueTrajectory(activeTrajId);
}
}
gapCnt++; // increase new projectile gap count
// update the active trajectory id, needed for a sound
if (activeTrajId < 0 && addTo >=0 ) activeTrajId = addTo;
// that's it, the projectiles are moved and added, queued and dequeued
}
private void clearFallenProjectiles() {
for (int i = 0; i < trajectoriesNumber; i++) {
trajectories[i] &= (~emptyTrajectoryMask);
}
}
public synchronized boolean hasProjectileOn(int trajId, int idx) {
if ((trajectories[trajId] & (1 << idx)) != 0) return true;
return false;
}
public synchronized boolean projectileFell(int trajId) {
return hasProjectileOn(trajId, trajectoryLength - 1);
}
public synchronized int getFellDownId() {
for (int i = 0; i < trajectoriesNumber; i++) {
if (projectileFell(i)) return i;
}
return -1;
}
public void startGame(int mode) {
resetGame();
gameMode = mode;
maxTraj = (gameMode == GAME_MODE_I ? 3 : 4);
resumeGame();
state = STATE_RUNNING;
}
public void resetProjectiles() {
trajectoryQueueCnt = 0;
trajectoryQueueIdx = -1;
for (int i = 0; i < trajectories.length; i++) {
trajectories[i] = 0x0;
}
for (int i = 0; i < trajectoriesQueue.length; i++) {
trajectoriesQueue[i] = 0xF;
}
}
public void resetGame() {
mTick = 0;
points = 0;
penalties = 0;
state = STATE_READY;
activeTrajId = 0;
gapCnt = 0;
resetProjectiles();
}
public synchronized void suspendGame() {
if (suspended) return;
suspended = true;
notify();
state = STATE_PAUSED;
}
public synchronized void resumeGame() {
if (!suspended) return;
suspended = false;
notify();
state = STATE_RUNNING;
}
}
private void updateSound() {
((ImageView)findViewById(R.id.sound)).setVisibility((mSoundOn ? View.VISIBLE : View.INVISIBLE));
}
private OnClickListener mInfoListener = new OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_INFO_ID);
}
};
private OnClickListener mStatsListener = new OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_STATS_ID);
}
};
private OnTouchListener mPositionListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (v == findViewById(R.id.btnLTop)) mCatcherPosition = CATCHER_LTOP;
if (v == findViewById(R.id.btnLBottom)) mCatcherPosition = CATCHER_LBOTTOM;
if (v == findViewById(R.id.btnRTop)) mCatcherPosition = CATCHER_RTOP;
if (v == findViewById(R.id.btnRBottom)) mCatcherPosition = CATCHER_RBOTTOM;
updateCatcher();
}
return false;
}
};
private OnClickListener mSoundListener = new OnClickListener() {
public void onClick(View v) {
mSoundOn = !mSoundOn;
updateSound();
}
};
private OnClickListener mGameModeListener = new OnClickListener() {
public void onClick(View v) {
int mode = (v == findViewById(R.id.btnGameI) ? GAME_MODE_I : GAME_MODE_II);
if (mGameThread.state != STATE_READY) return;
// check if game mode 2 is unlocked
if (mAddDisplayed && mode == GAME_MODE_II && !mUnlocked) {
showDialog(DIALOG_UNLOCK_ID);
return;
}
mGameThread.startGame(mode);
updatePoints();
updatePenalties();
((ImageView)findViewById(R.id.lblGame1)).setVisibility((mode == GAME_MODE_I ? View.VISIBLE : View.INVISIBLE));
((ImageView)findViewById(R.id.lblGame2)).setVisibility((mode == GAME_MODE_II ? View.VISIBLE : View.INVISIBLE));
}
};
private void updatePause() {
int pauseVisible = View.INVISIBLE;
if (mGameThread.state == STATE_PAUSED) pauseVisible = View.VISIBLE;
((ImageView)findViewById(R.id.pause)).setVisibility(pauseVisible);
}
private OnTouchListener mPauseListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mAddDisplayed && !mUnlocked) {
showDialog(DIALOG_UNLOCK_ID);
return false;
}
if (mGameThread.state == STATE_RUNNING) {
mGameThread.suspendGame();
} else if (mGameThread.state == STATE_PAUSED) {
mGameThread.resumeGame();
}
updatePause();
}
return false;
}
};
public static final String PREFS_NAME = "TheEggsPrefsFile";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// projectile views
initProjectileViews();
// digits, points, penalties views
initDigitViewIds();
initPointsViews();
initPenalties();
initCrashViews();
// game labels
((ImageView)findViewById(R.id.lblGame1)).setVisibility(View.INVISIBLE);
((ImageView)findViewById(R.id.lblGame2)).setVisibility(View.INVISIBLE);
// set touch listeners for buttons
ImageButton button = (ImageButton) findViewById(R.id.infoButton);
button.setOnClickListener(mInfoListener);
button = (ImageButton) findViewById(R.id.btnStats);
button.setOnClickListener(mStatsListener);
// catcher position buttons
((ImageButton)findViewById(R.id.btnLTop)).setOnTouchListener(mPositionListener);
((ImageButton)findViewById(R.id.btnLBottom)).setOnTouchListener(mPositionListener);
((ImageButton)findViewById(R.id.btnRTop)).setOnTouchListener(mPositionListener);
((ImageButton)findViewById(R.id.btnRBottom)).setOnTouchListener(mPositionListener);
// sound
((ImageButton)findViewById(R.id.btnSound)).setOnClickListener(mSoundListener);
// game mode
((ImageButton)findViewById(R.id.btnGameI)).setOnClickListener(mGameModeListener);
((ImageButton)findViewById(R.id.btnGameII)).setOnClickListener(mGameModeListener);
// pause
((ImageButton)findViewById(R.id.btnPause)).setOnTouchListener(mPauseListener);
// restore scores from preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
mScoreGameI = settings.getInt("scoreGameI", 0);
mScoreGameII = settings.getInt("scoreGameII", 0);
// restore features unlocked status from preferences
mUnlocked = settings.getBoolean("featuresUnlocked", false);
// init sounds
initSounds();
// create helper timer
HelperTask helperTask = new HelperTask();
mHelperTimer = new Timer(true);
mHelperTimer.schedule(helperTask, 5000, 5000);
// game "engine" thread
mGameThread = new GameThread();
mGameThread.start();
// update all views initially
updateCatcher();
updateHelper();
updateSound();
updatePause();
updateTrajectories();
updatePoints();
updatePenalties();
}
@Override
protected void onStop () {
super.onStop();
mGameThread.suspendGame();
//updatePause();
// Save game scores
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("scoreGameI", mScoreGameI);
editor.putInt("scoreGameII", mScoreGameII);
//Log.d("onStop", "Save unlocked status: " + mUnlocked);
editor.putBoolean("featuresUnlocked", mUnlocked);
// Don't forget to commit your edits!!!
editor.commit();
}
@Override
protected void onPause() {
super.onPause();
mGameThread.suspendGame();
//updatePause();
}
@Override
protected void onResume() {
super.onResume();
updatePause();
}
@Override
public Dialog onCreateDialog(int dialogID) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
switch (dialogID) {
case DIALOG_INFO_ID:
String message = null;
try {
message = getString(R.string.app_name)
+ "\n" + getString(R.string.by) + " " + getString(R.string.i4napps)
+ "\n" + "v" + getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
builder.setTitle(getString(R.string.about))
.setMessage(message)
.setCancelable(false)
.setPositiveButton(getString(R.string.OK), null);
break;
case DIALOG_STATS_ID:
builder.setTitle(getString(R.string.high_score))
.setMessage(getString(R.string.game_I) + ":\t" + mScoreGameI
+ "\n" + getString(R.string.game_II) + ":\t" + mScoreGameII)
.setCancelable(false)
.setPositiveButton(getString(R.string.OK), null);
break;
case DIALOG_UNLOCK_ID:
builder.setTitle(getString(R.string.unlock_title))
.setMessage(getString(R.string.unlock_msg))
.setCancelable(false)
.setPositiveButton(getString(R.string.OK), null);
break;
}
AlertDialog alert = builder.create();
return alert;
}
@Override
public void onPrepareDialog(int dialogID, Dialog dialog) {
if (dialogID == DIALOG_STATS_ID) {
((AlertDialog)dialog).setMessage(getString(R.string.game_I) + ":\t" + mScoreGameI
+ "\n" + getString(R.string.game_II) + ":\t" + mScoreGameII);
}
}
public void onAdRequestFailed(Context arg0, AdRequestParams arg1,
Status arg2) {
Log.d("ad", "Ad Request Failed");
// nothing
}
public void onAdRequestSuccessful(Context arg0, AdRequestParams arg1,
Ad arg2) {
Log.d("ad", "Ad Request Successful");
// nothing
}
private boolean mAddDisplayed = false;
public void onDisplayAd(Context arg0, Ad arg1) {
// nothing
Log.d("ad", "Ad Displayed");
((MainActivity)arg0).mAddDisplayed = true;
}
public void onAdClick(Context arg0, Ad arg1) {
// ad click listener
//Log.d("ad", "Ad Click");
// luckily for us, Context is exactly the running activity
((MainActivity)arg0).mUnlocked = true;
}
public void onAdRequest(Context arg0, AdRequestParams arg1) {
// nothing
}
}
خروجی بازی به صورت زیر خواهد بود:

- Android
- 2k بازدید
- 5 تشکر