#import #import #import #import "EAGLView.h" #import "peanutsmodel.h" #import "sprite.h" #define USE_DEPTH_BUFFER 0 @interface EAGLView () // boilerplate omitted - (void)drawRectangleX1:(double)x1 y1:(double)y1 x2:(double)x2 y2:(double)y2 color:(UIColor*)c; @end @implementation EAGLView // synthesized properties and initWithCoder omitted - (void)drawView { [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glViewport(0, 0, backingWidth, backingHeight); // set up ortho projection to show game area of (0, 0) to (1, 1) [should use model getWidth...] // note that the view is 50% taller than wide in portrait mode so we have a little extra space there glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0.0, 1.0f, -0.25f, 1.25f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); // clear view glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // draw borders [self drawRectangleX1:0.0 y1:-0.25 x2:1.0 y2:0.0 color:[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0]]; [self drawRectangleX1:0.0 y1:1.0 x2:1.0 y2:1.25 color:[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0]]; NSArray* sprites = [model getSprites]; for (int i = 0; i < [sprites count]; i++) { Sprite* s = (Sprite*)[sprites objectAtIndex:i]; [self drawRectangleX1:[s getX] - [s getBoundingRadius] / 2 y1:[s getY] - [s getBoundingRadius] / 2 x2:[s getX] + [s getBoundingRadius] / 2 y2:[s getY] + [s getBoundingRadius] / 2 color:[s getColor]]; } glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; } - (void)drawRectangleX1:(double)x1 y1:(double)y1 x2:(double)x2 y2:(double)y2 color:(UIColor*)c { GLfloat* verts = malloc(sizeof(GLfloat) * 8); GLubyte* colors = malloc(sizeof(GLubyte) * 16); verts[0] = x1; verts[1] = y1; verts[2] = x2; verts[3] = y1; verts[4] = x1; verts[5] = y2; verts[6] = x2; verts[7] = y2; const CGFloat* colorComponents = CGColorGetComponents(c.CGColor); int numComponents = CGColorGetNumberOfComponents(c.CGColor); for (int v = 0; v < 4; v++) { for (int c = 0; c < 4; c++) { if (c < numComponents - 1) { colors[v * 4 + c] = (int)(colorComponents[c] * 255); } else if (c == 3) { // alpha is last component colors[v * 4 + c] = (int)(colorComponents[numComponents - 1] * 255); } else { // assume grayscale; use 1st component colors[v * 4 + c] = (int)(colorComponents[0] * 255); } } } glVertexPointer(2, GL_FLOAT, 0, verts); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); glEnableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); free(verts); free(colors); } // layoutSubviews, createFramebufer, destroyFramebuffer omitted - (void)update { if (model != nil) { [model update]; } [self drawView]; } - (id) init { model = nil; return [super init]; } - (void)associate:(PeanutsModel*) d { model = [d retain]; } - (void)startAnimation { self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(update) userInfo:nil repeats:YES]; } // stopAnimation, setAnimationTimer, setAnimationInterval omitted - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { [model movePlayerXDir:1 yDir:0]; // haven't enabled multi-touch, so anyObject gets _the_ touch UITouch* touch = [touches anyObject]; CGPoint location = [touch locationInView:self]; // compute touch location in world space (hard-coded (0,-.25)-(1,1.25) viewport) double touchX = (location.x - self.bounds.origin.x) / self.bounds.size.width; double touchY = 1.25 - (location.y - self.bounds.origin.y) / self.bounds.size.height * 1.5; double playerX = [[model getPlayer] getX]; double playerY = [[model getPlayer] getY]; // figure out direction from player to touch int dx = 0; if (touchX + 0.1 < playerX) { dx = -1; } else if (touchX - 0.1 > playerX) { dx = 1; } int dy = 0; if (touchY + 0.1 < playerY) { dy = -1; } else if (touchY - 0.1 > playerY) { dy = 1; } [model movePlayerXDir:dx yDir:dy]; } - (void)dealloc { [self stopAnimation]; if ([EAGLContext currentContext] == context) { [EAGLContext setCurrentContext:nil]; } if (model != nil) { [model release]; } [context release]; [super dealloc]; } @end