IOS 实现植物大战僵尸
一。实现界面上的图像;
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 实现植物大战僵尸相关推荐
- 植物2 IOS 怎么实名认证_【植物大战僵尸2国际版最新iOS版】植物大战僵尸2国际版iOS版下载...
植物大战僵尸2国际版iOS版下载如遇网络信号问题,可切换至WIFI网络或4G网络. 植物大战僵尸2国际版iOS版下载游戏更新: [月卡焕新 限时特惠] 潘妮时空车进行了大改造,带来了更多超棒的月卡新特 ...
- 植物2 IOS 怎么实名认证_植物大战僵尸2未来世界22天困难怎么过关 植物阵容推荐...
植物大战僵尸2未来世界22天困难攻略 植物大战僵尸2未来世界22天有很多小伙伴都卡在这里,难度是一定的,那么到底要怎么过呢?下面就和小编一起去了解一下吧! 植物大战僵尸未来世界第二十二天过关条件是指挥 ...
- 植物大战僵尸2 服务器维护时间,植物大战僵尸2PVP商店多久更新一次
植物大战僵尸2PVP商店多久更新一次以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 植物大战僵尸2PVP商店多久更新一次 ...
- 植物大战僵尸android版手机版,植物大战僵尸95版手机版
植物大战僵尸95版是近期非常不错的一款经典怀旧休闲系列游戏,游戏中玩家能体验到非常不错的植物大战僵尸策略世界的完美乐趣,多种不同的趣味游戏内容,经典的休闲游戏时光,给你带来最新的冒险之旅,相信不少的用 ...
- 女友让我破解植物大战僵尸!我干脆撸了一款一样的....翻身舔狗把歌唱呀
今天给大家分享的开源项目可以说非常适合入门,还比较好玩,更是一个有故事的项目.既能满足想学习的读者,又能满足那些喜欢八卦的读者. 提到植物大战僵尸相信大部分读者都不陌生,可以说是塔防类游戏的鼻祖.就鸟 ...
- 【植物大战僵尸2】算法 笔记
文章目录 春日活动--旅行原木--特殊事件--植物挑战_超能花菜 春日活动--暖春植树--初春挑战 地图解锁顺序建议 花园战争 超z联赛 无尽挑战 无尽常用植物及装扮 植物排名 春日活动–旅行原木–特 ...
- pvz安卓服务器维修礼包码,植物大战僵尸2礼包兑换码大全2020最新版
植物大战僵尸2礼包码2020最新版是一款能够让玩家体验烧脑塔防大战的放置游戏,拥有经典的游戏规则设计,带来的玩法也会让每个玩家体验最为精彩的体验,每个僵尸都有着自己的特性,游戏之中的每一种植物都有自己 ...
- [日记]游长白遇梅花,植物大战僵尸
"旅客朋友们--"我因为坐在面包车副驾驶的位置,所以假装自己是导游,"您即将经过的景点是'董眼镜修车铺',请向车窗的左侧观看--" 董眼镜修车铺 "董 ...
- 基于python开发植物大战僵尸
目录 摘要 2 一, 引言 3 1.1中国游戏产业的现状 3 1.2中国游戏产业的未来发展局势 4 1.3植物大战僵尸游戏的发展状况 4 二.系统结构 5 2.1 Python3.8.2 IDLE 简 ...
最新文章
- 毕业五年,几个月入百万阿里系大神的公众号!
- 不投降就是成功 --- 我看《新喜剧之王》
- BAPI:BAPI_CONTRACT_CREATE(内部合同创建)
- Linux vi 命令使用说明
- mybatis-generator 插件扩展,生成支持多种数据库的分页功能
- es6与java的相似度_计算字符串的相似度-两种解法
- 配置单臂路由、三层交换技术以及动态路由
- 【简便解法】1090 危险品装箱 (25分)_33行代码AC
- linux7 共享盘创建,使用CentOS7建立samba文件共享服务器
- 广东2021高考成绩位次查询,广东一分一段表查询2021-广东省2021年一分一段统计表...
- 送你一个Python 数据排序的好方法
- Web Server 和 HTTP 协议
- 响应式布局及bootstrap(实例)
- 表格闪退怎么解决_Excel中出现表格打开闪退的处理技巧
- 电磁阀、电磁铁的工作原理说明
- Spring Cloud Netflix框架最基础的五大组件介绍
- 锁存器—74HC573D
- 彻底解决2440触摸屏跳点以及抖动问题
- 如何建立一个网站?规划、设计、目的、原则、宣传(三)
- MySQL 计算两个日期/时间之间相差的天数、分钟数、秒数...
热门文章
- 2018年互联网公司市值排名
- 实时时钟模块RX-8010SJ
- 计算机主板电池没电的状态,电脑主板电池没电引起的故障检查修理_提示CMOS电池电量不足怎么办...
- EditPlus 5.0.651 中文版
- 图表生成pdf,出坑经历
- 运放放大倍数计算公式_运算放大器基础1——用作比较器
- 锁存器Latch和触发器Flip-flop的区别
- 使用echartJs展示报表广东省地图+柱状图
- UPDATE和DELETE
- 光剑读书思想录 2014.5.7