//聯系人:石虎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
=========================
===================================================
謝謝!!!