热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

实现割绳子游戏(来源网络)

转载网址:http:www.open-open.comlibviewopen1326597582452.html参考资料:http:www.cocos2d-ip




转载网址:http://www.open-open.com/lib/view/open1326597582452.html





参考资料:http://www.cocos2d-iphone.org/forum/topic/10411


这是我改写的一则绳子,绳子以body小节相连接


不过我还是觉得 verlet rope那种原型方式更加漂亮!


原型的缺点就是绳子一旦被切断,就要即刻清除所有相关内容,


一根绳子被切断后就这么凭空消失了,这总让人觉得有点儿说不过去吧?


于是我便想以body的形式改写一则更有质感的绳子,


这样的话,即使在被切断了之后,两段“绳子尸体”依然还能飘来荡去~


 


学到了不少新的东西,例如CCSpriteBatchNode的正确使用方法~


以前我也用 CCSpriteBatchNode,但是用的方法不正确


 


我现在是这么认识的,CCSpriteBatchNode加载一份图片文件,


其他的CCSprite都可以来使用这份图片,直接从内存里面取的,迅速快捷~


如果一份图片反复要在游戏里面用到,但是每次都通过 [CCSprite spriteWithFile:@"123.png"]的方式来取的话


就会存在每次都要从磁盘介质里面拿取这份图片,而读磁盘是很耗时间的,不管怎么说,一定比从内存读取慢!


 


其实很多时候都要权衡利弊,从内存里面读取资源文件虽快,但是ios设备内存吃紧


将整个游戏几十兆的资源文件一次性全部加载到内存,程序很有可能会被强干掉


上次我查了一番加密资源文件的手法,有一种方式是将资源文件“打碎成”字节数据放在头文件里面


后来我一想,游戏一运行,那么装载头文件里面的资源文件肯定在第一时间就会被全部加载到内存


快是够快了,内存够不够用却又成问题了~


后来我留言给作者,作者的回复也是如同我所想,此种加密方式仅限于一些必须要保密的资源,


如防止别人篡改公司logo,就可能将logo图片置于头文件中~


 


last,绳子其实还很有待挖掘,今后有时间的话,一定会力争写出更真实,更高效的绳子来~


 


//


//  BYRope.h


//  GoldMine0.6


//


//  Created by Bruce Yang on 12-1-13.


//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.


//



#import


#import"cocos2d.h"


#import"Box2D.h"


#import



#define PTM_RATIO32



// 绳子小段图片的高度和宽度~


#define ROPE_ITEM_WIDTH16.0f


#define ROPE_ITEM_HEIGHT4.0f



// 绳子 bar 图片的高度和宽度~


#define ROPE_BAR_DIAMETER8.0f



// 1.是否在绳子的两个连接点之间启用 距离限定关节~


#define B2_ROPE_JOINT_ENABLED NO



// 2.bar body到底是连接在绳子最外侧小节的 body 上,还是连接在 comp 元素的 body ~


#define CONNECTED_WITH_COMP_BODY0  // 紧随comp


#define CONNECTED_WITH_ROPE_BODY1  // 紧随绳子最外侧小节(因为会随着绳子抖动,所以效果感觉不怎么样)~


#define ROPE_BAR_CONNECT_MODE0



/**


 * added by BruceYang on 2012.01.15.06.22


 *  Box2D b2Math.h 做功能扩充(c语言 运算符重载的用法)~


 * 之所以放在该类里面而不直接去 box2d源码里面修改,主要还是为了升级 box2d 库的时候不出现方法丢失的问题~


 * 可想而知,如果这些代码是插进 box2d源码里面的话,升级的时候一个替换,这些我自己新添加的东西肯定就要丢失了~


 */


inline b2Vec2 operator * (const b2Vec2& a, float32 s) {


return b2Vec2(s * a.x, s * a.y);


}


inline b2Vec2 operator / (const b2Vec2& a, float32 s) {


return b2Vec2(a.x / s, a.y / s);


}


inline float32 b2Vec2ToAngle(const b2Vec2& v) {


return atan2f(v.y, v.x);


}



@interface BYRope :NSObject {


    // ~


}



/**


 * p1为在 body1 fxitures 内部的一个世界坐标点~


 * p2为在 body2 fxitures 内部的一个世界坐标点~


 * itemBatch装载绳子小节图片


 * barBatch 装载绳子端点圆形小图片(若传入参数nil,则绳子两端不包含圆形小图片)~


 */


-(id) init:(b2Body*)body1 


    point1:(b2Vec2)p1 


     body2:(b2Body*)body2 


    point2:(b2Vec2)p2 


 itemBatch:(CCSpriteBatchNode*)itemBatch 


  barBatch:(CCSpriteBatchNode*)barBatch;



-(void) dealloc;



@end








 


 


//


//  BYRope.mm


//  GoldMine0.6


//


//  Created by Bruce Yang on 12-1-13.


//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.


//



#import"BYRope.h"



@implementation BYRope



-(id) init:(b2Body*)body1 


    point1:(b2Vec2)p1 


     body2:(b2Body*)body2 


    point2:(b2Vec2)p2 


 itemBatch:(CCSpriteBatchNode*)itemBatch 


  barBatch:(CCSpriteBatchNode*)barBatch 


{


if((self = [super init])) {


        // world完全没必要用一个参数传进来,直接从 body 里面取出来就是了~


        b2World *world = body1->GetWorld();


        vector<b2Vec2> vPoints;


        


       // 计算两点之间的距离~


        float distance = b2Distance(p1, p2);


        


        //定义绳子的 “每段平均长度:长度越短,段数越多;长度越长,段数越少~


        float segmentLength = ROPE_ITEM_WIDTH /PTM_RATIO;


        int pointsCount = distance / segmentLength + 1;


        


       // 两点间的矢量差~


        b2Vec2 diffVector = p2 - p1;


       // 求出单位向量~


        diffVector.Normalize();


        


        float multiplier = distance / (pointsCount - 1);


        for(int i = 0; i


            b2Vec2 vector = p1 + multiplier * i * diffVector;


            vPoints.push_back(vector);


        }


        


        b2Body *prevBody = body1;


        b2BodyDef bodyDef;


        b2Body* body;


        b2Fixture* fixture;


       b2RevoluteJointDef jd;


        


        b2Body *firstBd, *lastBd;


        for(int i = 0; i 1; ++ i) {


            b2Vec2 p1_ = vPoints.at(i);


            b2Vec2 p2_ = vPoints.at(i+1);


            b2Vec2 stickVector = p1_ - p2_;


            float stickAngle = b2Vec2ToAngle(stickVector);


            


            b2Vec2 midPoint = (p1_ + p2_) / 2.0f;


            


            bodyDef.type =b2_dynamicBody;


            body = world->CreateBody(&bodyDef);


            


            //如果是绳子的第一个或最后一个关节,则不可以被切割~


            if(i == 0) {


                firstBd = body;


                body->m_isCuttable =false;


            }


            


            b2PolygonShape boxShape;


            boxShape.SetAsBox(multiplier/2.0f,ROPE_ITEM_HEIGHT/PTM_RATIO/2.0f);


            fixture = body->CreateFixture(&boxShape,1.0f);


            


           // 设置绳子单元不响应碰撞~


            fixture->SetSensor(true);


            body->SetTransform(b2Vec2(midPoint.x, midPoint.y), stickAngle);


            


            /**


             * 如果将下面这块代码放到上面那块代码的前面,会出现很奇葩的现象:


             * 所预期的绳子关节不会建立起来,绳子小段会到处乱飞,sprite图片也会一个个从场景中消失不见~


             *猜测原因可能是因为 body 创建出来的时候 position 还没有确定下来!!


             */


            jd.collideConnected =false;


            b2Vec2 anchor(p1_.x, p1_.y);


            jd.Initialize(prevBody, body, anchor);


            world->CreateJoint(&jd);


            prevBody = body;


            


            if(i == pointsCount-2) {


                lastBd = body;


                body->m_isCuttable =false;


                jd.collideConnected =false;


                b2Vec2 lastAnchor(p2_.x, p2_.y);


                jd.Initialize(body, body2, lastAnchor);


                world->CreateJoint(&jd);


            }


            


            CGRect spriteRect = CGRectMake(0,0, multiplier*PTM_RATIO,ROPE_ITEM_HEIGHT);


CCSprite *itemSprite = [CCSprite spriteWithBatchNode:itemBatch rect:spriteRect];


            


ccTexParams params = {GL_LINEARGL_LINEAR,GL_REPEATGL_REPEAT };


[itemSprite.texture setTexParameters:¶ms];


            


[itemSpritesetPosition:ccp(midPoint.x*PTM_RATIO, midPoint.y*PTM_RATIO)];


[itemSpritesetRotation:-1 *CC_RADIANS_TO_DEGREES(stickAngle)];


[itemBatchaddChild:itemSprite];


            body->SetUserData(itemSprite);


        }


        


        //创建绳子关节,限定两物体之间的最大距离(解决了绳子与被连接物体碰撞的问题,这个绳子关节便没必要创建了)~


       if(B2_ROPE_JOINT_ENABLED ==YES) {


            b2RopeJointDef rjd;


            rjd.bodyA = body1;


            rjd.bodyB = body2;


            rjd.localAnchorA = p1-body1->GetPosition();


            rjd.localAnchorB = p2-body2->GetPosition();


            rjd.maxLength = (p2 - p1).Length();


            world->CreateJoint(&rjd);


        }


        


       // 添加绳子端点的图片~


        if(barBatch != nil) {


           // 1.创建绳子端点上的body(给绳子 bar依附用)~


            b2BodyDef bd;


            bd.type =b2_dynamicBody;


bd.position.Set(p1.x, p1.y);


            b2Body *b1 = world->CreateBody(&bd); // p1 点的 body~


bd.position.Set(p2.x, p2.y);


            b2Body *b2 = world->CreateBody(&bd); // p2 点的 body~


            


           // 2.将端点 body 连接到绳子最外侧的两个绳子小节~


           b2RevoluteJointDef jd;


            jd.collideConnected =false;


           if(ROPE_BAR_CONNECT_MODE ==CONNECTED_WITH_COMP_BODY) {


                jd.Initialize(b1, body1, p1);


                world->CreateJoint(&jd);


                jd.Initialize(b2, body2, p2);


            }else if(ROPE_BAR_CONNECT_MODE ==CONNECTED_WITH_ROPE_BODY) {


                jd.Initialize(b1, firstBd, p1);


                world->CreateJoint(&jd);


                jd.Initialize(b2, lastBd, p2);


            }



            world->CreateJoint(&jd);


            


           // 3.创建绳子 bar sprite~


            CCTexture2D *tex2d = barBatch.textureAtlas.texture;


           CGRect barRect =CGRectMake(0,0ROPE_BAR_DIAMETER,ROPE_BAR_DIAMETER);


            CCSprite *spriteA = [CCSprite spriteWithTexture:tex2d rect:barRect];


            [spriteAsetPosition:ccp(p1.x*PTM_RATIO, p1.y*PTM_RATIO)];


            [barBatchaddChild:spriteA];


            b1->SetUserData(spriteA);


            CCSprite *spriteB = [CCSprite spriteWithTexture:tex2d rect:barRect];


            [spriteBsetPosition:ccp(p2.x*PTM_RATIO, p2.y*PTM_RATIO)];


            [barBatchaddChild:spriteB];


            b2->SetUserData(spriteB);


        }


}


return self;


}




-(void)dealloc{


    [super dealloc];


}



@end








推荐阅读
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
author-avatar
linxiuying261
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有