iOS MonsterBall(怪物舞會)~demo

//聯系人:石虎QQ: 1224614774昵稱:嗡嘛呢叭咪哄

/**

注意點: 1.看 GIF 效果圖.

2.看連線視圖的效果圖.

3.看實現代碼(直接復制實現效果).

4.需要真機設備 才有效果 ...

5.關于 ?"gate" "ball1" "monster_move_1" "grass" ?分別是加載的圖片

*/

一、GIF 效果圖:

二、連線視圖的效果圖:

圖1:

圖2:

圖3:

三、實現代碼:

=========================

===================================================

==========================

控制器1:SHBallView.h

//

//? SHBallView.h

//? MonsterBall(怪物舞會)~demo

//

//? Created by石虎on 2017/8/14.

//? Copyright ? 2017年shihu. All rights reserved.

//

#import

#import

@interfaceSHBallView :UIView

//定義屬性來記錄足球的當前位置

@property(nonatomic,assign)CGPointcurrentPoint;

@property(nonatomic,assign)CMAccelerationacceleration;

//定義屬性來記錄足球滾動的X、Y軸方向的速度

@property(nonatomic,assign)CGFloatxVelocity;

@property(nonatomic,assign)CGFloatyVelocity;

- (void)update;

@end

控制器1:SHBallView.m

//

//? SHBallView.m

//? MonsterBall(怪物舞會)~demo

//

//? Created by石虎on 2017/8/14.

//? Copyright ? 2017年shihu. All rights reserved.

//

#import"SHBallView.h"

#define BALL_SIZE24

//定義怪物的數量

#define MONSTER_NUM3

//定義球門的起始位置

#define GATE_ORIGIN_X85

//定義球門的寬度

#define GATE_WIDTH150

@interfaceSHBallView()

{

NSArray* ballImages;

NSArray* monsterImages;

UIImage* gateImage;

//定義變量記錄足球動畫幀的索引

NSIntegerballIndex , count;

//定義變量記錄每個怪物當前顯示的動畫幀的索引

NSIntegermonsterImageIndexs[MONSTER_NUM];

//定義數組來記錄每個怪物的位置

CGPointmonsterPoints[MONSTER_NUM];

NSTimer* timer;

BOOLisPlaying;//定義變量記錄游戲的狀態

}

@end

@implementationSHBallView

- (id)initWithCoder:(NSCoder*)aDecoder

{

self= [superinitWithCoder:aDecoder];

if(self) {

//加載球門圖片

gateImage= [UIImageimageNamed:@"gate"];

//加載足球滾動的每一幀的圖片

ballImages= [NSArrayarrayWithObjects:

[UIImageimageNamed:@"ball1"],

[UIImageimageNamed:@"ball2"],

[UIImageimageNamed:@"ball3"],

[UIImageimageNamed:@"ball4"],

[UIImageimageNamed:@"ball5"],

[UIImageimageNamed:@"ball6"],

[UIImageimageNamed:@"ball7"],

[UIImageimageNamed:@"ball8"],nil];

//加載怪物走動的每一幀的圖片

monsterImages= [NSArrayarrayWithObjects:

[UIImageimageNamed:@"monster_move_1"],

[UIImageimageNamed:@"monster_move_2"],

[UIImageimageNamed:@"monster_move_3"],

[UIImageimageNamed:@"monster_move_4"],nil];

monsterImageIndexs[1] =1;

monsterImageIndexs[2] =2;

[selfstartGame];//開始游戲

}

returnself;

}

- (void) moveMonster

{

for(inti =0; i

{

//控制怪物動畫顯示下一幀的圖片

monsterImageIndexs[i] =monsterImageIndexs[i] +1;

//改變第i個怪物的X坐標

monsterPoints[i].x=monsterPoints[i].x+arc4random() %9-4;

}

[selfsetNeedsDisplay];

}

- (void)drawRect:(CGRect)rect

{

//繪制足球

[ballImages[ballIndex++ %8]drawAtPoint:self.currentPoint];

//繪制球門

[gateImagedrawAtPoint:CGPointMake(GATE_ORIGIN_X,64)];

//采用循環繪制3個怪物

for(inti =0; i

{

[monsterImages[monsterImageIndexs[i] %4]drawAtPoint:monsterPoints[i]];

}

}

//重寫實現currentPoint屬性的setter方法

- (void)setCurrentPoint:(CGPoint)newPoint

{

//如果正在游戲中,且足球新的位置點與原來的位置點不位于同一個點。

if(isPlaying&& (fabs(_currentPoint.x- newPoint.x) >1

||fabs(_currentPoint.y- newPoint.y) >1))

{

_currentPoint= newPoint;

//如果足球當前的X坐標小于0,就足球已經位于最左邊

if(_currentPoint.x<0)

{

//將足球設置在最左邊,并將水平速度設為0

_currentPoint.x=0;

self.xVelocity=0;

}

//球已經到了底線,且沒進球門

if(_currentPoint.y<75&& (_currentPoint.x

||_currentPoint.x>GATE_ORIGIN_X+GATE_WIDTH-4))

{

//將足球設置在底線上,并將垂直速度設為0

_currentPoint.y=75;

self.yVelocity=0;

}

//球進了球門

if(_currentPoint.y<75&& (_currentPoint.x>=GATE_ORIGIN_X+2

||_currentPoint.x<=GATE_ORIGIN_X+GATE_WIDTH-4))

{

//使用UIAlertView提示用戶游戲結束,并詢問用戶是否要開始下一盤游戲

[[[UIAlertViewalloc]initWithTitle:@"游戲結束"

message:@"您進球了,再來一盤?"delegate:self

cancelButtonTitle:@"好"otherButtonTitles:nil]show];

//取消計時器

[timerinvalidate];

isPlaying=NO;

}

//如果足球的X坐標大于該控件的高度,表明足球已經到了屏幕最下方

if(_currentPoint.x>self.bounds.size.width-BALL_SIZE)

{

//將足球設置到屏幕最下方,并將垂直速度設為0

_currentPoint.x=self.bounds.size.width-BALL_SIZE;

self.xVelocity=0;

}

//如果足球的Y坐標大于該控件的寬度,表明足球已經到了屏幕最右邊

if(_currentPoint.y>self.bounds.size.height-BALL_SIZE)

{

//將足球設置到屏幕最右邊,并將水平速度設為0

_currentPoint.y=self.bounds.size.height-BALL_SIZE;

self.yVelocity=0;

}

//遍歷每個怪物,檢測怪物與足球是否碰撞

for(inti =0; i

{

//如果怪物所在矩形和足球所在矩形有交集,表明二者相撞

if(CGRectIntersectsRect([selfgetBallRect], [selfgetMonsterRect:i]))

{

//怪物將足球快速向下踢出,也就是足球的Y方向上速度增加0.6

self.yVelocity=self.yVelocity+0.6;

}

}

[selfsetNeedsDisplay];

}

}

- (void)update

{

staticNSDate*lastUpdateTime;

//如果初始化過lastUpdateTime變量

if(lastUpdateTime !=nil)

{

//計算上次到現在的時間差

NSTimeIntervalsecondsSinceLastDraw =

-([lastUpdateTimetimeIntervalSinceNow]);

//根據加速度數據計算足球在X方向、Y方向的速度

self.yVelocity=self.yVelocity+ -(self.acceleration.y*

secondsSinceLastDraw);

self.xVelocity=self.xVelocity+self.acceleration.x*

secondsSinceLastDraw;

//根據足球的速度計算足球在單位時間內滾動的距離。

//由于實際算出來的滾動距離太小,因此都需要乘以500(實際上可用400、600等)

CGFloatxDelta = secondsSinceLastDraw *self.xVelocity*500;

CGFloatyDelta = secondsSinceLastDraw *self.yVelocity*500;

//設置足球的位置為新計算出來的位置

self.currentPoint=CGPointMake(self.currentPoint.x+ xDelta,

self.currentPoint.y+ yDelta);

}

lastUpdateTime = [[NSDatealloc]init];

}

//獲取怪物所在的矩形框

- (CGRect) getMonsterRect:(NSInteger) monsterIndex

{

CGRectrect;

//獲取索引為monsterIndex的怪物的左上角坐標

rect.origin=monsterPoints[monsterIndex];

//獲取圖片的大小

rect.size= ((UIImage*)monsterImages[0]).size;

returnrect;

}

//獲取足球所在的矩形框

- (CGRect) getBallRect

{

CGRectrect;

rect.origin=self.currentPoint;

rect.size= ((UIImage*)ballImages[0]).size;

returnrect;

}

- (void) resetGame

{

//依次設置每個怪物的位置

monsterPoints[0] =CGPointMake(20,150);

monsterPoints[1] =CGPointMake(190,150);

monsterPoints[2] =CGPointMake(80,280);

//設置足球開始的位置,位于該UIView的中心

self.currentPoint=CGPointMake((self.bounds.size.width-BALL_SIZE) /2.0f,

(self.bounds.size.height-BALL_SIZE) /2.0f);

//設置足球的開始速度

self.xVelocity=0.0f;

self.yVelocity=0.0f;

}

//當用戶單擊UIAlertView警告框上按鈕時激發該方法

- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:

(NSInteger)buttonIndex

{

//如果用戶單擊第一個按鈕

if(buttonIndex ==0)

{

[selfstartGame];//重新開始游戲

}

}

- (void) startGame

{

//設置游戲狀態:正在游戲

isPlaying=YES;

//重設足球和怪物的位置

[selfresetGame];

//使用定時器控制怪物的動作

timer= [NSTimerscheduledTimerWithTimeInterval:0.2target:self

selector:@selector(moveMonster)userInfo:nilrepeats:YES];

}

@end

=========================

===================================================

控制器2:ViewController.m

//

//? ViewController.m

//? MonsterBall(怪物舞會)~demo

//

//? Created by石虎on 2017/8/14.

//? Copyright ? 2017年shihu. All rights reserved.

//

#import"ViewController.h"

#import

#import"SHBallView.h"

@interfaceViewController()

//運動管理器

@property(strong,nonatomic)CMMotionManager*motionManager;

@property(weak,nonatomic)SHBallView*ballView;

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

//創建以grass.png圖片平鋪的顏色

UIColor* bgColor = [UIColorcolorWithPatternImage:

[UIImageimageNamed:@"grass"]];

//將該視圖控制器管理的View控件轉換為SHBallView

self.ballView= (SHBallView*)self.view;

//將背景設為以grass.png圖片平鋪的顏色

self.ballView.backgroundColor= bgColor;

//創建CMMotionManager對象

self.motionManager= [[CMMotionManageralloc]init];

NSOperationQueue* queue = [[NSOperationQueuealloc]init];

//設置CMMotionManager獲取加速度數據的頻率

self.motionManager.accelerometerUpdateInterval=0.05;

//使用代碼塊獲取加速度數據

[self.motionManagerstartAccelerometerUpdatesToQueue:queuewithHandler:

^(CMAccelerometerData*accelerometerData,NSError*error)

{

//將獲取得到的加速度數據傳給FKBallView對象

self.ballView.acceleration= accelerometerData.acceleration;

//在主線程中調用FKBallView對象的update方法

[self.ballViewperformSelectorOnMainThread:@selector(update)

withObject:nilwaitUntilDone:NO];

}];

}

@end

=========================

===================================================

謝謝!!!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容