游戏开发:矢量角色与粒子效果及手势交互
立即解锁
发布时间: 2025-08-24 01:33:49 阅读量: 1 订阅数: 3 

### 游戏开发:矢量角色与粒子效果及手势交互
#### 1. 简单粒子系统与小行星类
在游戏开发中,简单粒子系统通常是在屏幕上创建大量短寿命的元素,这些元素会相对快速地衰减或消失。下面我们以小行星类为例,看看如何创建一个简单的粒子效果。
当用户点击屏幕时,会触发`tapGesture:`任务,代码如下:
```objc
- (void)tapGesture:(UIGestureRecognizer *)gestureRecognizer{
for (Asteroid* asteroid in [self actorsOfType:[Asteroid class]]){
[asteroid doHit:self];
}
}
```
此任务会遍历场景中的每个小行星,并调用其`doHit:`方法。
小行星类`Asteroid`的头文件如下:
```objc
@interface Asteroid : Actor{
}
@property (nonatomic) int level;
+(id)asteroid:(GameController*)aController;
+(id)asteroidOfLevel:(int)aLevel At:(CGPoint)aCenter;
-(void)doHit:(GameController*)controller;
@end
```
从上述代码可知,`Asteroid`类继承自`Actor`,有两个构造函数。`asteroid:`构造函数用于向场景中添加最大的小行星,`asteroidOfLevel:At:`构造函数则在点击事件后调用的`doHit:`任务中用于创建和添加较小的小行星。
`asteroid:`构造函数的实现如下:
```objc
+(id)asteroid:(GameController*)acontroller{
CGSize gameSize = [acontroller gameAreaSize];
CGPoint gameCenter = CGPointMake(gameSize.width/2.0, gameSize.height/2.0);
float directionOffScreen = arc4random()%100/100.0 * M_PI*2;
float distanceFromCenter = MAX(gameCenter.x,gameCenter.y) * 1.2;
CGPoint center = CGPointMake(gameCenter.x + cosf(directionOffScreen)*distanceFromCenter, gameCenter.y + sinf(directionOffScreen)*distanceFromCenter);
return [Asteroid asteroidOfLevel:4 At:center];
}
```
该构造函数通过调用另一个构造函数创建一个大小为 4 的新小行星,主要工作是找到小行星在屏幕外的起始点。
`asteroidOfLevel:At:`构造函数的实现如下:
```objc
+(id)asteroidOfLevel:(int)aLevel At:(CGPoint)aCenter{
ImageRepresentation* rep = [ImageRepresentation imageRepWithDelegate:[AsteroidRepresentationDelegate instance]];
[rep setBackwards:arc4random()%2 == 0];
if (aLevel >= 4){
[rep setStepsPerFrame:arc4random()%2+2];
} else {
[rep setStepsPerFrame:arc4random()%4+1];
}
Asteroid* asteroid = [[Asteroid alloc] initAt:aCenter WithRadius:4 + aLevel*7 AndRepresentation:rep];
[asteroid setLevel:aLevel];
[asteroid setVariant:arc4random()%AST_VARIATION_COUNT];
[asteroid setRotation: (arc4random()%100)/100.0*M_PI*2];
float direction = arc4random()%100/100.0 * M_PI*2;
LinearMotion* motion = [LinearMotion linearMotionInDirection:direction AtSpeed:1];
[motion setWrap:YES];
[asteroid addBehavior:motion];
return asteroid;
}
```
此为`Asteroid`类的主要构造函数,根据`aLevel`的值创建具有不同半径的小行星。随着小行星的分裂,新的小行星级别比其创建者低一级,从而逐渐变小。最后,为小行星添加`LinearMotion`行为,使其沿直线移动并环绕屏幕。
#### 2. 用同一类表示小行星和粒子
为了让小行星类和创建的粒子外观相同(只是大小不同),我们创建了`AsteroidRepresentationDelegate`类,用于指定类似小行星的元素的渲染方式。其实现代码如下:
```objc
+(AsteroidRepresentationDelegate*)instance{
static AsteroidRepresentationDelegate* instance;
@synchronized(self) {
if(!instance) {
instance = [AsteroidRepresentationDelegate new];
}
}
return instance;
}
-(int)getFrameCountForVariant:(int)aVariant AndState:(int)aState{
return 31;
}
-(NSString*)getNameForVariant:(int)aVariant{
if (aVariant == VARIATION_A){
return @"A";
} else if (aVariant == VARIATION_B){
return @"B";
} else if (aVariant == VARIATION_C){
return @"C";
} else {
return nil;
}
}
-(NSString*)baseImageName{
return @"Asteroid";
}
```
从代码中可以看出,图像文件以“`Asteroid`”开头,每个变体有 31 张图像。`instance`方法用于创建`AsteroidRepresentationDelegate`类的单例,通过对小行星类对象进行同步,确保只有在`instance`变量为`nil`时才创建新实例。
#### 3. 小行星的销毁
当点击屏幕时,会调用小行星的`doHit:`方法,代码如下:
```objc
-(void)doHit:(GameController*)controller{
if (level > 1){
int count = arc4random()%3+1;
for (int i=0;i<count;i++){
Asteroid* newAst = [Asteroid asteroidOfLevel:level-1 At:self.center];
[controller addActor:newAst];
}
}
int particles = arc4random()%5+1;
for (int i=0;i<particles;i++){
ImageRepresentation* rep = [ImageRepresentation imageRepWithDelegate:[AsteroidRepresentationDelegate instance]];
Particle* particle = [Particle particleAt:self.center WithRep:rep Steps:25];
[particle setRadius:6];
[particle setVariant:arc4random()%AST_VARIATION_COUNT];
[particle setRotation: (arc4random()%100)/100.0*M_PI*2];
LinearMotion* motion = [LinearMotion linearMotionRandomDirectionAndSpeed];
[particle addBehavior:motion];
[controller addActor: particle];
}
[controller removeActor:self];
}
```
该方法会先判断小行星的级别是否大于 1,如果是,则在当前小行星的位置创建 1 到 3 个级别低一级的新小行星。同时,会生成一定数量的类似小行星的粒子,粒子的数量是随机的。每个粒子使用`AsteroidRepresentationDelegate`的单例实例,设置其半径、变体和旋转属性,并添加随机的`LinearMotion`行为,最后将粒子添加到场景中,并移除当前小行星。
#### 4. 粒子类
粒子类`Particle`的头文件如下:
```objc
@interface Particle : Actor<ExpireAfterTimeDelegate> {
}
@property (nonatomic) float totalStepsAlive;
+(id)particleAt:(CGPoint)aCenter WithRep:(NSObject<Representation>*)rep Steps:(float)numStepsToLive;
@end
```
`Particle`类继承自`Actor`,并遵循`ExpireAfterTimeDelegate`协议,目的是在粒子的生命周期内改变其不透明度,使其逐渐消失。`totalStepsAlive`属性表示粒子在场景中存在的时长,在`particleAt:WithRep:Steps:`构造函数中设置。
`Parti
0
0
复制全文
相关推荐










