0

たとえば、次のコードがあります(例として、ゲームではなく構築しています。OpenGL ES で KNOB コントロールを構築しようとしています。Quartz2D は適合しません。理由は聞かないでください)。

ここからの元のコード:
http://www.raywenderlich.com/9743/how-to-create-a-simple-2d-iphone-game-with-opengl-es-2-0-and-glkit-part-1

画面に次の画像を描画するコード。将来的には、この画像を KNOB に置き換えます。
スクリーンショット

基本的に、私はプレーヤー (左側のエリアの男性) だけをローテーションすることに興味があります。0度から360度まで連続回転させたい。次のコードを試しましたが...

    self.effect.transform.modelviewMatrix = GLKMatrix4Rotate(self.effect.transform.modelviewMatrix, radians(10), 0, 0, -1);

全画面回転 (モンスターも含む) を提供しますが、オブジェクトを 1 つだけ回転させたい (この例では、左側の領域のプレイヤーのみ)。また、モンスターが動いていることに注意したい。

関数 [sprite render] のコード。下記参照。

メインコードは次のとおりです。

    //
//  SGGViewController.m
//  SimpleGLKitGame
//
//  Created by Ray Wenderlich on 1/30/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SGGViewController.h"
#import "SGGSprite.h"

@interface SGGViewController ()
@property (strong, nonatomic) EAGLContext *context;
@property (strong) GLKBaseEffect * effect;
@property (strong) SGGSprite * player;
@property (strong) NSMutableArray * children;
@property (assign) float timeSinceLastSpawn;
@end

@implementation SGGViewController
@synthesize effect = _effect;
@synthesize context = _context;
@synthesize player = _player;
@synthesize children = _children;
@synthesize timeSinceLastSpawn = _timeSinceLastSpawn;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];


    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    [EAGLContext setCurrentContext:self.context];

    self.effect = [[GLKBaseEffect alloc] init];

    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, 1024, 0, 768, -1, 1);
    self.effect.transform.projectionMatrix = projectionMatrix;

    self.player = [[SGGSprite alloc] initWithFile:@"2.png" effect:self.effect];
    self.player.position = GLKVector2Make(self.player.contentSize.width/2, 160);

    self.children = [NSMutableArray array];
    [self.children addObject:self.player];


}

- (void)addTarget {
    SGGSprite * target = [[SGGSprite alloc] initWithFile:@"Target.png" effect:self.effect];
    [self.children addObject:target];

    int minY = target.contentSize.height/2;
    int maxY = 320 - target.contentSize.height/2;
    int rangeY = maxY - minY;
    int actualY = (arc4random() % rangeY) + minY;

    target.position = GLKVector2Make(480 + (target.contentSize.width/2), actualY);    

    int minVelocity = 480.0/4.0;
    int maxVelocity = 480.0/2.0;
    int rangeVelocity = maxVelocity - minVelocity;
    int actualVelocity = (arc4random() % rangeVelocity) + minVelocity;

    target.moveVelocity = GLKVector2Make(-actualVelocity, 0);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

#pragma mark - GLKViewDelegate


static inline double radians (double degrees) {return degrees * M_PI/180;}


- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {    



    glClearColor(1, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);    
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    for (SGGSprite * sprite in self.children) {
        [sprite render];
    }
}

- (void)update {    

    self.timeSinceLastSpawn += self.timeSinceLastUpdate;
    if (self.timeSinceLastSpawn > 1.0) {
        self.timeSinceLastSpawn = 0;
        [self addTarget];
    }

    for (SGGSprite * sprite in self.children) {
        [sprite update:self.timeSinceLastUpdate];
    }
}

@end

これは関数 [sprite render] のコードです。

//
//  SGGSprite.m
//  SimpleGLKitGame
//
//  Created by Ray Wenderlich on 1/30/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SGGSprite.h"

typedef struct {
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

typedef struct {
    TexturedVertex bl;
    TexturedVertex br;    
    TexturedVertex tl;
    TexturedVertex tr;    
} TexturedQuad;

@interface SGGSprite()

@property (strong) GLKBaseEffect * effect;
@property (assign) TexturedQuad quad;
@property (strong) GLKTextureInfo * textureInfo;

@end

@implementation SGGSprite
@synthesize position = _position;
@synthesize contentSize = _contentSize;
@synthesize effect = _effect;
@synthesize quad = _quad;
@synthesize textureInfo = _textureInfo;
@synthesize moveVelocity = _moveVelocity;

- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect {
    if ((self = [super init])) {
        self.effect = effect;

        NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithBool:YES],
                                  GLKTextureLoaderOriginBottomLeft, 
                                  nil];

        NSError * error;    
        NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
        self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
        if (self.textureInfo == nil) {
            NSLog(@"Error loading file: %@", [error localizedDescription]);
            return nil;
        }

        self.contentSize = CGSizeMake(self.textureInfo.width, self.textureInfo.height);

        TexturedQuad newQuad;
        newQuad.bl.geometryVertex = CGPointMake(0, 0);
        newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0);
        newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
        newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height);

        newQuad.bl.textureVertex = CGPointMake(0, 0);
        newQuad.br.textureVertex = CGPointMake(1, 0);
        newQuad.tl.textureVertex = CGPointMake(0, 1);
        newQuad.tr.textureVertex = CGPointMake(1, 1);
        self.quad = newQuad;

    }
    return self;
}

- (GLKMatrix4) modelMatrix {

    GLKMatrix4 modelMatrix = GLKMatrix4Identity;    
    modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, 0);
    modelMatrix = GLKMatrix4Translate(modelMatrix, -self.contentSize.width/2, -self.contentSize.height/2, 0);
    return modelMatrix;

}


static inline double radians (double degrees) {return degrees * M_PI/180;}

- (void)render { 

    self.effect.texture2d0.name = self.textureInfo.name;
    self.effect.texture2d0.enabled = YES;
    self.effect.transform.modelviewMatrix = self.modelMatrix;

    [self.effect prepareToDraw];
    long offset = (long)&_quad;


    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

}

- (void)update:(float)dt {

    GLKVector2 curMove = GLKVector2MultiplyScalar(self.moveVelocity, dt);



    self.position = GLKVector2Add(self.position, curMove);

}

@end
4

1 に答える 1

0

この例では、同じ関数を共有して、プレーヤー、ターゲット、および背景を描画します。プレーヤーが回転などの別の効果を適用するには、新しい効果とマトリックスを個別に定義する必要があります。

たとえば、SGGViewController.m の場合は次のとおりです。

//
//  SGGViewController.m
//  SimpleGLKitGame
//
//  Created by Ray Wenderlich on 1/30/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SGGViewController.h"
#import "SGGSprite.h"

float _rotation;

@interface SGGViewController ()
@property (strong, nonatomic) EAGLContext *context;
@property (strong) GLKBaseEffect * effect;
@property (strong) GLKBaseEffect * effectPlayer;  //Added For The Player
@property (strong) SGGSprite * player;
@property (strong) NSMutableArray * children;
@property (strong) NSMutableArray * childrenPlayer; //Added For The Player
@property (assign) float timeSinceLastSpawn;
@end

@implementation SGGViewController
@synthesize effect = _effect;
@synthesize effectPlayer = _effectPlayer;
@synthesize context = _context;
@synthesize player = _player;
@synthesize children = _children;
@synthesize childrenPlayer = _childrenPlayer;
@synthesize timeSinceLastSpawn = _timeSinceLastSpawn;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];


    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    [EAGLContext setCurrentContext:self.context];

    //--------------------This Is To Define Effect For The background-------------------
    self.effect = [[GLKBaseEffect alloc] init];
    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, 480, 0, 320, -1024, 1024);
    self.effect.transform.projectionMatrix = projectionMatrix;
    //----------------------------------------------------------------------------------

    //--------This One For The Player ---------
    self.effectPlayer = [[GLKBaseEffect alloc] init];
    GLKMatrix4 projectionMatrixPlay = GLKMatrix4MakeOrtho(0, 480, 0, 320, -1024, 1024);
    self.effectPlayer.transform.projectionMatrix = projectionMatrixPlay;
    //----------------------------------------------------------------------------------

    //----Note Here I Have Uses Another Separate Function To Init The Texture File----
    self.player = [[SGGSprite alloc] initWithFilePlayer:@"2.png" effectPlayer:self.effectPlayer];
    self.player.positionPlayer = GLKVector2Make(self.player.contentSizePlayer.width/2, 160);

    //--The Array Setting For Target And Anything Else (Background, Splash, Etc.)---
    self.children = [NSMutableArray array];

    //---And This Is The Array Setting For The Player---
    self.childrenPlayer = [NSMutableArray array];
    [self.childrenPlayer addObject:self.player];


}

//-----While The Target As Usual--------
- (void)addTarget 
{
    SGGSprite * target = [[SGGSprite alloc] initWithFile:@"Target.png" effect:self.effect];
    [self.children addObject:target];

    int minY = target.contentSize.height/2;
    int maxY = 320 - target.contentSize.height/2;
    int rangeY = maxY - minY;
    int actualY = (arc4random() % rangeY) + minY;

    target.position = GLKVector2Make(480 + (target.contentSize.width/2), actualY);    

    int minVelocity = 480.0/4.0;
    int maxVelocity = 480.0/2.0;
    int rangeVelocity = maxVelocity - minVelocity;
    int actualVelocity = (arc4random() % rangeVelocity) + minVelocity;

    target.moveVelocity = GLKVector2Make(-actualVelocity, 0);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

#pragma mark - GLKViewDelegate


static inline double radians (double degrees) {return degrees * M_PI/180;}


- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {    



    glClearColor(1, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);    
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    for (SGGSprite * sprite in self.children) {
        [sprite render];
    }
    //--------Separate Rendering For The Player In A New Function RenderPlayer-----------
    for (SGGSprite * sprite in self.childrenPlayer) {
        [sprite renderPlayer];
    }

}

- (void)update 
{    

    self.timeSinceLastSpawn += self.timeSinceLastUpdate;
    _rotation += self.timeSinceLastUpdate * 20;  //Speed And Angle Of Rotation

    if (self.timeSinceLastSpawn > 1.0) {
        self.timeSinceLastSpawn = 0;
        [self addTarget];
    }

    for (SGGSprite * sprite in self.children) 
    {
        [sprite update:self.timeSinceLastUpdate];
    }

    //---Another One For The Player Note Theres A New Function Called updatePlayer---
    for (SGGSprite * sprite in self.childrenPlayer) 
    {
        [sprite updatePlayer:self.timeSinceLastUpdate rotationPlayer:_rotation];
    }
}

@end

そして今 SGGSprite.m

//
//  SGGSprite.m
//  SimpleGLKitGame
//
//  Created by Ray Wenderlich on 1/30/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SGGSprite.h"

typedef struct {
    CGPoint geometryVertex;
    CGPoint textureVertex;
} TexturedVertex;

typedef struct {
    TexturedVertex bl;
    TexturedVertex br;    
    TexturedVertex tl;
    TexturedVertex tr;    
} TexturedQuad;

typedef struct {
    CGPoint geometryVertexPlayer;
    CGPoint textureVertexPlayer;
} TexturedVertexPlayer;

typedef struct {
    TexturedVertexPlayer bl;
    TexturedVertexPlayer br;    
    TexturedVertexPlayer tl;
    TexturedVertexPlayer tr;    
} TexturedQuadPlayer;




@interface SGGSprite()

@property (strong) GLKBaseEffect * effect;
@property (strong) GLKBaseEffect * effectPlayer;  //Added
@property (assign) TexturedQuad quad;
@property (strong) GLKTextureInfo * textureInfo;
@property (assign) TexturedQuadPlayer quadPlayer; //Added
@property (strong) GLKTextureInfo * textureInfoPlayer; //Added

@end

@implementation SGGSprite
@synthesize position = _position;
@synthesize positionPlayer = _positionPlayer;  //Added
@synthesize contentSize = _contentSize;
@synthesize contentSizePlayer = _contentSizePlayer;  //Added
@synthesize effect = _effect;
@synthesize effectPlayer = _effectPlayer; //Added
@synthesize quad = _quad;
@synthesize quadPlayer = _quadPlayer; //Added
@synthesize textureInfo = _textureInfo;
@synthesize moveVelocity = _moveVelocity;
@synthesize textureInfoPlayer = _textureInfoPlayer;  //Added
@synthesize moveVelocityPlayer = _moveVelocityPlayer;  //Added

int moved = 0;   // to make sure the game just started

- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect 
{
    if ((self = [super init])) 
    {
        self.effect = effect;

        NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithBool:YES],
                                  GLKTextureLoaderOriginBottomLeft, 
                                  nil];

        NSError * error;    
        NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
        self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
        if (self.textureInfo == nil) 
        {
            NSLog(@"Error loading file: %@", [error localizedDescription]);
            return nil;
        }

        self.contentSize = CGSizeMake(self.textureInfo.width, self.textureInfo.height);

        TexturedQuad newQuad;
        newQuad.bl.geometryVertex = CGPointMake(0, 0);
        newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0);
        newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
        newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height);

        newQuad.bl.textureVertex = CGPointMake(0, 0);
        newQuad.br.textureVertex = CGPointMake(1, 0);
        newQuad.tl.textureVertex = CGPointMake(0, 1);
        newQuad.tr.textureVertex = CGPointMake(1, 1);
        self.quad = newQuad;
    }
    return self;
}
//----------The Init Function For The Player Only-------------
- (id)initWithFilePlayer:(NSString *)fileName effectPlayer:(GLKBaseEffect *)effectPlayer 
{
    if ((self = [super init])) 
    {
        self.effectPlayer = effectPlayer;

        NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithBool:YES],
                                  GLKTextureLoaderOriginBottomLeft, 
                                  nil];

        NSError * error;    
        NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
        self.textureInfoPlayer = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
        if (self.textureInfoPlayer == nil) 
        {
            NSLog(@"Error loading file: %@", [error localizedDescription]);
            return nil;
        }

        self.contentSizePlayer = CGSizeMake(self.textureInfoPlayer.width, self.textureInfoPlayer.height);

        TexturedQuadPlayer newQuad;
        newQuad.bl.geometryVertexPlayer = CGPointMake(0, 0);
        newQuad.br.geometryVertexPlayer = CGPointMake(self.textureInfoPlayer.width, 0);
        newQuad.tl.geometryVertexPlayer = CGPointMake(0, self.textureInfoPlayer.height);
        newQuad.tr.geometryVertexPlayer = CGPointMake(self.textureInfoPlayer.width, self.textureInfoPlayer.height);
        newQuad.bl.textureVertexPlayer = CGPointMake(0, 0);
        newQuad.br.textureVertexPlayer = CGPointMake(1, 0);
        newQuad.tl.textureVertexPlayer = CGPointMake(0, 1);
        newQuad.tr.textureVertexPlayer = CGPointMake(1, 1);
        self.quadPlayer = newQuad;
    }
    return self;
}


- (GLKMatrix4) modelMatrix 
{

    GLKMatrix4 modelMatrix = GLKMatrix4Identity;    
    modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, 0);
    modelMatrix = GLKMatrix4Translate(modelMatrix, -self.contentSize.width/2, -self.contentSize.height/2, 0);
    return modelMatrix;

} 

//-------------Added For The Player-----------------
- (GLKMatrix4) modelMatrixPlayer 
{

    GLKMatrix4 modelMatrixPlayer = GLKMatrix4Identity;    
    modelMatrixPlayer = GLKMatrix4Translate(modelMatrixPlayer, self.positionPlayer.x, self.positionPlayer.y, 0);
    modelMatrixPlayer = GLKMatrix4Translate(modelMatrixPlayer, -self.contentSizePlayer.width/2, -self.contentSizePlayer.height/2, 0);
    return modelMatrixPlayer;

} 


static inline double radians (double degrees) {return degrees * M_PI/180;}

- (void)render 
{ 

    self.effect.texture2d0.name = self.textureInfo.name;
    self.effect.texture2d0.enabled = YES;
    self.effect.transform.modelviewMatrix = self.modelMatrix;

    [self.effect prepareToDraw];
    long offset = (long)&_quad;


    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

}

- (void)renderPlayer 
{ 

    self.effectPlayer.texture2d0.name = self.textureInfoPlayer.name;
    self.effectPlayer.texture2d0.enabled = YES;

    if (moved == 0) // Only Applied When You Restart Game To Position The Player In The Center
    {
        self.effectPlayer.transform.modelviewMatrix = self.modelMatrixPlayer;
    }

    [self.effectPlayer prepareToDraw];
    long offset = (long)&_quadPlayer;


    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertexPlayer), (void *) (offset + offsetof(TexturedVertexPlayer, geometryVertexPlayer)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertexPlayer), (void *) (offset + offsetof(TexturedVertexPlayer, textureVertexPlayer)));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

}


- (void)update:(float)dt 
{

    GLKVector2 curMove = GLKVector2MultiplyScalar(self.moveVelocity, dt);
    self.position = GLKVector2Add(self.position, curMove);

}

// ------------- Rotate The Object --------------------------------------------

- (void)updatePlayer:(float)rt rotationPlayer:(float)rotate
{

    moved = 1;

    self.effectPlayer.transform.modelviewMatrix = self.modelMatrixPlayer; //Adjust the player Location And Ready To Move 

    //Moving The Object 
    GLKVector2 curRotate = GLKVector2MultiplyScalar(self.moveVelocityPlayer, rt);
    self.positionPlayer = GLKVector2Add(self.positionPlayer, curRotate);     

    //Rotation Section
    self.effectPlayer.transform.modelviewMatrix = GLKMatrix4Rotate(self.effectPlayer.transform.modelviewMatrix, rotate, 0, 0, -1);

}

@end

ここにあるのは SGGSprite.h だけではありません

//
//  SGGSprite.h
//  SimpleGLKitGame
//
//  Created by Ray Wenderlich on 1/30/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <GLKit/GLKit.h>
#import <Foundation/Foundation.h>

@interface SGGSprite : NSObject
@property (assign) GLKVector2 position; 
@property (assign) GLKVector2 positionPlayer; //Position For The Player
@property (assign) CGSize contentSize;  
@property (assign) CGSize contentSizePlayer;  //Size Of The Player
@property (assign) GLKVector2 moveVelocity; 
@property (assign) GLKVector2 moveVelocityPlayer; //Speed Of The Player If Moved

- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect;
- (id)initWithFilePlayer:(NSString *)fileName effectPlayer:(GLKBaseEffect *)effectPlayer;
- (void)render;
- (void)renderPlayer;

- (void)update:(float)dt;  //Move Object
- (void)updatePlayer:(float)rt rotationPlayer:(float)rotate; //Rotate Object
@end
于 2012-08-10T08:32:20.663 に答える