iOS MonsterBall(怪物舞会)~demo

//联系人:石虎QQ: 1224614774昵称:嗡嘛呢叭咪哄

/**

注意点: 1.看 GIF 效果图.

2.看连线视图的效果图.

3.看实现代码(直接复制实现效果).

4.需要真机设备 才有效果 ...

5.关于  "gate" "ball1" "monster_move_1" "grass"  分别是加载的图片

*/

一、GIF 效果图:

二、连线视图的效果图:

图1:

iOS MonsterBall(怪物舞会)~demo_第1张图片

图2:

iOS MonsterBall(怪物舞会)~demo_第2张图片

图3:

iOS MonsterBall(怪物舞会)~demo_第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

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

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

谢谢!!!

你可能感兴趣的:(iOS MonsterBall(怪物舞会)~demo)