tinywings

时间:2024-10-16 22:22:20编辑:小早

用iphone可以做什么?

用iphone可以做以下行为:1、上网看漫画,看小说;2、上网看视频及手机电视、听音乐。3、地图导航,使用谷歌地图可以导航。尤其去旅游的时候,定位导航方便。4、可以定外卖,网购;5、玩手游;6、照相、录像、录音。第一代iPhone及iPhone 3G都有一个固定焦距的200万像素后置镜头,它们没有闪光灯、光学焦距及自动对焦,不支持拍摄视频。iPhone 3G的用户可以通过在应用程序商店购买第三方应用程序,IOS越狱也能做到这效果。iPhone OS 2.0引入了照片的地理标记功能。扩展资料:功能设置iPhone包括了iPod的媒体播放功能,和为了移动设备修改后的Mac OS X操作系统(iOS,本名iPhone OS,自4.0版本起改名为iOS),以及800万像素的摄像头。此外,设备内置有重力感应器,iPhone4有三轴陀螺仪,能依照用户水平或垂直的持用方式,自动调整屏幕显示方向。并且内置了光感器,支持根据当前光线强度调整屏幕亮度。还内置了距离感应器,防止在接打电话时,耳朵误触屏幕引起的操作。2012年9月发布的iPhone4S、5更是加入了一个全新的拍照模式——全景模式,在该模式下可以用iPhone 4S、5拍摄全景照片,全景照片可达2800万像素。移动电话、宽屏iPod和上网装置 ─iPhone将三大功能集于一身,通过iPhone的多点触摸(Multi-Touch)技术,手指轻点就能拨打电话、应用程序之间也易如反掌。还可以直接从网站拷贝粘贴文字和图片。它同时是世界上第一台批量生产商业用途的使用电容屏的智能手机。参考资料来源:百度百科-iPhone

如何制作一个类似Tiny Wings的游戏 Cocos2d-x 2.1.4

步骤如下(个人复制 仅供参考 版权归原作者):
1.使用上一篇的工程;
2.添加地形类Terrain,派生自CCNode类。文件Terrain.h代码如下:

#pragma once
#include "cocos2d.h"
#define kMaxHillKeyPoints 1000
class Terrain : public cocos2d::CCNode
{
public:
Terrain(void);
~Terrain(void);
CREATE_FUNC(Terrain);
CC_SYNTHESIZE_RETAIN(cocos2d::CCSprite*, _stripes, Stripes);
private:
int _offsetX;
cocos2d::CCPoint _hillKeyPoints[kMaxHillKeyPoints];
};
这里声明了一个_hillKeyPoints数组,用来存储每个山丘顶峰的点,同时声明了一个_offsetX代表当前地形滚动的偏移量。文件Terrain.cpp代码如下:


#include "Terrain.h"
using namespace cocos2d;
Terrain::Terrain(void)
{
_stripes = NULL;
_offsetX = 0;
}
Terrain::~Terrain(void)
{
CC_SAFE_RELEASE_NULL(_stripes);
}
增加如下方法:

void Terrain::generateHills()
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
float x = 0;
float y = winSize.height / 2;
for (int i = 0; i < kMaxHillKeyPoints; ++i)
{
_hillKeyPoints[i] = ccp(x, y);
x += winSize.width / 2;
y = rand() % (int)winSize.height;
}
}
这个方法用来生成随机的山丘顶峰的点。第一个点在屏幕的左侧中间,之后的每一个点,x轴方向移动半个屏幕宽度,y轴方向设置为0到屏幕高度之间的一个随机值。添加以下方法:

bool Terrain::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(!CCNode::init());
this->generateHills();
bRet = true;
} while (0);
return bRet;
}
void Terrain::draw()
{
CCNode::draw();
for (int i = 1; i < kMaxHillKeyPoints; ++i)
{
ccDrawLine(_hillKeyPoints[i - 1], _hillKeyPoints[i]);
}
}
init方法调用generateHills方法创建山丘,draw方法简单地绘制相邻点之间的线段,方便可视化调试。添加以下方法:
1
2
3
4
5
void Terrain::setOffsetX(float newOffsetX)
{
_offsetX = newOffsetX;
this->setPosition(ccp(-_offsetX * this->getScale(), 0));
}
英雄沿着地形的x轴方法前进,地形向左滑动。因此,偏移量需要乘以-1,还有缩放比例。打开HelloWorldScene.h文件,添加头文件引用:
1
#include "Terrain.h"
添加如下变量:
1
Terrain *_terrain;
打开HelloWorldScene.cpp文件,在onEnter方法里,调用genBackground方法之前,加入如下代码:
1
2
_terrain = Terrain::create();
this->addChild(_terrain, 1);
在update方法里,最后面添加如下代码:
1
_terrain->setOffsetX(offset);
修改genBackground方法为如下:

void HelloWorld::genBackground()
{
if (_background)
{
_background->removeFromParentAndCleanup(true);
}
ccColor4F bgColor = this->randomBrightColor();
_background = this->spriteWithColor(bgColor, 512, 512);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
_background->setPosition(ccp(winSize.width / 2, winSize.height / 2));
ccTexParams tp = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
_background->getTexture()->setTexParameters(&tp);
this->addChild(_background);
ccColor4F color3 = this->randomBrightColor();
ccColor4F color4 = this->randomBrightColor();
CCSprite *stripes = this->spriteWithColor1(color3, color4, 512, 512, 4);
ccTexParams tp2 = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_CLAMP_TO_EDGE};
stripes->getTexture()->setTexParameters(&tp2);
_terrain->setStripes(stripes);
}
注意,每次触摸屏幕,地形上的条纹纹理都会随机生成一个新的条纹纹理,这方便于测试。此外,在Update方法里_background调用setTextureRect方法时,可以将offset乘以0.7,这样背景就会比地形滚动地慢一些。编译运行,可以看到一些线段,连接着山丘顶峰的点,如下图所示:
当看到山丘滚动,可以想象得到,这对于一个Tiny Wings游戏,并不能很好的工作。由于采用y轴随机值,有时候山丘太高,有时候山丘又太低,而且x轴也没有足够的差别。但是现在已经有了这些测试代码,是时候用更好的算法了。
3.更好的山丘算法。使用Sergey的算法来进行实现。打开Terrain.cpp文件,修改generateHills方法为如下:

void Terrain::generateHills()
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
float minDX = 160;
float minDY = 60;
int rangeDX = 80;
int rangeDY = 40;
float x = -minDX;
float y = winSize.height / 2;
float dy, ny;
float sign = 1; // +1 - going up, -1 - going down
float paddingTop = 20;
float paddingBottom = 20;
for (int i = 0; i < kMaxHillKeyPoints; ++i)
{
_hillKeyPoints[i] = ccp(x, y);
if (i == 0)
{
x = 0;
y = winSize.height / 2;
}
else
{
x += rand() % rangeDX + minDX;
while (true)
{
dy = rand() % rangeDY + minDY;
ny = y + dy * sign;
if (ny paddingBottom)
{
break;
}
}
y = ny;
}
sign *= -1;
}
}
这个算法执行的策略如下:
在范围160加上0-80之间的随机数进行递增x轴。
在范围60加上0-40之间的随机数进行递增y轴。
每次都反转y轴偏移量。
不要让y轴值过于接近顶部或底部(paddingTop, paddingBottom)。
开始于屏幕外的左侧,硬编码第二个点为(0, winSize.height/2),所以左侧屏幕外有一个山丘。
编译运行,现在可以看到一个更好的山丘算法,如下图所示:
4.一次只绘制部分。在更进一步之前,需要做出一项重大的性能优化。现在,绘制出了山丘的1000个顶峰点,即使每次都只有少数在屏幕上看得到。所以,可以根据屏幕区域来计算哪些顶峰点会被显示出来,然后只显示那些点,如下图所示:
打开Terrain.h文件,添加如下变量:
1
2
int _fromKeyPointI;
int _toKeyPointI;
打开Terrain.cpp文件,在构造函数里面添加如下代码:
1
2
_fromKeyPointI = 0;
_toKeyPointI = 0;
添加如下方法:

void Terrain::resetHillVertices()
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
static int prevFromKeyPointI = -1;
static int prevToKeyPointI = -1;
// key points interval for drawing
while (_hillKeyPoints[_fromKeyPointI + 1].x getScale())
{
_fromKeyPointI++;
}
while (_hillKeyPoints[_toKeyPointI].x getScale())
{
_toKeyPointI++;
}
}
这里,遍历每一个顶峰点(从0开始),将它们的x轴值拿来做比较。无论当前对应到屏幕左边缘的偏移量设置为多少,只要将它减去winSize.width/8。如果顶峰点的x轴值小于结果值,那么就继续遍历,直到找到一个大于结果值的,这个顶峰点就是显示的起始点。对于toKeypoint也采用同样的过程。修改draw方法,代码如下:

void Terrain::draw()
{
CCNode::draw();
for (int i = MAX(_fromKeyPointI, 1); i <= _toKeyPointI; ++i)
{
ccDrawColor4F(1.0, 0, 0, 1.0);
ccDrawLine(_hillKeyPoints[i - 1], _hillKeyPoints[i]);
}
}
现在,不是绘制所有点,而是只绘制当前可见的点,这些点是前面计算得到的。另外,也把线的颜色改成红色,这样更易于分辨。接着,在init方法里面,最后面添加如下代码:
1
this->resetHillVertices();
在setOffsetX方法里面,最后面添加如下代码:
1
this->resetHillVertices();
为了更容易看到,打开HelloWorldScene.cpp文件,在onEnter方法,最后面添加如下代码:
1
this->setScale(0.25);
编译运行,可以看到线段出现时才进行绘制,如下图所示:
5.制作平滑的斜坡。山丘是有斜坡的,而不是这样直上直下的直线。一个办法是使用余弦函数让山丘弯曲。回想一下,余弦曲线就如下图所示:
因此,它是从1开始,每隔PI长度,曲线下降到-1。但怎么利用这个函数来创建一个漂亮的曲线连接顶峰点呢?先只考虑两个点的情况,如下图所示:
首先,需要分段绘制线,因此,需要每10个点创建一个区段。同样的,想要一个完整的余弦曲线,因此,可以将PI除以区段的数量,得到每个点的角度。然后,让cos(0)对应p0的y轴值,而cos(PI)对应p1的y轴值。要做到这一点,将调用cos(angle),乘以p1和p0之间距离的一半(图上的ampl)。由于cos(0)=1,而cos(PI)=-1,所以,ampl在p0,而-ampl在p1。将它加上中点坐标,就可以得到想要的y轴值。打开Terrain.h文件,添加区段长度定义,如下代码:
1
#define kHillSegmentWidth 10
然后,打开Terrain.cpp文件,在draw方法里面,ccDrawLine之后,添加如下代码:

ccDrawColor4F(1.0, 1.0, 1.0, 1.0);
CCPoint p0 = _hillKeyPoints[i - 1];
CCPoint p1 = _hillKeyPoints[i];
int hSegments = floorf((p1.x - p0.x) / kHillSegmentWidth);
float dx = (p1.x - p0.x) / hSegments;
float da = M_PI / hSegments;
float ymid = (p0.y + p1.y) / 2;
float ampl = (p0.y - p1.y) / 2;
CCPoint pt0, pt1;
pt0 = p0;
for (int j = 0; j < hSegments + 1; ++j)
{
pt1.x = p0.x + j * dx;
pt1.y = ymid + ampl * cosf(da * j);
ccDrawLine(pt0, pt1);
pt0 = pt1;
}
打开HelloWorldScene.cpp文件,在onEnter方法,设置scale为1.0,如下代码:

this->setScale(1.0);
编译运行,现在可以看到一条曲线连接着山丘,如下图所示:
6.绘制山丘。用上一篇文章生成的条纹纹理来绘制山丘。计划是对山丘的每个区段,计算出两个三角形来渲染山丘,如下图所示:
还将设置每个点的纹理坐标。对于x坐标,简单地除以纹理的宽度(因为纹理重复)。对于y坐标,将山丘的底部映射为0,顶部映射为1,沿着条带的方向分发纹理高度。打开Terrain.h文件,添加如下代码:

#define kMaxHillVertices 4000
#define kMaxBorderVertices 800
添加类变量,代码如下:

int _nHillVertices;
cocos2d::CCPoint _hillVertices[kMaxHillVertices];
cocos2d::CCPoint _hillTexCoords[kMaxHillVertices];
int _nBorderVertices;
cocos2d::CCPoint _borderVertices[kMaxBorderVertices];
打开Terrain.cpp文件,在resetHillVertices方法里面,最后面添加如下代码:

if (prevFromKeyPointI != _fromKeyPointI || prevToKeyPointI != _toKeyPointI)
{
// vertices for visible area
_nHillVertices = 0;
_nBorderVertices = 0;
CCPoint p0, p1, pt0, pt1;
p0 = _hillKeyPoints[_fromKeyPointI];
for (int i = _fromKeyPointI + 1; i < _toKeyPointI + 1; ++i)
{
p1 = _hillKeyPoints[i];
// triangle strip between p0 and p1
int hSegments = floorf((p1.x - p0.x) / kHillSegmentWidth);
float dx = (p1.x - p0.x) / hSegments;
float da = M_PI / hSegments;
float ymid = (p0.y + p1.y) / 2;
float ampl = (p0.y - p1.y) / 2;
pt0 = p0;
_borderVertices[_nBorderVertices++] = pt0;
for (int j = 1; j < hSegments + 1; ++j)
{
pt1.x = p0.x + j * dx;
pt1.y = ymid + ampl * cosf(da * j);
_borderVertices[_nBorderVertices++] = pt1;
_hillVertices[_nHillVertices] = ccp(pt0.x, 0);
_hillTexCoords[_nHillVertices++] = ccp(pt0.x / 512, 1.0f);
_hillVertices[_nHillVertices] = ccp(pt1.x, 0);
_hillTexCoords[_nHillVertices++] = ccp(pt1.x / 512, 1.0f);
_hillVertices[_nHillVertices] = ccp(pt0.x, pt0.y);
_hillTexCoords[_nHillVertices++] = ccp(pt0.x / 512, 0);
_hillVertices[_nHillVertices] = ccp(pt1.x, pt1.y);
_hillTexCoords[_nHillVertices++] = ccp(pt1.x / 512, 0);
pt0 = pt1;
}
p0 = p1;
}
prevFromKeyPointI = _fromKeyPointI;
prevToKeyPointI = _toKeyPointI;
}
这里的大部分代码,跟上面的使用余弦绘制山丘曲线一样。新的部分,是将山丘每个区段的顶点用来填充数组,每个条纹需要4个顶点和4个纹理坐标。在draw方法里面,最上面添加如下代码:

CC_NODE_DRAW_SETUP();
ccGLBindTexture2D(_stripes->getTexture()->getName());
ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords);
ccDrawColor4F(1.0f, 1.0f, 1.0f, 1.0f);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, _hillVertices);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, _hillTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)_nHillVertices);
这里绑定条纹纹理作为渲染纹理来使用,传入之前计算好的顶点数组和纹理坐标数组,然后以GL_TRIANGLE_STRIP来绘制这些数组。此外,注释掉绘制山丘直线和曲线的代码。在init方法里面,调用generateHills方法之前,添加如下代码:
1
this->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTexture));
打开HelloWorldScene.cpp文件,在spriteWithColor1方法里面,注释// Layer 4: Noise里,更改混合方式,代码如下:
1
ccBlendFunc blendFunc = {GL_DST_COLOR, CC_BLEND_DST};
编译运行,可以看到不错的山丘了,如下图所示:
7.还不完善?仔细看山丘,可能会注意到一些不完善的地方,如下图所示:
增加水平区段数量,可以提高一些质量。打开Terrain.h文件,修改kHillSegmentWidth为如下:
1
#define kHillSegmentWidth 5
通过减少每个区段的宽度,强制代码生成更多的区段来填充空间。编译运行,可以看到山丘看起来更好了。当然,代价是处理时间。效果如下图所示:
在第二部分,将会实现海豹飞翔。


上一篇:活着 读后感

下一篇:没有了