前言
最近写了个贪吃蛇小游戏,和各位分享下思路.由于一直做的是iOS方面的工作,所以这次不做iPhone版的了,改做Mac版本.其他无论iPhone还是Mac,代码其实都是基本一致的,只想看iPhone游戏的也可以来看下.
游戏设计
蛇的移动由键盘控制,ASDW来改变蛇的移动方向.这是一个最基本的贪吃蛇游戏,实现了蛇的移动,吃食物.
整个程序主要有2个类,SnakeView类和Snake类,还有2个暂时不重要的Food和SnakeBody类.SnakeView是个视图类,主要的功能就是获得蛇和食物的frame,然后画出来,还有就是接受键盘事件,通知Snake类,这个类主要不涉及游戏的逻辑算法.Snake类是游戏的逻辑类,负责蛇的移动,吃食物,设置食物等等,并且告知SnakeView类关于蛇身的位置信息.Food和SnakeBody类主要是保存蛇身和食物的frame,便于绘画,暂时用处不大,如果游戏需要升级的话,Food类需要添加分数,有效时间等属性.
SnakeView类
键盘事件
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)keyDown: (NSEvent *) event
{
// the key ADWS for change the direction of the snake
NSString *chars = [event characters];
if ([chars isEqualToString:@"s"]) {
[self.snake didMoveToDirection:goDown];
}
if ([chars isEqualToString:@"w"]) {
[self.snake didMoveToDirection:goUp];
}
if ([chars isEqualToString:@"a"]) {
[self.snake didMoveToDirection:goLeft];
}
if ([chars isEqualToString:@"d"]) {
[self.snake didMoveToDirection:goRight];
}
}
在drawRect方法中绘画,获得蛇身和食物的frame,然后使用NSRectFill绘画.
- (void)drawRect:(NSRect)dirtyRect
{
// set body color of the snake to darkGrayColor
[[NSColor darkGrayColor] set];
//get every body of the snake, and draw using NSRectFill
for (int i = 0; i < [self.snake.bodyArray count]; i++) {
SnakeBody *body = [self.snake.bodyArray objectAtIndex:i];
NSRectFill(body.bodyRect);
}
[[NSColor blackColor] set];
NSRectFill(self.snake.theFood.foodRect);
}
游戏循环事件,设置一个NSTimer,每0.3秒执行gamePlay方法.
- (void)gamePlay
{
//move the snake
[self.snake move];
//update the game\'s view
[self setNeedsDisplay:YES];
}
Snake类
一条蛇由N个身体组成,bodyArray变量存储着所以蛇身的位置信息.
移动方法
- (void)move
{
//根据蛇的前进方向,添加一个新的蛇头,然后删掉一个蛇尾
//by the move direction of the snake, add a new snake head, and delete the snake tail
//get snake head X&Y
SnakeBody *headBody = [self.bodyArray objectAtIndex:0];
CGPoint headPoint = headBody.bodyRect.origin;
CGPoint p;
//delete the snake tail
if (!hasEaten) {
[bodyArray removeLastObject];
}else{
hasEaten = NO;
}
//add a new snake head
switch (self.direction) {
case goUp:
p = CGPointMake(headPoint.x , headPoint.y - 10);
break;
case goDown:
p = CGPointMake(headPoint.x , headPoint.y + 10);
break;
case goLeft:
p = CGPointMake(headPoint.x - 10, headPoint.y);
break;
case goRight:
p = CGPointMake(headPoint.x + 10, headPoint.y);
break;
default:
break;
}
SnakeBody *body = [[SnakeBody alloc] initWithX:p.x andY:p.y];
[bodyArray insertObject:body atIndex:0];
[body release];
[self detectSnakeState];
}
游戏状态检测
- (void)detectSnakeState
{
SnakeBody *headBody = [self.bodyArray objectAtIndex:0];
//touch itself,die game over
//touch wall,die game over
if (headBody.bodyRect.origin.x<0||headBody.bodyRect.origin.x>480||headBody.bodyRect.origin.y<0||headBody.bodyRect.origin.y>360) {
[self.delegate SnakeDidDie];
}
//eat food length+1.... (later,maybe add score and raise speed)
if (CGRectEqualToRect(headBody.bodyRect,self.theFood.foodRect)) {
hasEaten = YES;
[self initTheFood];
}
}
游戏是开源的,有兴趣的童鞋可以通过这个链接下载:https://github.com/zhungxd/Snake-Game