13 Star 73 Fork 10

Simki / Adapted-game-GreedyErha

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
snake.py 22.18 KB
一键复制 编辑 原始数据 按行查看 历史
Simki 提交于 2020-08-05 17:13 . BGM + sound+ delete
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
## 导入相关模块
import random
import pygame
import sys
from pygame.locals import *
import datetime
windows_width = 800
windows_height = 600 # 游戏窗口的大小
cell_size = 20 # 贪吃蛇身体方块大小,注意身体大小必须能被窗口长宽整除
''' #初始化区
由于我们的贪吃蛇是有大小尺寸的, 因此地图的实际尺寸是相对于贪吃蛇的大小尺寸而言的
'''
map_width = int(windows_width / cell_size)
map_height = int(windows_height / cell_size)
# 颜色定义
white = (255, 255, 255)
black = (0, 0, 0)
gray = (230, 230, 230)
dark_gray = (40, 40, 40)
DARKGreen = (0, 155, 0)
Green = (0, 255, 0)
Red = (255, 0, 0)
blue = (0, 0, 255)
dark_blue = (0, 0, 139)
FOOD_color = [(10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))] # 食物颜色
FOOD_IMG = ['img/gt4.jpg', 'img/gt3.jpg', 'img/gt2.jpg', 'img/gt1.jpg']
BG_COLOR = black # 游戏背景颜色
# BGM
# BGM = pygame.mixer.Sound("bjm1.wav")
# 定义方向
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
HEAD = 0 # 贪吃蛇头部下标
score_add = [] # 排名
max_score = 0 # 最高分数
buff = 0 # 隐分身加成时间
mirror = 0 # 镜像加成时间
buff_list = [] # 道具
has_gate = False
bomb_list = [] # 炸弹
def running_game(screen, snake_speed_clock, num):
global has_gate
has_gate = False
change_speed = 0 # 定义改变速度
start_speed = 2 # 贪吃蛇的原始速度+2
startx = random.randint(20, map_width - 20) # 开始位置
starty = random.randint(10, map_height - 10)
snake_coords = [{'x': startx, 'y': starty}, # 初始贪吃蛇
{'x': startx - 1, 'y': starty},
{'x': startx - 2, 'y': starty}]
direction = RIGHT # 开始时向右移动
food = get_random_location() # 食物随机位置
gate = get_random_location() # 传送门随机位置
sep = get_random_location() # 隐分身道具随机位置
bomb = get_random_location() # 炸弹随机位置
global buff
global mirror
global buff_list
global bomb_list
bomb_list = []
buff_list = []
buff = 0
mirror = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN: # and 判断是否输入了反方向
if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT and mirror == 0:
direction = LEFT
elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT and mirror == 0:
direction = RIGHT
elif (event.key == K_UP or event.key == K_w) and direction != DOWN and mirror == 0:
direction = UP
elif (event.key == K_DOWN or event.key == K_s) and direction != UP and mirror == 0:
direction = DOWN
# 镜像方向
if (event.key == K_LEFT or event.key == K_a) and direction != LEFT and mirror > 0:
direction = RIGHT
elif (event.key == K_RIGHT or event.key == K_d) and direction != RIGHT and mirror > 0:
direction = LEFT
elif (event.key == K_UP or event.key == K_w) and direction != UP and mirror > 0:
direction = DOWN
elif (event.key == K_DOWN or event.key == K_s) and direction != DOWN and mirror > 0:
direction = UP
elif event.key == K_SPACE:
pause(screen)
elif event.key == K_ESCAPE:
terminate()
elif event.key == K_1: # 按“1”加速,加速不超过20
if change_speed < 20:
change_speed += 1
elif event.key == K_2: # 按“2”减速,减速数不能超过加速5,且不能低于当前长度最低数字
if change_speed > -5 and len(snake_coords) > 8:
change_speed -= 1
move_snake(direction, snake_coords) # 移动蛇
ret = snake_is_alive(snake_coords)
if not ret:
break # 蛇跪了. 游戏结束
# 控制速度
if len(snake_coords) < 40:
snake_speed = change_speed + len(snake_coords) // 2 + start_speed
draw_speed(screen, change_speed + len(snake_coords) // 2 + start_speed)
pygame.display.update()
else:
snake_speed = 10 # 长度到达40时,若一直按减速,则看到速度最小为10
draw_speed(screen, 10)
pygame.display.update()
snake_speed_clock.tick(snake_speed)
snake_is_eat_food(snake_coords, food) # 判断蛇是否吃到食物
screen.fill(BG_COLOR)
if has_gate:
snake_is_eat_food2(snake_coords, gate, screen, direction) # 判断蛇是否吃到传送门
if len(buff_list) > 0:
snake_is_eat_buff(snake_coords, buff_list, direction) # 判断蛇是否吃到道具
draw_buff(screen, buff_list)
if len(bomb_list) > 0:
draw_bomb(screen, bomb_list)
draw_grid(screen)
draw_snake(screen, snake_coords)
# 倒计时
if buff > 0:
buff -= 1
draw_snake_copy(screen, snake_coords)
draw_time(screen, buff, 0)
if mirror > 0:
mirror -= 1
draw_time(screen, mirror, 1)
r = random.randint(0, snake_speed * 5 + 1)
draw_food(screen, food)
if has_gate or r == 3:
draw_gate(screen, gate)
if r == 1:
buff_list.append(sep)
sep = get_random_location() # 道具随机位置
if r == 2:
bomb_list.append(bomb)
bomb = get_random_location() # 炸弹随机位置
draw_score(screen, len(snake_coords) - 3)
pygame.display.update()
# 控制速度
if len(snake_coords) < 40:
snake_speed = change_speed + len(snake_coords) // 2 + start_speed
draw_speed(screen, change_speed + len(snake_coords) // 2 + start_speed)
pygame.display.update()
else:
snake_speed = 10 # 长度到达40时,若一直按减速,则看到速度最小为10
draw_speed(screen, 10)
pygame.display.update()
snake_speed_clock.tick(snake_speed)
keep_rangking(len(snake_coords) - 4, num)
show_gameover_info(screen, len(snake_coords) - 4, num)
# 将食物画出来
def draw_food(screen, food):
x = food['x'] * cell_size
y = food['y'] * cell_size
appleRect = pygame.Rect(x, y, cell_size, cell_size)
sk = pygame.image.load(FOOD_IMG[random.randint(0, 1)]).convert()
screen.blit(sk, appleRect)
# 画传送门
def draw_gate(screen, food):
global has_gate
has_gate = True
x = food['x'] * cell_size
y = food['y'] * cell_size
sk = pygame.image.load('img/gate.jpg').convert()
appleRect = pygame.Rect(x, y, cell_size, cell_size)
screen.blit(sk, appleRect)
# 画道具
def draw_buff(screen, buffS):
for bu in buffS:
x = bu['x'] * cell_size
y = bu['y'] * cell_size
sk = pygame.image.load('img/buff.jpg').convert()
appleRect = pygame.Rect(x, y, cell_size, cell_size)
screen.blit(sk, appleRect)
# 画炸弹
def draw_bomb(screen, bombS):
for bo in bombS:
x = bo['x'] * cell_size
y = bo['y'] * cell_size
sk = pygame.image.load('img/bomb.jpg').convert()
appleRect = pygame.Rect(x, y, cell_size, cell_size)
screen.blit(sk, appleRect)
# 将贪吃蛇画出来
def draw_snake(screen, snake_coords):
# 头
xh = snake_coords[0]['x'] * cell_size
yh = snake_coords[0]['y'] * cell_size
sk = pygame.image.load('img/head1.jpg')
wormSegmentRect = pygame.Rect(xh, yh, cell_size, cell_size)
screen.blit(sk, wormSegmentRect)
for coord in snake_coords[1:]:
x = coord['x'] * cell_size
y = coord['y'] * cell_size
if mirror > 0:
sk = pygame.image.load('img/mir.jpg')
else:
sk = pygame.image.load('img/timg.jpg')
wormSegmentRect = pygame.Rect(x, y, cell_size, cell_size)
screen.blit(sk, wormSegmentRect)
# 画影分身
def draw_snake_copy(screen, snake_coords):
# 头
xh = windows_width - snake_coords[0]['x'] * cell_size
yh = windows_height - snake_coords[0]['y'] * cell_size
sk = pygame.image.load('img/head1.jpg')
wormSegmentRect = pygame.Rect(xh, yh, cell_size, cell_size)
screen.blit(sk, wormSegmentRect)
for coord in snake_coords[1:]:
x = windows_width - coord['x'] * cell_size
y = windows_height - coord['y'] * cell_size
sk = pygame.image.load('img/timg.jpg')
wormSegmentRect = pygame.Rect(x, y, cell_size, cell_size)
screen.blit(sk, wormSegmentRect)
# 传送门蛇位置处理
def draw_Gate(screen, snake_coords, direction):
if direction == LEFT or direction == UP:
x = random.randint(1, map_width - snake_coords[len(snake_coords) - 1]['x'])
y = random.randint(1, map_height - snake_coords[len(snake_coords) - 1]['y'])
if direction == RIGHT:
x = random.randint(1, map_width - snake_coords[0]['x'])
y = random.randint(1, map_height - snake_coords[len(snake_coords) - 1]['y'])
if direction == DOWN:
x = random.randint(1, map_width - snake_coords[len(snake_coords) - 1]['x'])
y = random.randint(1, map_height - snake_coords[0]['y'])
for coord in snake_coords:
coord['x'] = coord['x'] + x
coord['y'] = coord['y'] + y
# 画网格
def draw_grid(screen):
for x in range(0, windows_width, cell_size): # draw 水平 lines
pygame.draw.line(screen, dark_gray, (x, 0), (x, windows_height))
for y in range(0, windows_height, cell_size): # draw 垂直 lines
pygame.draw.line(screen, dark_gray, (0, y), (windows_width, y))
# 移动贪吃蛇
def move_snake(direction, snake_coords):
if direction == UP:
newHead = {'x': snake_coords[HEAD]['x'], 'y': snake_coords[HEAD]['y'] - 1}
elif direction == DOWN:
newHead = {'x': snake_coords[HEAD]['x'], 'y': snake_coords[HEAD]['y'] + 1}
elif direction == LEFT:
newHead = {'x': snake_coords[HEAD]['x'] - 1, 'y': snake_coords[HEAD]['y']}
elif direction == RIGHT:
newHead = {'x': snake_coords[HEAD]['x'] + 1, 'y': snake_coords[HEAD]['y']}
snake_coords.insert(0, newHead)
# 吃道具音效
def eat_sound():
sound = pygame.mixer.Sound("music/eat.wav")
sound.play()
# 判断蛇死了没
def snake_is_alive(snake_coords):
tag = True
if snake_coords[HEAD]['x'] == -1 or snake_coords[HEAD]['x'] == map_width or snake_coords[HEAD]['y'] == -1 or \
snake_coords[HEAD]['y'] == map_height:
tag = False # 蛇碰壁啦
for snake_body in snake_coords[1:]:
if snake_body['x'] == snake_coords[HEAD]['x'] and snake_body['y'] == snake_coords[HEAD]['y']:
tag = False # 蛇碰到自己身体啦
for bomb in bomb_list:
if bomb['x'] == snake_coords[HEAD]['x'] and bomb['y'] == snake_coords[HEAD]['y']:
tag = False # 蛇碰到炸弹啦
if buff > 0:
xh = map_width - snake_coords[HEAD]['x']
yh = map_height - snake_coords[HEAD]['y']
if bomb['x'] == xh and bomb['y'] == yh:
tag = False # 影子碰到炸弹啦
return tag
# 判断贪吃蛇是否吃到食物
def snake_is_eat_food(snake_coords, food): # 如果是列表或字典,那么函数内修改参数内容,就会影响到函数体外的对象。
xh = map_width - snake_coords[HEAD]['x']
yh = map_height - snake_coords[HEAD]['y']
if snake_coords[HEAD]['x'] == food['x'] and snake_coords[HEAD]['y'] == food['y']:
eat_sound()
food['x'] = random.randint(0, map_width - 1)
food['y'] = random.randint(0, map_height - 1) # 实物位置重新设置
# 判断分身是否吃到食物
elif buff > 0 and xh == food['x'] and yh == food['y']:
eat_sound()
food['x'] = random.randint(0, map_width - 1)
food['y'] = random.randint(0, map_height - 1) # 实物位置重新设置
else:
del snake_coords[-1] # 如果没有吃到实物, 就向前移动, 那么尾部一格删掉
# 判断贪吃蛇是否吃到道具
def snake_is_eat_buff(snake_coords, buffs, direction):
global buff
global mirror
global bomb_list
for bu in buffs:
if snake_coords[HEAD]['x'] == bu['x'] and snake_coords[HEAD]['y'] == bu['y']:
# 随机道具效果
eat_sound()
r = random.randint(0, 2)
if r == 0:
buff += 30
buffs.remove(bu)
add_snake(snake_coords, 3, direction)
return
elif r == 1:
mirror += 30
buffs.remove(bu)
add_snake(snake_coords, 3, direction)
return
elif r == 2:
bomb_list = []
add_snake(snake_coords, 3, direction)
return
if buff > 0:
xh = map_width - snake_coords[HEAD]['x']
yh = map_height - snake_coords[HEAD]['y']
if xh == bu['x'] and yh == bu['y']:
eat_sound()
# 影子吃到道具
r = random.randint(0, 2)
if r == 0:
buff += 30
buffs.remove(bu)
add_snake(snake_coords, 3, direction)
return
elif r == 1:
mirror += 30
buffs.remove(bu)
add_snake(snake_coords, 3, direction)
return
elif r == 2:
bomb_list = []
add_snake(snake_coords, 3, direction)
return
return
# 判断贪吃蛇是否吃到传送门
def snake_is_eat_food2(snake_coords, food, screen, direction): # 如果是列表或字典,那么函数内修改参数内容,就会影响到函数体外的对象。
global has_gate
if snake_coords[HEAD]['x'] == food['x'] and snake_coords[HEAD]['y'] == food['y']:
eat_sound()
has_gate = False
food['x'] = random.randint(0, map_width - 1)
food['y'] = random.randint(0, map_height - 1) # 实物位置重新设置
draw_Gate(screen, snake_coords, direction)
add_snake(snake_coords, 2, direction)
xh = map_width - snake_coords[HEAD]['x']
yh = map_height - snake_coords[HEAD]['y']
# 判断分身是否吃到传送门
if buff > 0 and xh == food['x'] and yh == food['y']:
eat_sound()
has_gate = False
food['x'] = random.randint(0, map_width - 1)
food['y'] = random.randint(0, map_height - 1) # 实物位置重新设置
draw_Gate(screen, snake_coords, direction)
add_snake(snake_coords, 2, direction)
else:
return
# del snake_coords[-1] # 如果没有吃到实物, 就向前移动, 那么尾部一格删掉
# 食物随机生成
def get_random_location():
return {'x': random.randint(2, map_width - 2), 'y': random.randint(6, map_height - 2)}
# 开始信息显示
def show_start_info(screen):
font1 = pygame.font.Font('ttf/myfont.ttf', 80)
tip1 = font1.render('贪吃的二哈', True, (255, 0, 0))
font = pygame.font.Font('ttf/myfont.ttf', 40)
tip = font.render('按任意键开始游戏', True, (255, 0, 0))
gamestart = pygame.image.load('img/s_2.jpg').convert() # 图片自适应设置
screen.blit(gamestart, (0, 0))
screen.blit(tip1, (360, 90))
screen.blit(tip, (330, 260))
pygame.display.update()
while True: # 键盘监听事件
for event in pygame.event.get(): # event handling loop
if event.type == QUIT:
terminate() # 终止程序
elif event.type == KEYDOWN:
if (event.key == K_ESCAPE): # 终止程序
terminate() # 终止程序
elif event.key == K_SPACE:
pause = True
pygame.quit()
quit()
else:
return # 结束此函数, 开始游戏
# 游戏结束信息显示
def show_gameover_info(screen, score, num):
font = pygame.font.Font('ttf/myfont.ttf', 30)
font2 = pygame.font.Font('ttf/myfont.ttf', 40)
tip = font.render('按Q或者ESC退出游戏, 按3可以查看排行榜', True, (255, 255, 0))
tip2 = font2.render('按任意键重新开始游戏', True, (255, 0, 255))
# 创建一个和串窗口一样大小的图片
start = pygame.image.load('img/o2.jpg')
pygame.mixer.music.stop()
sound = pygame.mixer.Sound("music/over.wav")
sound.play()
# 设定显示的背景图和位置
screen.blit(start, (100, 100))
screen.blit(tip, (140, 450))
screen.blit(tip2, (200, 500))
pygame.display.update()
while True: # 键盘监听事件
for event in pygame.event.get(): # event handling loop
if event.type == QUIT:
terminate() # 终止程序
elif event.type == KEYDOWN:
if event.key == K_ESCAPE or event.key == K_q: # 终止程序
terminate() # 终止程序
elif event.key == K_3: # 排名
show_ranking(screen, score, num)
pygame.display.update()
else:
pygame.mixer.music.play()
return # 结束此函数, 重新开始游戏
# 画成绩
def draw_score(screen, score):
font = pygame.font.Font('ttf/myfont.ttf', 30)
scoreSurf = font.render('得分: %s' % score, True, Green)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 120, 10)
screen.blit(scoreSurf, scoreRect)
scoreSurf2 = font.render('最高分数: %s' % max_score, True, Green)
scoreRect2 = scoreSurf.get_rect()
scoreRect2.topleft = (windows_width - 160, 40)
screen.blit(scoreSurf2, scoreRect2)
# 画倒计时
def draw_time(screen, count, type):
font = pygame.font.Font('ttf/myfont.ttf', 30)
if type == 0: # 隐分身
scoreSurf = font.render('分身模式时间剩余:%s' % count, True, Red)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 400, 70)
elif type == 1: # 镜像
scoreSurf = font.render('镜像模式时间剩余:%s' % count, True, Red)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 400, 100)
elif type == 2:
scoreSurf = font.render(': %s' % count, True, Red)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 120, 10)
screen.blit(scoreSurf, scoreRect)
# 画速度
def draw_speed(screen, speed):
font = pygame.font.Font('ttf/myfont.ttf', 30)
speedSurf = font.render('速度: %s' % speed, True, Green)
speedRect = speedSurf.get_rect()
speedRect.topleft = (windows_width - 790, 10)
screen.blit(speedSurf, speedRect)
def add_snake(snake_coords, count, direction):
hx = snake_coords[0]['x']
hy = snake_coords[0]['y']
if direction == LEFT:
for i in range(0, count):
snake_coords.insert(len(snake_coords), {'x': hx + 1 + i, 'y': hy})
return
if direction == RIGHT:
for i in range(0, count):
snake_coords.insert(len(snake_coords), {'x': hx - 1 - i, 'y': hy})
return
if direction == UP:
for i in range(0, count):
snake_coords.insert(len(snake_coords), {'x': hx, 'y': hy + 1 + i})
return
if direction == DOWN:
for i in range(0, count):
snake_coords.insert(len(snake_coords), {'x': hx, 'y': hy - 1 - i})
return
# 保存排名
def keep_rangking(score, num):
global max_score
if score > max_score:
max_score = score
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
score_list = {}
score_list['次数'] = num
score_list['分数'] = score
score_list['时间'] = now
global score_add
score_add.append(score_list)
# 排序
score_add.sort(key=takeSecond)
print(score_add)
# 获取列表的分数
def takeSecond(elem):
return elem['分数']
# 排名
def show_ranking(screen, score, num):
rang = pygame.image.load('img/ph1.jpg')
screen.blit(rang, (0, 0))
font = pygame.font.Font('ttf/myfont.ttf', 30)
scoreSurf = font.render('%s' % '排名 ' + '分数' + " " + '时间', True, Green)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 620, 180)
screen.blit(scoreSurf, scoreRect)
for i in range(num):
show_ranking_text(screen, i)
def show_ranking_text(screen, i):
font = pygame.font.Font('ttf/myfont.ttf', 30)
scoreSurf = font.render(
'%s' % str(i + 1) + ' ' + str(score_add[len(score_add) - i - 1]['分数']) + " " + (
score_add[len(score_add) - i - 1]['时间']), True, Green)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 620, 220 + (i * 50))
screen.blit(scoreSurf, scoreRect)
# 程序暂停
def pause(screen):
pygame.mixer.music.stop()
font = pygame.font.Font('ttf/myfont.ttf', 40)
tem = font.render('游戏暂停, 按“空格”键继续游戏~', True, (255, 255, 0))
font2 = pygame.font.Font('ttf/myfont.ttf', 20)
tem2 = font2.render('提示:按1可以加速,按2可以减速哟', True, Green)
screen.blit(tem, (150, 260))
screen.blit(tem2, (200, 360))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
elif event.type == pygame.KEYDOWN:
if event.key == K_SPACE:
pygame.mixer.music.play()
return
# 程序终止
def terminate():
pygame.quit()
sys.exit()
# 主函数
def main():
pygame.init() # 模块初始化
snake_speed_clock = pygame.time.Clock() # 创建Pygame时钟对象
screen = pygame.display.set_mode((windows_width, windows_height), 0, 32) #
screen.fill(white)
pygame.display.set_caption("Jixq 贪吃的二哈") # 设置标题
show_start_info(screen) # 欢迎信息
# BGM
pygame.mixer.init()
pygame.mixer.music.load("music/bjm1.wav")
pygame.mixer.music.play()
num = 0
while True:
num += 1
running_game(screen, snake_speed_clock, num)
if __name__ == '__main__':
main()
Python
1
https://gitee.com/jixq/Adapted-game-GreedyErha.git
git@gitee.com:jixq/Adapted-game-GreedyErha.git
jixq
Adapted-game-GreedyErha
Adapted-game-GreedyErha
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891