سورس بازی Ballon Season در اندروید

پنجشنبه 28 بهمن 1395

در این مقاله می خواهیم در مورد بازی Ballon ها صحبت نماییم که این بازی به چه صورت است ، در این بازی بالن هایی از پایین صفحه به بالای صفحه می آیند و شما با ضربه زدن به آن ها امتیاز لازم را کسب می کنید .

سورس بازی Ballon Season در اندروید

ابتدا در مورد لایه layout برنامه صحبت می کنیم:

این بازی بیشتر با سنسور های گوشی شما کار می کند در واقع زمانی که شما بالن ها را می بیند به صورت عکس هستن که این بالن با استفاده از تعریف چند تا Imageview در کنار یک دیگر و حرکت این ها و بازدن ضربه به هر کدام عکس مورد نظر بالن ها عوض می شود، و عکس دومی جای آن را می گیرد فقط حرکت بالن ها مهم است.

چون تعداد لایه ها و کلاس ها زیاد است ما از هر کدام 3 مورد را توضیح می دهیم بقیه کلاس ها و لایه ها را اگر مشکلی داشتید و جایی از آن را متوجه نشدید در بخش انجمن اندروید بپرسید:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
				xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
			    android:layout_width="fill_parent"
			    android:layout_height="fill_parent"
			    android:orientation="vertical"    
			    android:background="@drawable/sky_background"
			    android:weightSum="1">

	<View android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.05"/> 
	<ImageView 
		android:layout_weight="0.50"
		android:src="@drawable/tentative_logo"
		android:layout_height="0dp"
		android:layout_width="fill_parent"
		android:visibility="invisible"
		android:id="@+id/logo"/>

	<View android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.075"/> 
    <LinearLayout android:id="@+id/bottom_elements" android:visibility="invisible" android:weightSum="1" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.375">
	 
	 	<!-- -->
	 	<View android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.12"/> 
        <ImageView 
         	android:layout_height="fill_parent" 
         	android:layout_width="0dp" 
         	android:src="@drawable/menu_start_button" 
         	android:id="@+id/start_button"
         	android:layout_weight="0.4"
         	android:adjustViewBounds="true"/>

       	<ImageView 
         	android:layout_height="fill_parent"                	
         	android:layout_width="0dp" 
         	android:src="@drawable/menu_tutorial_button" 
         	android:id="@+id/tutorial_button"
         	android:adjustViewBounds="true"
			android:layout_weight="0.4"/>	
   	
    	<LinearLayout android:id="@+id/option_button_list" android:layout_width="0dp" android:layout_height="fill_parent" android:orientation="vertical" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_weight="0.081" android:weightSum="0.9">
    	    
	    	<CheckBox android:id="@+id/option_button_sound" android:layout_height="0dp" android:layout_width="fill_parent" android:layout_weight="0.3" android:button="@drawable/option_button_sound"/>

	    	<CheckBox android:id="@+id/option_button_colour_wheel" android:layout_height="0dp" android:layout_width="fill_parent" android:layout_weight="0.3" android:button="@drawable/option_button_colour_wheel"/>

	    	<CheckBox android:id="@+id/option_button_vibrate" android:layout_height="0dp" android:layout_width="fill_parent" android:layout_weight="0.3" android:button="@drawable/option_button_vibrate"/>    

		</LinearLayout>

	</LinearLayout>

	
</LinearLayout>

این لایه از چند Imageview و چک باکس و... تشکیل شده است لایه ای است که کاربر ابتدا چند عکس در صفحه می بیند که این عکس ها برای خروج کاربر ، ادامه بازی و شروع بازی از اول و همین طور برای تنظیمات بازی هم هست که کاربر بتواند صدا را قطع کند یا ویبره ای که بر اثر زدن ضربه به بالن ها انجام می شود آن ها را قطع نماید.

لایه مربوط به توضیح بازی:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:background="@drawable/sky_background">
	<!-- Everything is in a single RelativeLayout for easy exit animation -->
	<RelativeLayout
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/tutorial_frame">
		<RelativeLayout
			android:layout_width="fill_parent"
			android:layout_height="fill_parent">
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_1"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1" >
			    	<ImageView 
			    	    android:layout_width="fill_parent"
			    	    android:layout_height="0dp"
			    	    android:layout_weight="0.3"
			    	    android:src="@drawable/tutorial_label"/>
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.7"
					    android:text="@string/tutorial_page_1"/>    
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_2"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.2"/>
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.8"
					    android:text="@string/tutorial_page_2"/> 
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_3"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:visibility="invisible"
			    android:weightSum="1" >
			    	<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.1"/>   
			   		<LinearLayout
						android:layout_width="fill_parent"
						android:layout_height="0dp"
						android:layout_weight="0.9"
						android:orientation="horizontal"
						android:weightSum="1">
				    	<TextView
						    style="@style/TutorialFont"
							android:layout_height="fill_parent"
							android:layout_width="0dp"
							android:layout_weight="0.85"
						    android:text="@string/tutorial_page_3"/>
	   			   		<ImageView
						    android:layout_height="100dp"
						    android:layout_width="0dp"
						    android:layout_weight="0.15"
						    android:paddingRight="5dp"
						    android:src="@drawable/colour_wheel_target_red"/>		   		    
			   		</LinearLayout> 
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_4"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:background="@drawable/tutorial_combo_examples"
			    android:orientation="vertical"
			    android:visibility="invisible" >
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="fill_parent"
					    android:text="@string/tutorial_page_4"/>
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_5"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.25"/>
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.75"
					    android:text="@string/tutorial_page_5"/>    
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_6"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:background="@drawable/tutorial_mode_buttons"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.1"/>
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.9"
					    android:text="@string/tutorial_page_6"/>
			</LinearLayout>
			<!--  -->
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_7"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:background="@drawable/tutorial_snow"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.3"
					    android:text="@string/tutorial_page_7"
					    android:background="#DD000000"/>
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.7"/>    
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_8"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:background="@drawable/tutorial_sun"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible">
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.25"
					    android:text="@string/tutorial_page_8"
					    android:background="#DD000000"/>
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.75"/>    
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_9"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:background="@drawable/tutorial_fog"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.3"
					    android:text="@string/tutorial_page_9"
					    android:background="#DD000000"/>
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.7"/>    
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_10"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.2"/>    
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.8"
					    android:text="@string/tutorial_page_10"/>
			</LinearLayout>
		   	<LinearLayout
		   	    android:id="@+id/tutorial_page_11"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1"
			    android:visibility="invisible" >
			   		<View
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.3"/>
			    	<TextView
					    style="@style/TutorialFont"
					    android:layout_width="fill_parent"
					    android:layout_height="0dp"
					    android:layout_weight="0.7"
					    android:text="@string/tutorial_page_11"/>    
			</LinearLayout>
		</RelativeLayout>
	
		<RelativeLayout
		      android:layout_width="fill_parent"
		      android:layout_height="fill_parent">
			<LinearLayout 
			    xmlns:android="http://schemas.android.com/apk/res/android"
			    android:layout_width="match_parent"
			    android:layout_height="match_parent"
			    android:orientation="vertical"
			    android:weightSum="1" >
				<View
					android:layout_width="fill_parent"
					android:layout_height="0dp"
					android:layout_weight="0.65"/>
				<LinearLayout
				    android:layout_width="fill_parent"
				    android:layout_height="0dp"
				    android:layout_weight="0.35"
				    android:weightSum="1"
				    android:orientation="horizontal">
				    <ImageButton
						android:background="@null"
						android:id="@+id/exit_tutorial"
						android:src="@drawable/exit_button"
						android:layout_weight="0.2"
						android:layout_width="0dp"
						android:layout_height="fill_parent"/>
					<View android:layout_height="fill_parent" android:layout_width="0dp" android:layout_weight="0.4"/>
	   			    <ImageButton
						android:background="@null"
						android:id="@+id/goto_prev_page"
						android:src="@drawable/prev_button"
						android:layout_weight="0.2"
						android:layout_width="0dp"
						android:layout_height="fill_parent"/>
				    <ImageButton
						android:background="@null"
						android:id="@+id/goto_next_page"
						android:src="@drawable/next_button"
						android:layout_weight="0.2"
						android:layout_width="0dp"
						android:layout_height="fill_parent"/>
				</LinearLayout>     
		  	</LinearLayout>
		</RelativeLayout>
	</RelativeLayout>    
</FrameLayout>

در این لایه برای کاربر در مورد بازی توضیح داده شده است که کاربر می تواند آن را بخواند دو دکمه برای بازگشت به بازی , رفتن به صفحات بعدی هم گذاشته شده است.

لایه سوم :

این لایه در مورد امتیاز دهی به کاربر است که از یک کلاس استفاده شده است:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.balloon.dl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/end_score_layout_empty"
    android:weightSum="1" >
		<com.balloon.dl.customviews.BorderedTextView
		    android:text="@string/game_over_score_label"
			android:layout_weight="0.4"
		    android:layout_height="0dp"
		    android:layout_width="match_parent"
		    android:paddingTop="8dp"
		    android:paddingLeft="8dp"
   		    android:textSize="30dp"
		    android:textColor="#FFECECFF"
		    custom:borderSize="3dp"
			custom:borderColor="#FF777777"/>
		<com.balloon.dl.customviews.BorderedTextView
	        android:id="@+id/final_score"
			android:layout_weight="0.4"
		    android:layout_height="0dp"
		    android:layout_width="match_parent"
		    android:paddingTop="5dp"
		    android:paddingLeft="10dp"
		    android:textSize="40dp"
		    android:textColor="#FFECECFF"
		    custom:borderSize="5dp"
			custom:borderColor="#FF777777"/>
		<com.balloon.dl.customviews.BorderedTextView
		    android:text="@string/game_over_highscore_label"
	        style="@style/GoldenFont"
	        android:id="@+id/high_score_label"
			custom:borderSize="2dp"
		    android:layout_weight="0.2"
		    android:layout_height="0dp"
		    android:layout_width="match_parent"
			custom:borderColor="#FFABAB37"			/>
			<!-- android:visibility="invisible" -->

</LinearLayout>

حالا در مورد کلاس ها می خواهیم توضیح دهیم:

گفتیم که این بازی در مورد حرکت اشکال در بازی است در این بازی حرکت ابر و خورشید را هم داریم برای این کار یک کلاس نوشته شده است که عکس های مربوطه با حرکت x,y بر روی صفحه گوشی شما حرکت خواهند کرد.

package com.balloon.dl;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

public class Cloud extends GameObject{
	private Bitmap mSpriteSheet;
	private int mCloudID;

	public final int ONSCREEN = 0;
	public final int OFFSCREEN_X = 1;
	public final int OFFSCREEN_Y = 2;
	
	private final int mTotalFrames = 7;
	private final int mFPS = 1000/12;
	private long mFrameTimer;
	private int mCurrentFrame;
	private Rect mSRectangle;
	
	private int mCloudHeight;
	private int mCloudWidth;
	
	public Cloud () {
		super();
	}
	
	public void setAttributes(Bitmap sprite, int cloudID, int x, int y, int xSp, int ySp) {
		mSpriteSheet = sprite;
		mCloudHeight = mSpriteSheet.getHeight();
		mCloudWidth = mSpriteSheet.getWidth()/mTotalFrames;
		
		mFrameTimer = 0;
		mCurrentFrame = 0;
		mSRectangle = new Rect();
		
		mCloudID = cloudID;
		updateSpeed(xSp, ySp);
		
		mX = x;
		mY = y;
	
		if (xSp > 0)
			this.mX-=mCloudWidth;
	}
	
	public boolean updatePosition(int minX, int maxX) {
		mX += mXSpeed; 
		mY += mYSpeed;
		
		if (mX + mCloudWidth < minX || mX > maxX)
			return false;
		
		return true;
	}

	public void updateSpeed(int xSpeed, int ySpeed) {
		this.mXSpeed = xSpeed;
		this.mYSpeed = ySpeed;
	}
	
	public int getCloudID() {
		return mCloudID;
	}

	@Override
	public Rect getHitBox(int offset) {
		mHitbox.set(mX - offset, mY - offset, mX + mCloudWidth + offset, mY + mCloudHeight + offset);
		
		return mHitbox;
	}

	@Override
	public void draw(Canvas canvas) {
		Rect bounds = getHitBox(0);
	    canvas.drawBitmap(mSpriteSheet, mSRectangle, bounds, null);
	}

	@Override
	public boolean update(int interval) {
		mFrameTimer+=interval;
	    if(mFrameTimer > mFPS ) {
	        mFrameTimer = 0;
	        mCurrentFrame +=1;
	 
        	if (mCurrentFrame >= mTotalFrames)
        			mCurrentFrame = 0;
        	
        	mSRectangle.top = 0;
        	mSRectangle.bottom = mCloudHeight;
    	    mSRectangle.left = mCurrentFrame * mCloudWidth;
    	    mSRectangle.right = mSRectangle.left + mCloudWidth;
	    }
	    return true;
	}
	
	public void cleanUp() {
		mSpriteSheet = null;
	}

	@Override
	void onCollision(GameObject other, boolean isArbitrator) {

	}
}

پس ما برای هر کدام از اشکال خورشید و ابر و بارش برف و شب و روز شدن کلاس داریم که برای هر کدام تصاویر بر روی صفحه به صورت x,y حرکت خواهند کرد.

برای منو و تنطظیمات از یک کلاس داخل کلاس Main تعریف شده است.

کلاس دیگری که می خواهیم در مورد آن صحبت کنیم کلاس مربوط به سرعت حرکت اشکال در صفحه است که برای هر کدام از اشکال ها یک سرعتی مشخص شده است که چه زمانی ظاهر شوند و نمایش داده شوند.

package com.balloon.dl;

import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;


/*
 * Note that this activity should be an interface; a bridge between the game and the player. The GameCanvas and GameThread
 * classes take care of the game elements while the ArcadeModeActivity merely relays input and output between the game and the
 * user.package com.balloon.dl;
 * */
public class ArcadeModeActivity extends GameActivity {

	//End of the timer code
	
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PreferencesManager.getInstance(this);
        
		game = (GameCanvas)findViewById(R.id.arcadecanvas);
		game.setOnTouchListener(mTouchEvent);
		thread = game.getThread();
        
        initializeGame();
        
        if (savedInstanceState == null) {
        	mHandler.postDelayed(mUpdateTimeTask, mInterval);
            thread.setState(GameCanvas.STATE_RUNNING);
            
        } else {
            thread.restoreState(savedInstanceState);   
            thread.togglePause(true);
        }
    }
    
    /*
     * Captures the back button press to pause the game instead of killing the activity
     * */
    public boolean onKeyDown(int keyCode, KeyEvent event)  {
        return super.onKeyDown(keyCode, event);
    }

    private void initializeGame() {
    	Utilities.resetOptionButtons(mOptionSound, mOptionColourWheel, mOptionVibrate);
		
    	DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		int width = dm.widthPixels;
		int height = dm.heightPixels;
    	//thread.setGameVariables(width, height, -1, 1000, GameCanvas.GAME_OVER_TIMEOUT);
		thread.setGameVariables(width, height, -1, 60000, GameCanvas.GAME_OVER_TIMEOUT);
    	
    	// Sets all the object managers
		BalloonManager b = new BalloonManager();
		b.setAttributes(0, width, 0, height, 2, 4, 2, 5, 13, 35, getBaseContext(), true);
		//b.setAttributes(0, width, 0, height, 3, 5, 2, 6, 15, 40, getBaseContext(), true); // Old configurations
		thread.setBalloonManager(b);

		CloudManager c = new CloudManager();
		c.setAttributes(0, width, 0, height, -1, -1, -1, -1, 4, 2, getBaseContext(), false);
		thread.setCloudManager(c);

		// Add all the events
    	SnowyEvent snow = new SnowyEvent();
    	snow.setAttributes(5000, 1, game);
    	thread.addEvent(snow);

    	SunnyEvent sun = new SunnyEvent();
    	sun.setAttributes(4000, 2, game);
    	thread.addEvent(sun);

    	MistEvent mist = new MistEvent();
    	mist.setAttributes(3500, 2, game);
    	thread.addEvent(mist);

    	HUD hud = new HUD(this, dm.density, width, height);
    	hud.setRule(HUD.RULE_SHOW_SCORE, true);
    	hud.setRule(HUD.RULE_SHOW_COMBO, true);
    	hud.setRule(HUD.RULE_SHOW_HIGHSCORE, true);
    	hud.setRule(HUD.RULE_SHOW_TIMER, true);
    	hud.setRule(HUD.RULE_SHOW_COLOUR_WHEEL, true);
    	thread.setHUD(hud);
    	
    	// Prevents the device from going to sleep mode
		game.setKeepScreenOn(true);
		
        // give the GameCanvas a means to update UI elements
        game.setActivityReference(this);
        thread.initializeGame();
    }
/*
    protected void initializeHandlers() {
    	super.initializeHandlers();
    	mHudHandler = new Handler() {
            public void handleMessage(Message m) {
    	    	((HUDForTimedGame)mHUD).updateScore(m.getData().getInt("score"));
    	    	((HUDForTimedGame)mHUD).updateCombo(m.getData().getInt("combo"));
    	    	((HUDForTimedGame)mHUD).updateHighScore(m.getData().getInt("highscore"));
    	    	((HUDForTimedGame)mHUD).updateTimer(m.getData().getInt("timer"));
            }
    	};
    }*/
}

در آخر یک خروجی از بازی :

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید