一。实现界面上的图像;

1.这是界面的布局成为这个熊样。

2.将4个相同类型的植物槽中的植物关联到同一个事件中。

@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *plantIVs;

3.将下面的45个草坪中的坑 添加uiview,然后关联到一个相同功能的数组中。

@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *boxes;

4.背景出现什么就拖出什么 ,拖出阳光的图片  阳光图片的下面托出一个lable用于显示数据。

二。拖拽植物槽里点植物:

1。以下代码是用来实现 植物槽里点植物多,从一张图片中截取出你要的图片显示在植物槽里;

-(void)initUI{

UIImage *plantsImage = [UIImageimageNamed:@"seedpackets.png"];

float w = plantsImage.size.width/18;

float h = plantsImage.size.height;

for (int i=0; i<4; i++) {

UIImageView *plantIV =self.plantIVs[i];

float x = 0;

switch (i) {

case1://豌豆射手

x= 2*w;

break;

case2://寒冰射手

x= 3*w;

break;

case3://坚果

x= 5*w;

break;

}

CGImageRef subImage = CGImageCreateWithImageInRect(plantsImage.CGImage, CGRectMake(x, 0, w, h));

plantIV.image = [UIImageimageWithCGImage:subImage];

CGImageRelease(subImage);

三。 创建一个植物类,用来显示植物了, 植物类应该继承uiimageview;

1.因为所有以后要用到多植物都是属于要有动态效果的, 所以在创建好  植物父类的时候就要对其进行一个timer方法: 然后在调用这个方法的时候要创建一个改变图片的方法

- (id)initWithFrame:(CGRect)frame

{

self = [superinitWithFrame:frame];

if (self) {

[NSTimerscheduledTimerWithTimeInterval:.1target:selfselector:@selector(changeImage) userInfo:nilrepeats:YES];

}

returnself;

}

然后在初始化此方法后要对这个方法进行实现。   , 此段代码就是实现图片的所有植物类图片的动态效果。  此方法需要在 viewdidload里面实现。

而且注意对是: 这里面用到了一个count的变量,  所以需要在.h里面进行声明

@property (nonatomic)int count;

@property (nonatomic, strong)UIImage *plantImage;

.h里面的声明代码。  而plantImage 是表示植物槽里点植物 声明的全局属性,其它子类可以继承。

-(void)changeImage{

float w = self.plantImage.size.width/8;

//    x  0w   1w  2w  3w

CGImageRef subImage = CGImageCreateWithImageInRect(self.plantImage.CGImage, CGRectMake(self.count++%8*w, 0, w, self.plantImage.size.height));

self.image = [UIImageimageWithCGImage:subImage];

CGImageRelease(subImage);

}做完这些后,也无法实现显示动态植物的原因是, 没有在viewcontroller中进行初始化的声明及使用。

四。接下来  需要创建其它的子类用来继承plant植物类,  因为现在声明了一个全局变量叫plantImage

1.声明一个子类叫做sunflower就是向日葵:  继承父类plant,然后在其自己的类当中实现自己要显示的图片。

- (id)initWithFrame:(CGRect)frame

{

self = [superinitWithFrame:frame];

if (self) {

self.plantImage = [UIImageimageNamed:@"plant_0.png"];   此段代码是这个阶段要用的!  此时需要在页面中创建一个花 需要代码进行初始化,

就是self.dragPlant =[[SunFloweralloc]initWithFrame:plantIV.frame];类似于这样的

//打开用户交互不然自身及内部子控件的事件响应不了

self.userInteractionEnabled= YES;

//让超出自身范围的子控件不显示

self.clipsToBounds = YES;

}

returnself;

}

接下来此阶段的工作酒时重复以上的工作,创建一个豌豆射手,寒冰射手,坚果类  然后继承父类 的方法:然后在其具体的方法中进行自身图片的显示。

五。第五步,接下来这部分应该实现的是具体的每个草坪的坑中, 需要托45个view   然后45个view需要将其设置成透明,alpha里面设置,用控件全选。

此阶段就需要实现鼠标的点击事件了。

-(void)touchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event{

UITouch *t = [touches anyObject];

CGPoint p = [t locationInView:self.view];

for (UIImageView *plantIV inself.plantIVs) {

if (CGRectContainsPoint(plantIV.frame, p)) {    //植物槽上的植物和p点(鼠标的点)点位置相同的话,用一个switch来创建点击不同植物槽,在当前的植物槽上创建植物。

switch (plantIV.tag) {

case0:

{

self.dragPlant = [[SunFloweralloc]initWithFrame:plantIV.frame];

}

break;

case1:

{

self.dragPlant = [[Peaalloc]initWithFrame:plantIV.frame];

}

break;

case2:

{

self.dragPlant = [[IcePeaalloc]initWithFrame:plantIV.frame];

}

break;

case3:

{

self.dragPlant = [[Nutalloc]initWithFrame:plantIV.frame];

}

break;

}

self.dragPlant.delegate = self;

[self.viewaddSubview:self.dragPlant];

}

}

}     此段代码的意思就是  当你点击植物槽里点植物时  在当前点击的植物上复制一个新的植物   每个植物槽的tag不同。

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{  鼠标移动的事件情况

UITouch *t = [touches anyObject];

CGPoint p = [t locationInView:self.view];

self.dragPlant.center = p;

-(void)touchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event{

//判断是否拖拽着植物

if (self.dragPlant) {如果拖动的是植物的话:下面的判断是遍历每个草坪上的槽;

for (UIView *box inself.boxes) {

if (CGRectContainsPoint(box.frame, self.dragPlant.center)&&box.subviews.count==0) {如果草坪上的frame和拖动植物的中心点中心点重叠多话:将植物显示到当前你拖动到的草坪槽的中心点上,    而后面加的box的count的判断是为了避免:   一个草坪槽里出现多个植物。

[box addSubview:self.dragPlant];

self.dragPlant.center = CGPointMake(box.frame.size.width/2, box.frame.size.height/2);

//开火儿

[self.dragPlantbeginFire];

}

}

//判断如果没有扔到任何一个坑里面的话就把植物删除

if ([self.dragPlant.superviewisEqual:self.view]) {

[self.dragPlantremoveFromSuperview];

}

self.dragPlant = nil;   //如果没有次方法:会出现  如果拖动一个植物后拖动到草坪槽里,  但是点击松手后,但是你鼠标移动的话也会出现植物跟着移动;

}

}

此时实现以上的方法后    会有一个小bug 因为如果遇到了意外中断的情况  是可以讲图片添加等任意位置的:  所以此时就需要实现一个意外中断的方法:

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{

if (self.dragPlant) {

[self.dragPlantremoveFromSuperview];

}

第五步完成了以后, 现在所有植物槽的植物能拖动了,,植物也能正确懂种植在草坪上,  但是现在当情况是,没有阳光,  每一个植物所对应的:如产阳光,发射子弹,等功能没有实现。所以,下一步的功能就是  实现��产出阳光。

第六步:

解决方案与需求: 因为��产出阳光 是其自身的状态属性, 但是这个 状态属性,基本上大部分的植物都存在,  所以需要声明一个父类的方法, 然后在父类的.h中声明.m中实现, 但是父类的实现的代码里不做任何代码的操作,  而是要通过子类继承重写的方式进行各自的  子类的植物的具体功能的实现,  所以需要重写。

在子类的重写方法中  因为是要动态的有规律的添加太阳, 需要调用计时器的方法:      然后selector中加入一个 添加阳光的方法:

需要注意的一点是。当你这个��扔到坑里的时候就需要调用开火这个方法,  所以还需要在view didload里面实现:

注意:  一般控件都有一个属性是用户交互, 因为当你拖动到草坪上时交互不开的花可能点不了:  原因是因为图片imageview的交互是默认关闭的,而他如果关闭了,所有在他内部的所有子控件也就变成了关闭的:  所以在这里需要写入一个方法;  这个方法是在向日葵自己的.m方法里面写的;自定义的时候。

//打开用户交互 不然自身及内部子控件的事件响应不了

self.userInteractionEnabled= YES;

//让超出自身范围的子控件不显示

self.clipsToBounds = YES;

-(void)beginFire{

[NSTimerscheduledTimerWithTimeInterval:8target:selfselector:@selector(addSun) userInfo:nilrepeats:YES];

}

-(void)addSun{

UIButton *sunBtn = [[UIButtonalloc]initWithFrame:CGRectMake(10, 25, 25, 25)];//因为阳光是按钮,需要收集,所以是按钮,

[sunBtn setImage:[UIImageimageNamed:@"sun.png"] forState:UIControlStateNormal];

[sunBtn addTarget:selfaction:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];

[selfaddSubview:sunBtn];

//阳光自己消失

[NSTimerscheduledTimerWithTimeInterval:3target:selfselector:@selector(removeSunAction:) userInfo:sunBtn repeats:NO];

}

-(void)removeSunAction:(NSTimer *)timer{

UIButton *sunBtn = timer.userInfo;

[sunBtn removeFromSuperview];

}

-(void)clicked:(UIButton *)sunBtn{阳光按钮自己的点击事件。

[sunBtn removeFromSuperview];

[self.delegateaddSunCount:25];

现在剩余一个小功能就是:没有阳光的计数。  所以要涉及到反向调用

第七步: 反向调用 给阳光的label添加修改功能。

反向传值流程:1.在B类的.h中声明一个A类型的weak属性delegate

2.在A类中创建完B类的时候给B类型对象的delegate属性赋值

3.在A类的.h中声明方法供B类调用 如果需要传递回来参数那该方法声明时需要带参数

viewcontroller是A类  ,太阳花是B类

1.现在是在sunflower中声明的, 因为方向调用要改Label的值得话 不仅仅是在这个子类当中,其他地方也要用,  所以需要声明在父类当中

2.在A类中 创建完B类的时候 也就是创建太阳花初始化方法的时候   给B类型的对象的delegate赋值。 self.dragPlant.delegate = self;

3.在A类的.h中声明方法供B调用,-(void)addSunCount:(int)count;

然后再.m里面实现以下

-(void)addSunCount:(int)count{

int oldCount = self.sunCountLabel.text.intValue;

self.sunCountLabel.text = [NSStringstringWithFormat:@"%d",oldCount+count];

剩下的工作就是只需要在点击按钮事件的时候  调用此方法就可以了  ;就是太阳花自己的点击消失的时候要计数;

-(void)clicked:(UIButton *)sunBtn{

[sunBtn removeFromSuperview];

[self.delegateaddSunCount:25];

做完这些 ,植物的大部分工作都已经做完了,剩下的工作就是添加子弹。

第八步.添加子弹

发射子弹是每隔一段事件发射, 所以在开火的方法中应该开一个timer pea的.m方法里

IOS 实现植物大战僵尸相关推荐

  1. 植物2 IOS 怎么实名认证_【植物大战僵尸2国际版最新iOS版】植物大战僵尸2国际版iOS版下载...

    植物大战僵尸2国际版iOS版下载如遇网络信号问题,可切换至WIFI网络或4G网络. 植物大战僵尸2国际版iOS版下载游戏更新: [月卡焕新 限时特惠] 潘妮时空车进行了大改造,带来了更多超棒的月卡新特 ...

  2. 植物2 IOS 怎么实名认证_植物大战僵尸2未来世界22天困难怎么过关 植物阵容推荐...

    植物大战僵尸2未来世界22天困难攻略 植物大战僵尸2未来世界22天有很多小伙伴都卡在这里,难度是一定的,那么到底要怎么过呢?下面就和小编一起去了解一下吧! 植物大战僵尸未来世界第二十二天过关条件是指挥 ...

  3. 植物大战僵尸2 服务器维护时间,植物大战僵尸2PVP商店多久更新一次

    植物大战僵尸2PVP商店多久更新一次以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 植物大战僵尸2PVP商店多久更新一次 ...

  4. 植物大战僵尸android版手机版,植物大战僵尸95版手机版

    植物大战僵尸95版是近期非常不错的一款经典怀旧休闲系列游戏,游戏中玩家能体验到非常不错的植物大战僵尸策略世界的完美乐趣,多种不同的趣味游戏内容,经典的休闲游戏时光,给你带来最新的冒险之旅,相信不少的用 ...

  5. 女友让我破解植物大战僵尸!我干脆撸了一款一样的....翻身舔狗把歌唱呀

    今天给大家分享的开源项目可以说非常适合入门,还比较好玩,更是一个有故事的项目.既能满足想学习的读者,又能满足那些喜欢八卦的读者. 提到植物大战僵尸相信大部分读者都不陌生,可以说是塔防类游戏的鼻祖.就鸟 ...

  6. 【植物大战僵尸2】算法 笔记

    文章目录 春日活动--旅行原木--特殊事件--植物挑战_超能花菜 春日活动--暖春植树--初春挑战 地图解锁顺序建议 花园战争 超z联赛 无尽挑战 无尽常用植物及装扮 植物排名 春日活动–旅行原木–特 ...

  7. pvz安卓服务器维修礼包码,植物大战僵尸2礼包兑换码大全2020最新版

    植物大战僵尸2礼包码2020最新版是一款能够让玩家体验烧脑塔防大战的放置游戏,拥有经典的游戏规则设计,带来的玩法也会让每个玩家体验最为精彩的体验,每个僵尸都有着自己的特性,游戏之中的每一种植物都有自己 ...

  8. [日记]游长白遇梅花,植物大战僵尸

    "旅客朋友们--"我因为坐在面包车副驾驶的位置,所以假装自己是导游,"您即将经过的景点是'董眼镜修车铺',请向车窗的左侧观看--" 董眼镜修车铺 "董 ...

  9. 基于python开发植物大战僵尸

    目录 摘要 2 一, 引言 3 1.1中国游戏产业的现状 3 1.2中国游戏产业的未来发展局势 4 1.3植物大战僵尸游戏的发展状况 4 二.系统结构 5 2.1 Python3.8.2 IDLE 简 ...

最新文章

  1. 毕业五年,几个月入百万阿里系大神的公众号!
  2. 不投降就是成功 --- 我看《新喜剧之王》
  3. BAPI:BAPI_CONTRACT_CREATE(内部合同创建)
  4. Linux vi 命令使用说明
  5. mybatis-generator 插件扩展,生成支持多种数据库的分页功能
  6. es6与java的相似度_计算字符串的相似度-两种解法
  7. 配置单臂路由、三层交换技术以及动态路由
  8. 【简便解法】1090 危险品装箱 (25分)_33行代码AC
  9. linux7 共享盘创建,使用CentOS7建立samba文件共享服务器
  10. 广东2021高考成绩位次查询,广东一分一段表查询2021-广东省2021年一分一段统计表...
  11. 送你一个Python 数据排序的好方法
  12. Web Server 和 HTTP 协议
  13. 响应式布局及bootstrap(实例)
  14. 表格闪退怎么解决_Excel中出现表格打开闪退的处理技巧
  15. 电磁阀、电磁铁的工作原理说明
  16. Spring Cloud Netflix框架最基础的五大组件介绍
  17. 锁存器—74HC573D
  18. 彻底解决2440触摸屏跳点以及抖动问题
  19. 如何建立一个网站?规划、设计、目的、原则、宣传(三)
  20. MySQL 计算两个日期/时间之间相差的天数、分钟数、秒数...

热门文章

  1. 2018年互联网公司市值排名
  2. 实时时钟模块RX-8010SJ
  3. 计算机主板电池没电的状态,电脑主板电池没电引起的故障检查修理_提示CMOS电池电量不足怎么办...
  4. EditPlus 5.0.651 中文版
  5. 图表生成pdf,出坑经历
  6. 运放放大倍数计算公式_运算放大器基础1——用作比较器
  7. 锁存器Latch和触发器Flip-flop的区别
  8. 使用echartJs展示报表广东省地图+柱状图
  9. UPDATE和DELETE
  10. 光剑读书思想录 2014.5.7