くまちゃんのiOS/Androidゲームプログラミング

マイペースでゲームつくってます。

ショートプログラム「ドッジボール」 【Xcode5】iOS7

f:id:tadakazu1972:20140108221503p:plain

画像ファイル3点用意
kumako01.png (32x32)
ball.png (8x8)
smile.png (8x)

ViewControllerをxibありで新規作成で追加、後述のDodgeBallViewクラスを追加した後、ひも付け
(ひも付けの意味は以下のPDFの9枚目以降を参照)
https://dl.dropboxusercontent.com/u/87424454/4%E8%83%8C%E6%99%AF%28Xcode5%29/Xcode5%E3%83%93%E3%83%AB%E3%83%89%E6%89%8B%E9%A0%86.pdf

AppDelegate.mに以下を追記

#import "ViewController.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    // Set root ViewController
    ViewController *viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = viewController;
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    // Screen Adjust Y+24 for time bar
    CGRect bounds=[[UIScreen mainScreen] bounds];
    bounds.origin.y+=24;
    bounds.size.height-=24;
    [viewController.view setFrame:bounds];
    
    return YES;
}

DodgeBallView.h

//
//  DodgeBallView.h
//  DodgeBall
//
//  Created by 中道 忠和 on 2014/01/05.
//  Copyright (c) 2014年 中道 忠和. All rights reserved.
//

#import <UIKit/UIKit.h>
#define N 30 //ボールの数

@interface DodgeBallView : UIView {
    int WIDTH;
    int HEIGHT;
    CGContextRef context;
    NSMutableArray* draw;
    
    CGPoint lastPoint;
    
    float px; // prayer x position
    float py; // prayer y position
    float vx;
    float vy;
    
    struct ball {
        float x;
        float y;
        float vx;
        float vy;
        int   smile;
    };
    
    struct ball b[N];

    int touch_direction; // 0:stop 1:up 2:right 3:down 4:left
    int time;
    int gs;
}

@end

DodgeBallView.m

//
//  DodgeBallView.m
//  DodgeBall
//
//  Created by 中道 忠和 on 2014/01/05.
//  Copyright (c) 2014年 中道 忠和. All rights reserved.
//

#import "DodgeBallView.h"
#define SPEED 1.0f

@implementation DodgeBallView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

-(id)initWithCoder:(NSCoder*)coder {
    self=[super initWithCoder:coder];
    if (self) {
        CGRect bounds=[[UIScreen mainScreen] bounds];
        WIDTH = bounds.size.width;
        HEIGHT= bounds.size.height;
        // 画面の準備
        context=NULL;
        
        // キャラクターの絵を準備
        draw=[NSMutableArray array];                      //配列を設定
        
        [ draw addObject:[UIImage imageNamed:@"kumako01.png"]];//0
        [ draw addObject:[UIImage imageNamed:@"ball.png"]];    //1
        [ draw addObject:[UIImage imageNamed:@"smile.png"]];   //2
        
        // タイマーの準備
        [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
        
        // くまちゃんの準備
        px=160.0f;   //最初のX座標
        py=400.0f; //最初のY座標
        vx=0.0f;   //最初のX座標の移動量
        vy=0.0f;  //最初のY座標の移動量
        
        // ボールの準備
        for (int i=0;i<N; i++) {
            b[i].x=rand()%320;
            b[i].y=rand()%100;
            
            float dist = sqrt((px-b[i].x)*(px-b[i].x)+(py-b[i].y)*(py-b[i].y));
            if (dist==0) dist=5; // distが0の時は次の割り算ができなくなるためその予防
            b[i].vx=(px-b[i].x)/dist*SPEED;
            b[i].vy=(py-b[i].y)/dist*SPEED;
            b[i].smile=rand()%5+1;
        }
        
        // その他変数 初期設定
        touch_direction=0;
        time=0;
        gs=1;
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    // 画面の準備(まあ、呪文のようなものです。アブダカダブラ。)
    if (context!=NULL) {
        CGContextRelease(context);
        context=NULL;
    }
    context=UIGraphicsGetCurrentContext();
    CGContextRetain(context);
    
    // 画面を真っ黒に塗って、全部消す。(それからあとで背景とキャラクターを高速で描くから、アニメーションに見える)
    CGContextSetRGBFillColor(context,0,0,0,1);
    CGContextSetRGBStrokeColor(context,0,0,0,1);
    CGContextFillRect(context,CGRectMake(0,0,WIDTH,HEIGHT));
    
    // iPhone5以降の時は、画面の下にバナーを出すようにする。(もともとiphone4Sの画面サイズでつくってたから、すきまができてしまう)
    if ([[UIScreen mainScreen] bounds].size.height == 568){
        //[[p_bmp objectAtIndex:5] drawAtPoint:(CGPointMake(0,455))];    //バナーを描画
    }
    
  if (gs==1) {
    
    // TEXT
    NSString* s1=[NSString stringWithFormat:@"TIME=%d", time];
    UIFont* font = [UIFont boldSystemFontOfSize:20];
    [s1 drawAtPoint:CGPointMake(100,500) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,[UIColor yellowColor],NSForegroundColorAttributeName,nil]];
    
    // タイムの処理
    time=time+1;

    // くまちゃんの描画
    [[draw objectAtIndex:0] drawAtPoint:(CGPointMake(px,py))];
    
    // くまちゃん移動処理
    // タッチ操作の方向に応じて移動量を代入しておく
    if (touch_direction==1) { vy=-1.0f; vx=0.0f; }
    if (touch_direction==2) { vx= 1.0f; vy=0.0f; }
    if (touch_direction==3) { vy= 1.0f; vx=0.0f; }
    if (touch_direction==4) { vx=-1.0f; vy=0.0f; }
    
    px=px+vx;
    if (px<0.0f) px=0.0f;
    if (px>288.0f) px=288.0f;
    py=py+vy;
    if (py<0.0f) py=0.0f;
    if (py>512.0f) py=512.0f;
    
    // ボール描画
    for (int i=0; i<N; i++) {
        if (b[i].smile==0) {
            [[draw objectAtIndex:2] drawAtPoint:(CGPointMake(b[i].x,b[i].y))];
        } else {
            [[draw objectAtIndex:1] drawAtPoint:(CGPointMake(b[i].x,b[i].y))];
        }
    
        // ボール移動
        b[i].x=b[i].x+b[i].vx;
        b[i].y=b[i].y+b[i].vy;
        
        if (b[i].x <0.0f || b[i].x>320.0f || b[i].y>536.0f) {
            b[i].x=(int)rand()%320;
            b[i].y=0.0f;
            
            float dist = sqrt((px-b[i].x)*(px-b[i].x)+(py-b[i].y)*(py-b[i].y));
            if (dist==0.0f) dist=SPEED; // distが0の時は次の割り算ができなくなるためその予防
            b[i].vx=(px-b[i].x)/dist*SPEED;
            b[i].vy=(py-b[i].y)/dist*SPEED;
        }
    
        // くまちゃんとのぶつかりチェック
        if (((px+15.0f)-(b[i].x+4.0f))*((px+15.0f)-(b[i].x+4.0f))+((py+15.0f)-(b[i].y+4.0f))*((py+15.0f)-(b[i].y+4.0f)) < (8+1)*(8+1)) {
            gs=2;
        }
    }
  } else if (gs==2) {
      // くまちゃんの描画
      [[draw objectAtIndex:0] drawAtPoint:(CGPointMake(px,py))];

      // TEXT
      NSString* s1=[NSString stringWithFormat:@"TIME=%d", time];
      UIFont* font2 = [UIFont boldSystemFontOfSize:20];
      [s1 drawAtPoint:CGPointMake(100,500) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font2, NSFontAttributeName,[UIColor yellowColor],NSForegroundColorAttributeName,nil]];
      
      // TEXT
      NSString* s2=[NSString stringWithFormat:@"アウト〜!"];
      NSString* s3=[NSString stringWithFormat:@"クリックして再開"];
      UIFont* font3 = [UIFont boldSystemFontOfSize:30];
      [s2 drawAtPoint:CGPointMake(100,200) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font3, NSFontAttributeName,[UIColor redColor],NSForegroundColorAttributeName,nil]];
      [s3 drawAtPoint:CGPointMake(40,260) withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font3, NSFontAttributeName,[UIColor redColor],NSForegroundColorAttributeName,nil]];

      if (touch_direction==0) {
        // くまちゃんの準備
        px=160.0f;   //最初のX座標
        py=400.0f; //最初のY座標
        vx=0.0f;   //最初のX座標の移動量
        vy=0.0f;  //最初のY座標の移動量
        // ボールの準備
        for (int i=0;i<N; i++) {
            b[i].x=(int)rand()%320;
            b[i].y=(int)rand()%100;
            float dist = sqrt((px-b[i].x)*(px-b[i].x)+(py-b[i].y)*(py-b[i].y));
            if (dist==0) dist=5; // distが0の時は次の割り算ができなくなるためその予防
            b[i].vx=(px-b[i].x)/dist*SPEED;
            b[i].vy=(py-b[i].y)/dist*SPEED;
            b[i].smile=rand()%5+1;
        }
        // その他変数 初期設定
        touch_direction=0;
        time=0;
        gs=1;
      }
  }
}

// タイマー
-(void)onTick:(NSTimer*)timer {
    [self setNeedsDisplay];
}

// タッチパネル操作
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    lastPoint = [[touches anyObject] locationInView:self.superview];
    if (gs==2) touch_direction=0;
}

-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
  
    // タッチした座標を取得
    CGPoint p=[[touches anyObject] locationInView:self.superview];
 
    // タッチ操作量はX方向とY方向のどちらが多いか絶対値で比較する(lastPointとpの座標を取得する構造がゆえに)
    float temp_vx, temp_vy;
    temp_vx=abs(lastPoint.x-p.x);
    temp_vy=abs(lastPoint.y-p.y);
    
    if (temp_vx > temp_vy) {
        if (lastPoint.x-p.x<0) {
            touch_direction=2;
        } else {
            touch_direction=4;
        }
    } else {
        if (lastPoint.y-p.y<0) {
            touch_direction=3;
        } else {
            touch_direction=1;
        }
    }
    
    // さっき取得したタッチの座標をラストポイントに書き換えておく。
    lastPoint = p;
}

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
}

-(void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
    [self touchesEnded:touches withEvent:event];
}

@end

https://itunes.apple.com/jp/app/kumachanjanpu2/id789138227?mt=8&uo=4&at=10l8JW&ct=hatenablog