一个简单的Mac贪吃蛇小游戏开发笔记,设计,算法等等.

时间:2024-02-16 15:40:12

前言

最近写了个贪吃蛇小游戏,和各位分享下思路.由于一直做的是iOS方面的工作,所以这次不做iPhone版的了,改做Mac版本.其他无论iPhone还是Mac,代码其实都是基本一致的,只想看iPhone游戏的也可以来看下.

 

游戏设计

蛇的移动由键盘控制,ASDW来改变蛇的移动方向.这是一个最基本的贪吃蛇游戏,实现了蛇的移动,吃食物.

整个程序主要有2个类,SnakeView类和Snake,还有2个暂时不重要的FoodSnakeBody.SnakeView是个视图类,主要的功能就是获得蛇和食物的frame,然后画出来,还有就是接受键盘事件,通知Snake,这个类主要不涉及游戏的逻辑算法.Snake类是游戏的逻辑类,负责蛇的移动,吃食物,设置食物等等,并且告知SnakeView类关于蛇身的位置信息.FoodSnakeBody类主要是保存蛇身和食物的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