python贪吃蛇最简单代码_用pygame写个简单的贪吃蛇游戏

编写游戏无疑是理解面向对象最有效的方法,在学习python面向对象部分的过程中,我尝试写了如下一个简单的贪吃蛇小游戏,作为理解面向对象、事件触发机制、pygame模块的一个途径。OK,废话少说,上代码。

首先介绍页面布局,为了美观,我们把每块蛇的身体定义为14x14像素的矩形,实物为直径14像素的圆。为什么采用14像素这个值呢?因为在身体大小合适的15像素附近,不想用一个奇数导致确定圆心的过程中会有浮点数产生,增加额外的内存消耗。当然您也可以使用16像素balablabla。游戏标题为“Greedy Snake”,窗口大小采用560x560像素,560/14=40,故横向纵向分别可以产生40个贪吃蛇的身体长度。

定义Snake类,包含初始化蛇的位置和蛇移动的初始方向。用一个嵌套列表来存储蛇的身体的位置,初始蛇向右移动,使用复制身体位置的方式移动蛇。

class Snake(object):

"""This is the snake class, including the initializing, body, eat food, and direction to move."""

def __init__(self):

"""Using the random module to create a initial snake. The snake has three parts:

a head, a body, and a tail."""

self.pos_list = [[42, 42]]

self.direction = 'R'

def posList(self):

"Return all the points of the snake."

return self.pos_list

def changeDirection(self, direction):

"Change the direction of the snake."

self.direction = direction

def moveDirection(self):

"Change the points to keep the snake moving in the given direction."

body_length = len(self.pos_list) - 1

while body_length > 0:

self.pos_list[body_length] = deepcopy(self.pos_list[body_length - 1])

body_length -= 1

if self.direction == 'R':

self.pos_list[0][0] += 14

elif self.direction == 'L':

self.pos_list[0][0] -= 14

elif self.direction == 'U':

self.pos_list[0][1] -= 14

elif self.direction == 'D':

self.pos_list[0][1] += 14

def eatFood(self, foodPoint):

"The snake eats a point and add the point to its body."

self.pos_list.insert(0, foodPoint)

然后,是食物这个类。类中包含对于食物坐标的初始值,和更新食物坐标的方法。

class Food(object):

"""Initialize the random coordinate of the food and return it."""

def __init__(self):

x = randint(5, 35) * 14

y = randint(5, 35) * 14

self.food_position = [x, y]

def foodList(self):

"Return the coordinate of the food point."

return self.food_position

def updateFood(self):

"When the food is eaten, update the position of the food."

self.food_position[0] = randint(0, 39) * 14

self.food_position[1] = randint(0, 39) * 14

接下来,定义一个贪吃蛇的函数,在这个函数中编写贪吃蛇移动的逻辑,更新食物坐标,判断蛇是否吃到了食物、是否撞到了墙上。逻辑上,如前所述,窗口大小采用560x560,使用时钟控制每秒钟的画面不超过20帧从而控制游戏的画面感,屏幕底色为白色,食物和蛇均为红色,当贪吃蛇撞到墙或者撞到自身时,绘制一幅底色为褐色、字体为红色的“Game Over!”图案,并等待退出事件,关闭窗口。

def snakeMain():

"The logic to run the game."

pygame.init()

screen = pygame.display.set_mode((560, 560), 0, 32)

pygame.display.set_caption("Greedy Snake")

clock = pygame.time.Clock()

snake = Snake()

food = Food()

direction_flag = 'R'

while True:

screen.fill((255, 255, 255))

for event in pygame.event.get():

if event.type == QUIT:

exit()

if event.type == KEYDOWN:

if event.key == K_RIGHT:

direction_flag = 'R'

elif event.key == K_LEFT:

direction_flag = 'L'

elif event.key == K_UP:

direction_flag = 'U'

elif event.key == K_DOWN:

direction_flag = 'D'

# Draw the food and the snake

food_position = deepcopy(food.foodList())

food_position[0] += 7

food_position[1] += 7

pygame.draw.circle(screen, (255, 0, 0), food_position, 10)

snake_position = snake.posList()

for pos in snake_position:

temp_rect = pygame.Rect(pos[0], pos[1], 14, 14)

pygame.draw.rect(screen, (255, 0, 0), temp_rect)

pygame.display.update()

# 20 frame of pictures per second

# and move the snake

frame_rate = clock.tick(20)

snake.changeDirection(direction_flag)

snake.moveDirection()

#Judge whether the snake eats a food or not

food_position = deepcopy(food.foodList())

snake_head = deepcopy(snake.posList()[0])

if direction_flag == 'R':

snake_head[0] += 14

elif direction_flag == 'L':

snake_head[0] -= 14

elif direction_flag == 'U':

snake_head[1] -= 14

elif direction_flag == 'D':

snake_head[1] += 14

if snake_head == food_position:

snake.eatFood(food_position)

food.updateFood()

# Judge whether the snake gets a collision or not

gameover_flag = False

snake_position = snake.posList()

snake_head = snake_position[0]

if direction_flag == 'R':

if snake_head[0] > 546:

gameover_flag = True

elif direction_flag == 'L':

if snake_head[0] < 0:

gameover_flag = True

elif direction_flag == 'U':

if snake_head[1] < 0:

gameover_flag = True

elif direction_flag == 'D':

if snake_head[1] > 546:

gameover_flag = True

for pos in range(1, len(snake_position) - 1):

if snake_head == snake_position[pos]:

gameover_flag = True

if gameover_flag:

pygame.font.init()

screen.fill((100, 0, 0))

font = pygame.font.SysFont("arial", 32)

text = font.render("Game Over!", True, (255, 0, 0))

screen.blit(text, (260, 260))

pygame.display.update()

while True:

again_event = pygame.event.poll()

if again_event.type == QUIT:

exit()

最后,判断是否在当前命名空间中执行该主体函数,如果是,则执行贪吃蛇游戏。

if __name__ == '__main__':

snakeMain()

总体来说,这是一个非常简单的贪吃蛇版本,逻辑上还需要继续完善,bug还需要修复。在接下来的修改过程中,我会将它转变成1个像素1个像素之间的移动,而不再将窗口分割成多个矩形,这样可以增加蛇移动的流畅度。另一方面,方向移动方面,向前移动不会再接受向后移动的事件,向左或向右类似,很简单,通过if判断就可以实现。蛇体要采用三幅图像载入,让蛇头、蛇身、蛇尾更美观逼真。加入游戏声音之后,可玩性更强。在标题栏下方增加一个类似扫雷游戏的记分机制,使贪吃蛇能够记录该游戏的得分最高值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值