当前位置:  编程技术>移动开发
本页文章导读:
    ▪UIScrollView的应用大全        UIScrollView的使用大全 UIScrollView 原理详解      UIScrollView为了显示多于一个屏幕的内容或者超过你能放在内存中的内容。            可以看出,ContentOffset内容中的那个点不是从conte.........
    ▪ win8开发(11)——共享目标志例        win8开发(11)——共享目标示例上一篇文章中,我们吹了一下共享数据的问题,后面还简单弄了一个例子,本文我们再做一个综合 一些的例子,咱们做一个全能共享目标,该目标应用可以接.........
    ▪ Box2d源码学习<5>b2Timer、b2Draw和b2Settings的实现       Box2d源码学习<五>b2Timer、b2Draw和b2Settings的实现本系列博客是由扭曲45原创,欢迎转载,转载时注明出处,http://blog.csdn.net/cg0206/article/details/8280463 今天我们要说在公共模块剩下的三个小模.........

[1]UIScrollView的应用大全
    来源: 互联网  发布时间: 2014-02-18
UIScrollView的使用大全
UIScrollView 原理详解

ScrollView

       UIScrollView

     UIScrollView为了显示多于一个屏幕的内容或者超过你能放在内存中的内容。

                 Scroll View为你处理缩小放大手势,UIScrollView实现了这些手势,并且替你处理对于它们的探测和回应。其中需要注意的子类是UITableView以及UITextView(用来显示大量的文字)。还有一个UIWebView,尽管那不是UIScrollView的直接子类,它适用UIScrollView去显示网页内容

        contentsize是内容的宽和高,contentsize.width是内容的宽度,contentsize.heght是高度,contentsize是UIScrollView的一个属性,它是一个CGSize,是由核心图形所定义的架构,那定义了你可以滚轴内容的宽度和高度,你也可以添加可以上下滚动的额外区域。第一种方法是你可以通过添加内容的大小来完成。另外一个比较动态的选择是UIScrollView的另一个属性contentInset,contentInset增加你在contentsize中指定的内容能够滚动的上下左右区域数量contentInset.top以及contentInset.buttom分别表示上面和下面的距离。

           在滚轴视图中,有一个叫做ContentOffset的属性跟踪UIScrollView的具体位置,你能够自己获取和设置它,ContentOffset是你当前可视内容在滚轴视图边界的左上角那个点。如图:


           可以看出,ContentOffset内容中的那个点不是从contentInset的左上角开始的,而是内容的左上角,此时的ContentOffset是正值,但有时也是负值,如下图所示:


使用一个ScrollView

     创建一个UIScrollView

             CGRectframe = CGRectMake( 0, 0, 200, 200);

              scrollView= [[UIScrollView alloc] initWithFrame: frame];

    添加子视图(框架可以超过scroll view的边界)

            frame= CGRectMake( 0, 0, 500, 500);

            myImageView= [[UIImageView alloc] initWithFrame: frame];

           [scrollViewaddSubview:myImageView];

    设置内容尺寸

           scrollView.contentSize= CGSize(500,500);


扩展Scroll View 的行为

      应用程序通常需要知道有关的滚图的事件

            scrolloffset改变的时候

           拖动开始和结束

            减速的开始和结束


通过子类化扩展Scroll View 的行为

        创建一个子类

        重写一些功能并改变行为

        关于这种方式的争议

               应用程序的逻辑和行为变成了视图本身的一部分,就像,你可能有一些定制的滚轴逻辑,,在那你只在意一个视图控制,但你想在不同地方重复使用你的滚轴视图,如果你必须为每个都子类化,你最后会有很多不同的滚轴视图子类以及在视图中的特定应用逻辑。

              编写很多子类是很沉闷的事情,你最后会有很多无法重复使用的单独视图,而MVC的视图部分的一个重点是视图是可以在不同的控制器和不同的模式之中重复使用的,如果我们把所有逻辑都放在视图中,它减少了可复用性。

              你的代码变得很牢固地配对在一起,它实际上变成了超类的一部分,你无法从UIScrollView中析取它,之后用其它东西代替,如果它在你控制器中且为控制器的一部分,在之后更容易改变它工作的方式和重新安排你应用程序的一些部分。


通过委派来扩展Scroll View 的行为(常用的)

         委派是一个单独的对象,协议,定义了委派会实现的一系列功能的Objective-C协议,它创建了一系列很清晰的撤销点,在那里你能定制行为和外观。它在这些对象之间保持了松散的配对,视图本身与视图控制器或任何其它的控制器对象,委派不是滚轴视图的直接子类,它比起牢固配对的子类更加的松散。




首先引用别人分析一篇不错的文章,同时也感谢这位朋友的分享:http://www.cocoachina.com/iphonedev/sdk/2010/1224/2503.html   

  在滚动过程当中,其实是在修改原点坐标。当手指触摸后, scroll view会暂时拦截触摸事件,使用一个计时器。假如在计时器到点后没有发生手指移动事件,那么 scroll view 发送 tracking events 到被点击的 subview。假如在计时器到点前发生了移动事件,那么 scroll view 取消 tracking 自己发生滚动。

    子类可以重载

touchesShouldBegin:withEvent:inContentView: 决定自己是否接收 touch 事件
pagingEnabled:当值是 YES 会自动滚动到 subview 的边界,默认是NO
touchesShouldCancelInContentView: 开始发送 tracking messages 消息给 subview 的时候调用这个方法,决定是否发送 tracking messages 消息到subview。假如返回 NO,发送。YES 则不发送。
假如 canCancelContentTouches属性是NO,则不调用这个方法来影响如何处理滚动手势。

    scroll view 还处理缩放和平移手势,要实现缩放和平移,必须实现委托 viewForZoomingInScrollView:、scrollViewDidEndZooming:withView:atScale:
两个方法。另外 maximumZoomScale和minimumZoomScale 两个属性要不一样。

几个属性介绍

tracking
当 touch 后还没有拖动的时候值是YES,否则NO

zoomBouncing
当内容放大到最大或者最小的时候值是 YES,否则 NO

zooming
当正在缩放的时候值是 YES,否则 NO

decelerating
当滚动后,手指放开但是还在继续滚动中。这个时候是 YES,其它时候是 NO

decelerationRate
设置手指放开后的减速率

maximumZoomScale
一个浮点数,表示能放最大的倍数

minimumZoomScale 
一个浮点数,表示能缩最小的倍数

pagingEnabled
当值是 YES 会自动滚动到 subview 的边界。默认是NO

scrollEnabled
决定是否可以滚动

delaysContentTouches
是个布尔值,当值是 YES 的时候,用户触碰开始,scroll view要延迟一会,看看是否用户有意图滚动。假如滚动了,那么捕捉 touch-down 事件,否则就不捕捉。假如值是NO,当用户触碰, scroll view 会立即触发 touchesShouldBegin:withEvent:inContentView:,默认是 YES

canCancelContentTouches
当值是 YES 的时候,用户触碰后,然后在一定时间内没有移动,scrollView 发送 tracking events,然后用户移动手指足够长度触发滚动事件,这个时候,scrollView 发送了 touchesCancelled:withEvent: 到 subview,然后 scroView 开始滚动。假如值是 NO,scrollView 发送 tracking events 后,就算用户移动手指,scrollView 也不会滚动。

contentSize
里面内容的大小,也就是可以滚动的大小,默认是0,没有滚动效果。

showsHorizontalScrollIndicator
滚动时是否显示水平滚动条

showsVerticalScrollIndicator
滚动时是否显示垂直滚动条

bounces
默认是 yes,就是滚动超过边界会反弹有反弹回来的效果。假如是 NO,那么滚动到达边界会立刻停止。

bouncesZoom
和 bounces 类似,区别在于:这个效果反映在缩放上面,假如缩放超过最大缩放,那么会反弹效果;假如是 NO,则到达最大或者最小的时候立即停止。

directionalLockEnabled
默认是 NO,可以在垂直和水平方向同时运动。当值是 YES 时,假如一开始是垂直或者是水平运动,那么接下来会锁定另外一个方向的滚动。 假如一开始是对角方向滚动,则不会禁止某个方向

indicatorStyle
滚动条的样式,基本只是设置颜色。总共3个颜色:默认、黑、白

scrollIndicatorInsets
设置滚动条的位置

最后加上,我刚定的一个例子,可以缩放,及对使用的代理方法加了注释


//  ScrollViewViewController.m

//  ScrollView

//

//  Created by ch_soft on 11-11-8.

//  Copyright 2011年 __MyCompanyName__. All rights reserved.

//


#import"ScrollViewViewController.h"

#import"CustomA.h"

#import"CustomB.h"


@implementation ScrollViewViewController


- (void)didReceiveMemoryWarning

{

   // Releases the view if it doesn't have a superview.

    [superdidReceiveMemoryWarning];

    

   // Release any cached data, images, etc that aren't in use.

}


#pragma mark - View lifecycle



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad

{

   scrollview =[[UIScrollViewalloc]initWithFrame:CGRectMake(50,0,200,400)];

    scrollview.contentSize=CGSizeMake(400,400);

   scrollview.backgroundColor=[UIColororangeColor];

   scrollview.pagingEnabled=YES;//是否自己动适应

    

   viewA=[[CustomAalloc]initWithFrame:CGRectMake(50,0,100,400)];

   viewA.backgroundColor=[UIColorblueColor];

    [scrollviewaddSubview:viewA];

    [viewArelease];

    

    CustomB * viewB=[[CustomB alloc] initWithFrame:CGRectMake(250,0,100,400)];

    viewB.backgroundColor=[UIColoryellowColor];

    [scrollviewaddSubview:viewB];

    [viewB release];

    

    [self.viewaddSubview:scrollview];

   scrollview.maximumZoomScale=2.0;

   scrollview.minimumZoomScale=0.5;

//    scrollview.decelerationRate=1;

   scrollview.delegate=self;

   //canCancelContentTouches:YES-移动手指足够长度触发滚动事件,NO-scrollView发送 tracking events 后,就算用户移动手指,scrollView也不会滚动。

   scrollview.canCancelContentTouches=NO;

    

    //当值是 YES的时候,用户触碰开始.要延迟一会,看看是否用户有意图滚动。假如滚动了,那么捕捉 touch-down事件,否则就不捕捉。假如值是NO,当用户触碰, scroll view会立即触发

   scrollview.delaysContentTouches=YES;

    [scrollviewrelease];

    [superviewDidLoad];

}



#pragma mark UIScrollViewDelegate

//只要滚动了就会触发

- (void)scrollViewDidScroll:(UIScrollView *)scrollView;   

{

//    NSLog(@" scrollViewDidScroll");

    NSLog(@"ContentOffset  x is  %f,yis %f",scrollView.contentOffset.x,scrollView.contentOffset.y);

}

//开始拖拽视图

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;   

{

   NSLog(@"scrollViewWillBeginDragging");

}

//完成拖拽

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate; 

{

   NSLog(@"scrollViewDidEndDragging");

}

//将开始降速时

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;   

{

   NSLog(@"scrollViewWillBeginDecelerating");

}


//减速停止了时执行,手触摸时执行执行

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;   

{

   NSLog(@"scrollViewDidEndDecelerating");

}

//滚动动画停止时执行,代码改变时出发,也就是setContentOffset改变时

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView;

{

   NSLog(@"scrollViewDidEndScrollingAnimation");

}

//设置放大缩小的视图,要是uiscrollview的subview

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;   

{

   NSLog(@"viewForZoomingInScrollView");

    return viewA;

}

//完成放大缩小时调用

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale; 

{

    viewA.frame=CGRectMake(50,0,100,400);

   NSLog(@"scale between minimum and maximum. called after any 'bounce' animations");

}// scale between minimum and maximum. called after any 'bounce' animations


//如果你不是完全滚动到滚轴视图的顶部,你可以轻点状态栏,那个可视的滚轴视图会一直滚动到顶部,那是默认行为,你可以通过该方法返回NO来关闭它

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;   

{

    NSLog(@"scrollViewShouldScrollToTop");

   returnYES;

}


- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView;     

{

    NSLog(@"scrollViewDidScrollToTop");

}




- (void)viewDidUnload

{

    [super viewDidUnload];

   // Release any retained subviews of the main view.

   // e.g. self.myOutlet = nil;

}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

   // Return YES for supported orientations

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}


@end


    
[2] win8开发(11)——共享目标志例
    来源: 互联网  发布时间: 2014-02-18
win8开发(11)——共享目标示例

上一篇文章中,我们吹了一下共享数据的问题,后面还简单弄了一个例子,本文我们再做一个综合

一些的例子,咱们做一个全能共享目标,该目标应用可以接收各种格式的数居。

先来认识一个类,该类可以告诉我们标准数据有哪些——StandardDataFormats,这是一个静态类,

位于Windows.ApplicationModel.DataTransfer下,意味着,它的所有成员都是静态的,看下图。

 



它的一系列静成员已经告诉我们六种标准数据格式,相信不用介绍了,看名字就知道了。

StorageItems一般指存储在计算机中的文件。


本例启用了五种格式的协定(除rtf外),可以接受多种共享数据,先看看运行的结果。

情景1:启动Bing应用,搜索一些图片,选择其中一张,然后把鼠标移到屏幕的右上角或右下角,

待出现侧边栏后选择“共享”。

 

 

 

情景2:打开浏览器,随便打开一个页面。可获取到页面的URI。

 

 

 


情景3:打开“网易云阅读”应用,随便打开一篇文章,然后共享,得到共享字符串。

 

 



 

实现步骤如下:
1、启动VS,新建一个项目,此处省略45个字。
2、打开清单文件Package.appxmanifest,切换到“声明”,在列表中选择“共享目标”,单击“添加”按钮。

 

在右边的框架中,添加五个数据格式的支持。


 
3、打开MainPage.xaml,输入以下XAML
<Page
    x:
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Canvas Name="cvText" Visibility="Collapsed">
            <TextBox Name="txtText" Canvas.Left="24" Canvas.Top="12" Width="860" Height="450" TextWrapping="Wrap"/>
        </Canvas>
        
        <Canvas Name="cvBitmap" Visibility="Collapsed">
            <Image Name="img" Canvas.Top="20" Canvas.Left="24" Stretch="Uniform" Width="900"/>
        </Canvas>
        
        <TextBlock Name="tbFomats" VerticalAlignment="Bottom" HorizontalAlignment="Left"
                   FontSize="24"
                   Canvas.ZIndex="10" TextWrapping="Wrap"/>
    </Grid>
</Page>
4、打开MainPage.xaml.cs,为App类重写OnShareTargetActivated,为了好看,就另外定义一个部分类。
    public sealed partial class App : Application
    {
        protected override void OnShareTargetActivated(Windows.ApplicationModel.Activation.ShareTargetActivatedEventArgs args)
        {
            ShareOperation op = args.ShareOperation;
            Frame root = Window.Current.Content as Frame;
            if (root == null)
            {
                root = new Frame();
                root.Navigate(typeof(MainPage), op);
            }
            Window.Current.Content = root;
            Window.Current.Activate();
        }
    }
5、MainPage.xaml.cs剩下的代码如下
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.ApplicationModel.DataTransfer;
using Windows.ApplicationModel.DataTransfer.ShareTarget;
using Windows.Storage;
using Windows.Storage.Streams;

namespace MyApp
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.Parameter is ShareOperation)
            {
                ShareOperation op = (ShareOperation)e.Parameter;
                DataPackageView pv = op.Data;
                // 显示包含格式
                IReadOnlyList<string> listFormats = pv.AvailableFormats;
                string formatsStr = string.Join("\t", listFormats.ToArray());
                tbFomats.Text = formatsStr;
                // 根据获取到不同的数据格式做相应处理
                if (pv.Contains(StandardDataFormats.Bitmap))
                {
                    RandomAccessStreamReference strRef = await pv.GetBitmapAsync();
                    IRandomAccessStreamWithContentType stream = await strRef.OpenReadAsync();
                    // 读出图片
                    Windows.UI.Xaml.Media.Imaging.BitmapImage bmp=new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                    bmp.SetSource(stream);
                    this.img.Source=bmp;
                    cvText.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    cvBitmap.Visibility = Windows.UI.Xaml.Visibility.Visible;
                }
                else if (pv.Contains(StandardDataFormats.Text))
                {
                    string value = await pv.GetTextAsync();
                    txtText.Text = value;
                    cvBitmap.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    cvText.Visibility = Windows.UI.Xaml.Visibility.Visible;
                }
                else if (pv.Contains(StandardDataFormats.Uri))
                {
                    Uri xuri = await pv.GetUriAsync();
                    txtText.Text = xuri.ToString();
                    cvBitmap.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    cvText.Visibility = Windows.UI.Xaml.Visibility.Visible;
                }
                else if (pv.Contains(StandardDataFormats.Html))
                {
                    string html = HtmlFormatHelper.GetStaticFragment(await pv.GetHtmlFormatAsync());
                    txtText.Text = html;
                    cvText.Visibility = Windows.UI.Xaml.Visibility.Visible;
                    cvBitmap.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                }
                else if (pv.Contains(StandardDataFormats.StorageItems))
                {
                    IReadOnlyList<IStorageItem> items = await pv.GetStorageItemsAsync();
                    string files = string.Empty;
                    foreach (var item in items)
                    {
                        files += item.Name + "\n";
                    }
                    txtText.Text = files;
                    cvBitmap.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    cvText.Visibility = Windows.UI.Xaml.Visibility.Visible;
                }
            }
        }
    }
上面代码中,把ShareOperation作为导航的参数传递给主页面,在MainPage中的OnNavigatedTo获取。

    
[3] Box2d源码学习<5>b2Timer、b2Draw和b2Settings的实现
    来源: 互联网  发布时间: 2014-02-18
Box2d源码学习<五>b2Timer、b2Draw和b2Settings的实现

本系列博客是由扭曲45原创,欢迎转载,转载时注明出处,http://blog.csdn.net/cg0206/article/details/8280463

今天我们要说在公共模块剩下的三个小模块的实现,分别是:计时器类、调试辅助类、和box2d引擎设置部分。

1、 计时器b2Timer

计时器主要是用来计算一段时间内的时间,通过对某个函数执行计时,可用来查看相关函数的效率和性能。Box2d中主要针对window系统和类unix系统(如linux、OS X)进行了实现。它们主要是通过宏开关控制的,像window系统上的宏是_WIN32,linux系统上的宏是__linux__,OS X系统上的宏则是__APPLE__,这些在不同系统的编译器中一般是有定义的,不要我们手动去改,如果真的没有不妨自己在文件中手动定义一下,碰碰运气。

好了,废话不多说,上代码:

//计时器。这是基于特定平台上的代码,可能无法在每个平台都正常工作
class b2Timer
{
public:
	/**************************************************************************
	* 功能描述:构造函数
	* 参数说明: (void)
	* 返 回 值: (void)
	***************************************************************************/
	b2Timer();
	/**************************************************************************
	* 功能描述:重置timer
	* 参数说明: (void)
	* 返 回 值: (void)
	***************************************************************************/
	void Reset();
	/**************************************************************************
	* 功能描述:获取time从构造或最近的重置开始
	* 参数说明: (void)
	* 返 回 值: 毫秒数
	***************************************************************************/
	float32 GetMilliseconds() const;

private:

#if defined(_WIN32)
	//开始计数变量,记录开始值
	float64 m_start;
	//获取每毫秒计数的次数
	static float64 s_invFrequency;
#elif defined(__linux__) || defined (__APPLE__)
	//开始计数的秒数、微秒数
	unsigned long m_start_sec;
	unsigned long m_start_msec;
#endif
};
上面有何详细的注解,不多说了,下面我们看下实现部分:

#if defined(_WIN32) && !defined(SHP)
//获取每毫秒计数的次数
float64 b2Timer::s_invFrequency = 0.0f;

#include <windows.h>
//构造函数
b2Timer::b2Timer()
{
	//
	LARGE_INTEGER largeInteger;
	//第一次开始的时候
	if (s_invFrequency == 0.0f)
	{
		//获取高精度计数器的频率
		QueryPerformanceFrequency(&largeInteger);
		s_invFrequency = float64(largeInteger.QuadPart);
		//获取每毫秒计数的次数
		if (s_invFrequency > 0.0f)
		{
			s_invFrequency = 1000.0f / s_invFrequency;
		}
	}
	//定时器的计数值
	QueryPerformanceCounter(&largeInteger);
	m_start = float64(largeInteger.QuadPart);
}
//重置
void b2Timer::Reset()
{
	LARGE_INTEGER largeInteger;
	QueryPerformanceCounter(&largeInteger);
	m_start = float64(largeInteger.QuadPart);
}
//获取毫秒数
float32 b2Timer::GetMilliseconds() const
{
	LARGE_INTEGER largeInteger;
	QueryPerformanceCounter(&largeInteger);
	//开始计数
	float64 count = float64(largeInteger.QuadPart);
	//毫秒数
	float32 ms = float32(s_invFrequency * (count - m_start));
	return ms;
}

#elif defined(__linux__) || defined (__APPLE__)

#include <sys/time.h>
//构造函数
b2Timer::b2Timer()
{
    Reset();
}
//重置
void b2Timer::Reset()
{
    timeval t;
    gettimeofday(&t, 0);
    m_start_sec = t.tv_sec;
    m_start_msec = t.tv_usec * 0.001f;
}
//获取毫秒数
float32 b2Timer::GetMilliseconds() const
{
    timeval t;
    gettimeofday(&t, 0);
    return (t.tv_sec - m_start_sec) * 1000 + t.tv_usec * 0.001f - m_start_msec;
}

#else

b2Timer::b2Timer()
{
}

void b2Timer::Reset()
{
}

float32 b2Timer::GetMilliseconds() const
{
	return 0.0f;
}

#endif

通过宏的编译可以看出,window和类nuix上使用的内部API是不一样的,就像软件有debug和Release版本一样,有时候debug没问题,relase则不然,孰不知,它们在编译时编译器调用的程序很有可能是不同的。同时我们也要注意下,还有其他的类型的系统没有实现此类(估计一般人也碰不上)。

 

2、 调试辅助类b2Draw

调试辅助类主要辅助box2d中物体的调试,通过绘制不同的调试辅助的形状,来监控并改正物体行为的正确性。首先我们看下b2Draw.h文件。

// 调试绘制的颜色,每个值都在[0,1]之间
struct b2Color
{
	/**************************************************************************
	* 功能描述:默认构造函数
	* 参数说明: (void)
	* 返 回 值: (void)
	***************************************************************************/
	b2Color() {}
	/**************************************************************************
	* 功能描述:构造函数
	* 参数说明: r : 红色值部分
	             g :绿色值部分
				 b :蓝色值部分
	* 返 回 值: (void)
	***************************************************************************/
	b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {}
	/**************************************************************************
	* 功能描述:设置颜色函数
	* 参数说明: ri : 红色值部分
				 gi :绿色值部分
				 bi :蓝色值部分
	* 返 回 值: (void)
	***************************************************************************/
	void Set(float32 ri, float32 gi, float32 bi) { r = ri; g = gi; b = bi; }
	//代表红、绿、蓝的变量
	float32 r, g, b;
};
//在b2World中实现并注册这个类,以便提供调试绘制不同的物理实体在你的游戏中
class b2Draw
{
public:
	/**************************************************************************
	* 功能描述:构造函数
	* 参数说明: (void)
	* 返 回 值: (void)
	***************************************************************************/
	b2Draw();
	/**************************************************************************
	* 功能描述:析构函数
	* 参数说明: (void)
	* 返 回 值: (void)
	***************************************************************************/
	virtual ~b2Draw() {}

	enum
	{
		e_shapeBit				= 0x0001,	///< 绘制形状
		e_jointBit				= 0x0002,	///< 绘制关节联系
		e_aabbBit				= 0x0004,	///< 绘制轴对齐边框
		e_pairBit				= 0x0008,	///< 绘制broad-phase pairs
		e_centerOfMassBit		= 0x0010	///< 绘制质心框架
	};

	/**************************************************************************
	* 功能描述:设置绘制标志位
	* 参数说明: flags:标志
	* 返 回 值: (void)
	***************************************************************************/
	void SetFlags(uint32 flags);
	/**************************************************************************
	* 功能描述:获得绘制标志位
	* 参数说明: (void)
	* 返 回 值: 绘制标志
	***************************************************************************/
	uint32 GetFlags() const;
	/**************************************************************************
	* 功能描述:追加绘制标志位
	* 参数说明: flags:绘制标志
	* 返 回 值: (void)
	***************************************************************************/
	void AppendFlags(uint32 flags);
	/**************************************************************************
	* 功能描述:从当前标志中清除标志
	* 参数说明: flags:绘制标志
	* 返 回 值: (void)
	***************************************************************************/
	void ClearFlags(uint32 flags);
	/**************************************************************************
	* 功能描述:按照提供的顶点绘制逆时针方式闭合的多边形
	* 参数说明: vertices      :顶点
	             vertextexCount: 顶点数量
				 color         : 颜色
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
	/**************************************************************************
	* 功能描述:按照提供的顶点绘制逆时针方式闭合的并填充颜色的多边形
	* 参数说明: vertices      :顶点
	             vertextexCount: 顶点数量
				 color         : 颜色
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
	/**************************************************************************
	* 功能描述:绘制一个圆
	* 参数说明: center      :向量
	             radius      : 半径
				 color       : 颜色
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0;
	/**************************************************************************
	* 功能描述:绘制一个填充颜色的圆
	* 参数说明: center      :向量
	             radius      : 半径
				 color       : 颜色
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
	/**************************************************************************
	* 功能描述:绘制一段线段
	* 参数说明: p1      :开始点
	             p2      : 结束点
				 color   : 颜色
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
	/**************************************************************************
	* 功能描述:绘制一个变换,选择你的长度比例。
	* 参数说明:  xf  :变换
	* 返 回 值: (void)
	***************************************************************************/
	virtual void DrawTransform(const b2Transform& xf) = 0;

protected:
	//绘制标志
	uint32 m_drawFlags;
};

通过代码我们可以看到有个b2Color的结构体的定义,它主要作为调试颜色使用的。

再看看b2Draw的实现部分

//构造函数
b2Draw::b2Draw()
{
	m_drawFlags = 0;
}
//设置标志位
void b2Draw::SetFlags(uint32 flags)
{
	m_drawFlags = flags;
}
//获取标志位
uint32 b2Draw::GetFlags() const
{
	return m_drawFlags;
}
//追加标志位
void b2Draw::AppendFlags(uint32 flags)
{
	m_drawFlags |= flags;
}
//清除标志位
void b2Draw::ClearFlags(uint32 flags)
{
	m_drawFlags &= ~flags;
}

通过观察b2Draw的实现,我们发现有点不对劲,定义的函数那么多,怎么实现就这几个函数呢?那其他的函数在哪里实现的呢?我们不禁要问难道是要我们使用者自己实现吗?真被我们猜中了,这个是要我们那实现的,可以看到没有实现的函数前面都有virtual做修饰,这就是虚函数,是等着用户自己用的时候去实现的,不能直接调用。

 

3、 Box2d设置

设置中主要定义了宏、常量、和一些辅助的公共函数。我们就来看看相关的定义。

在b2Settings.h文件中:

//主要是因为有的编译器将提示相关语句的值是未使用的,
//所以你必须告诉它忽略所有(void)。
//即消除编译器的警告
#define B2_NOT_USED(x) ((void)(x))

//对断言宏进行重新封装
#define b2Assert(A) assert(A)

//重新封装类型,这样做为了方便而且很好的移植到不同的平台
typedef signed char	int8;
typedef signed short int16;
typedef signed int int32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef float float32;
typedef double float64;
//float类型最大值
#define	b2_maxFloat		FLT_MAX
//float类型最小值
#define	b2_epsilon		FLT_EPSILON
//pi的值
#define b2_pi			3.14159265359f

/// 全局常量参数 基于米-千克-秒(MKS)单位

//碰撞

//在两个凸形状上的接触点最大数量,不要修改它的值
#define b2_maxManifoldPoints	2

//凸多边形的顶点数量的最大值。你不能将这个宏修改的太大,因为b2BolckAlloctor函数有一个物体内存大小的上限
#define b2_maxPolygonVertices	8

//  用这个在动态树上填充AABB,它允许代理少量移动不必去调整这个树
//  单位是米
#define b2_aabbExtension		0.1f

//  用这个在动态树上填充AABBs,这是基于当前位移用来预测未来的位置。
//  没有单位
#define b2_aabbMultiplier		2.0f

//一个小的长度作为碰撞和约束误差,通常它被选为数字意义重大,但视觉上无足轻重。
#define b2_linearSlop			0.005f

//一个小的角度作为碰撞和约束误差,通常它被选为数字意义重大,但视觉上无足轻重。
#define b2_angularSlop			(2.0f / 180.0f * b2_pi)

///半径的多边形/边缘形状的皮肤。这应该不会被修改。使
///这意味着将有一个小的多边形数不足为连续碰撞缓冲。
///使它更大的可能创建工件为顶点碰撞。
#define b2_polygonRadius		(2.0f * b2_linearSlop)

///在连续物理模拟里,在每次接触中子步骤的最大数值
#define b2_maxSubSteps			8


//动态
//接触的最大数用于处理解决一个撞击时间内的撞击
#define b2_maxTOIContacts			32

//弹性碰撞的一个速度阈值,任何与一个相对线速度碰撞,低于这个阈值的将被视为非弹性碰撞
#define b2_velocityThreshold		1.0f

//  线性速度位置的最大值校正当解决约束使用,这有助于阻止穿越物体
#define b2_maxLinearCorrection		0.2f

//  角位置的最大值校正当解决约束使用,这有助于阻止穿越物体
#define b2_maxAngularCorrection		(8.0f / 180.0f * b2_pi)

// 物体【刚体】的最大线速度,这限制是非常大的,用于防止数值问题。你不需要去适应这个
#define b2_maxTranslation			2.0f
#define b2_maxTranslationSquared	(b2_maxTranslation * b2_maxTranslation)

// 物体【刚体】的最大线速度,这限制是非常大的,用于防止数值问题。你不需要去适应这个
#define b2_maxRotation				(0.5f * b2_pi)
#define b2_maxRotationSquared		(b2_maxRotation * b2_maxRotation)

//这个比例因子控制怎样快速解决重叠问题。理想的情况下,这将是1,这样重叠将在一个时间步内被移除
#define b2_baumgarte				0.2f
#define b2_toiBaugarte				0.75f


// 休眠
//最小休眠时间
#define b2_timeToSleep				0.5f

//刚体[body]要想休眠,线的最大值,即当角速度超过它时刚体[body]无法休眠。
#define b2_linearSleepTolerance		0.01f

//刚体[body]要想休眠,角速度的最大值,即当角速度超过它时刚体[body]无法休眠。
#define b2_angularSleepTolerance	(2.0f / 180.0f * b2_pi)

// 内存申请
//申请内存函数,实现这个函数作为你自己的内存分配器。
void* b2Alloc(int32 size);

//释放内存函数,如果你实现b2Alloc,你也应该实现这个功能。
void b2Free(void* mem);

//打印日志函数
void b2Log(const char* string, ...);
//版本编号方案
//见 http://en.wikipedia.org/wiki/Software_versioning
struct b2Version
{
	int32 major;		///重大更新
	int32 minor;		///较大更新
	int32 revision;		///修复bug
};

//box2d当前版本号
extern b2Version b2_version;

在这里还想再强调说明下B2_NOT_USED(x),很多人不理解为什么要转化为((void)x),这样做的有什么作用或者好处吗?当然是有的,以下网上查找的解释

Mainly becauseat least one compiler will complain that the resulting statement's value isunused, so you have to tell it to ignore it all with (void).

翻译了一下,也就是消除有的编译器编译时候发出的警告。这里借此说一下,编程时不要无视编译器时候发出的警告,警告的出现往往多是我们编写的时候不规范造成的,当然有一部分是错误和还有一部分编译器的原因。我们要尽量去修复它,不要因为一个无视了一个未初始化一个指针的警告,你的程序出现了莫名其妙的情况时,再满头大汗的到处说指针很坑爹。

 

接着看b2Settings.cpp文件中的实现:

//box2d当前版本号
b2Version b2_version = {2, 2, 1};
/**************************************************************************
* 功能描述:申请内存
* 参数说明:size : 申请大小
* 返 回 值: (void)
**************************************************************************/
void* b2Alloc(int32 size)
{
	return malloc(size);
}
/**************************************************************************
* 功能描述:释放内存
* 参数说明:mem : 内存头
* 返 回 值: (void)
**************************************************************************/
void b2Free(void* mem)
{
	free(mem);
}
/**************************************************************************
* 函数名称:b2Log
* 功能描述:打印log
* 参数说明:string :打印字符串
            ...    :参数列表
* 返 回 值: (void)
**************************************************************************/
void b2Log(const char* string, ...)
{
#if defined(SHP)
	#ifdef _DEBUG
	__App_info(__PRETTY_FUNCTION__ , __LINE__, string);
	#endif
#else
	va_list args;
	va_start(args, string);
	vprintf(string, args);
	va_end(args);
#endif
}

通过这过我们可以看到,我们使用的是box2d 版本号2.2.1,接下来是对c中内存管理函数malloc和free函数的封装,好处就是如果使用了不同与malloc/free的接口,我们可以在此次快速的替换。而不需要找其他任何文件。

 

公共部分终于讲完了,下面我们将会学习碰撞部分。以上部分,根据本人理解所写,若有不妥或错误之处,还请大家多多指正。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3