我有以下代码(例如,我正在构建不是游戏,我正在尝试通过OpenGL ES构建KNOB控件,Quartz2D不适合,不要问为什么):
在屏幕上对图像进行代码绘制,将来我将用我的KNOB替换这些图像:
基本上我有兴趣只旋转玩家(左侧区域的男人)。 我希望他从0度到360度连续旋转。我尝试了以下代码,但是......
self.effect.transform.modelviewMatrix = GLKMatrix4Rotate(self.effect.transform.modelviewMatrix, radians(10), 0, 0, -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
答案 0 :(得分: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