3237浏览
查看: 3237|回复: 5

[M10项目] 行空板+空中飞鼠键盘 飞机大战

[复制链接]
本帖最后由 云天 于 2023-9-17 13:31 编辑

【项目背景】
行空板+空中飞鼠键盘 飞机大战图1


最近在DF商城上看到“空中飞鼠键盘”,它连到行空板上时,您不需安装任何驱动,只需把它插上去,就能立即使用了。它使用了2.4G无线传输技术,传输距离可达30米。无论是在客厅还是办公室,您都可使用它进行远程遥控。
【项目设计】
使用行空板结合“空中飞鼠键盘”,利用“PYgame库”,制作多个使用键盘控制的行空板小游戏。

行空板+空中飞鼠键盘 飞机大战图2

俄罗斯方块

行空板+空中飞鼠键盘 飞机大战图4

贪吃蛇


行空板+空中飞鼠键盘 飞机大战图3


飞机大战

【演示视频】


【飞机大战】

这次用Mind+软件Python模式下,连接终端行空板,利用Python中的pygame模块来完成一个飞机大战的小游戏;基本思路是通过方向键来控制飞机的左右移动射击飞船。
创建一个可以左右移动的小飞机,用户可以通过空格space键来控制飞机发射子弹
1.创建背景,加载角色
  1. import pygame
  2. import random
  3. import time
  4. # 定义窗口的大小
  5. WINDOW_WIDTH = 240
  6. WINDOW_HEIGHT = 320
  7. # 初始化 Pygame
  8. pygame.init()
  9. # 创建窗口 设置屏幕的分辨率
  10. window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
  11. pygame.display.set_caption('Plane Fight')
  12. # 加载角色图片
  13. background_image = pygame.image.load('background.png')
  14. player_image = pygame.image.load('player.png')
  15. enemy_image = pygame.image.load('enemy.png')
  16. bullet_image = pygame.image.load('bullet.png')
  17. # 定义颜色
  18. BLACK = (0, 0, 0)
  19. WHITE = (255, 255, 255)
  20. RED = (255, 0, 0)
  21. # 定义字体
  22. font = pygame.font.Font(None, 36)
复制代码

2.主循环体中,实现键盘控制
  1. while not game_over:
  2.     # 处理事件
  3.     for event in pygame.event.get():
  4.         if event.type == pygame.QUIT:
  5.             game_over = True
  6.         
  7.         elif event.type == pygame.KEYDOWN:
  8.             if event.key == pygame.K_RIGHT:
  9.                 # 当用户按下键位时标志位为True
  10.                 player.mv_right = True
  11.             elif event.key == pygame.K_LEFT:
  12.                 player.mv_left = True
  13.             if event.key == pygame.K_SPACE:#用户按下空格之后会创建一个子弹
  14.                
  15.                    player.mv_shoot = True
  16.                
  17.         elif event.type == pygame.KEYUP:
  18.             if event.key == pygame.K_RIGHT:
  19.                 # 当用户松开键位为false
  20.                 player.mv_right = False
  21.             elif event.key == pygame.K_LEFT:
  22.                 player.mv_left = False   
  23.             if event.key == pygame.K_SPACE:
  24.                
  25.                 player.mv_shoot = False
  26.             
复制代码

3.绘制小飞机玩家

定义一个Player类,来存储飞机的各种行为。
  1. # 定义玩家类
  2. class Player(pygame.sprite.Sprite):
  3.     def __init__(self):
  4.         super().__init__()
  5.         self.image = player_image
  6.         self.rect = self.image.get_rect()
  7.         self.rect.centerx = WINDOW_WIDTH // 2
  8.         self.rect.bottom = WINDOW_HEIGHT - 10
  9.         self.speed = 5
  10.         self.mv_right = False
  11.         self.mv_left = False
  12.         self.mv_shoot= False
  13.         self.Bullet_num=10
  14.         self.shoot_speed=1
  15.         self.last_shoot_time=time.time()
  16.     # 移动
  17.     # 定义一个调整小飞机位置的方法
  18.     def update(self):
  19.         # 根据标志位的调整小飞机的位置
  20.         #实现左右移动,控制小飞机持续移动
  21.         if self.mv_right:
  22.             self.rect.centerx += self.speed
  23.         if self.mv_left:
  24.             self.rect.centerx -= self.speed
  25.         if self.rect.left < 0:
  26.             self.rect.left = 0
  27.         elif self.rect.right > WINDOW_WIDTH:#限制小飞机的活动范围
  28.             self.rect.right = WINDOW_WIDTH
  29.         if self.mv_shoot:
  30.                 curTime_shoot = time.time()
  31.                 if curTime_shoot-self.last_shoot_time>self.shoot_speed:#限制子弹发射频率
  32.                    self.last_shoot_time = time.time()
  33.                    player.shoot()
  34.     # 射击
  35.     def shoot(self):
  36.         bullet = Bullet(self.rect.centerx, self.rect.top)
  37.         all_sprites.add(bullet)
  38.         bullets.add(bullet)
复制代码
  1. # 创建精灵组
  2. all_sprites = pygame.sprite.Group()
  3. enemies = pygame.sprite.Group()
  4. bullets = pygame.sprite.Group()
  5. # 创建玩家并添加到精灵组
  6. player = Player()
  7. all_sprites.add(player)
复制代码

4.完成射击功能
通过玩家按下空格来发射子弹
  1. # 定义子弹类
  2. class Bullet(pygame.sprite.Sprite):
  3.     def __init__(self, x, y):
  4.         super().__init__()
  5.         self.image = bullet_image
  6.         self.rect = self.image.get_rect()
  7.         self.rect.centerx = x
  8.         self.rect.bottom = y
  9.         self.speed = -10
  10.     # 移动
  11.     def update(self):
  12.         self.rect.y += self.speed
  13.         if self.rect.bottom < 0:#删除已经消失的子弹
  14.             self.kill()
复制代码

5.制作飞船
现在小飞机也创建完成了,现在就该创建小飞机的敌人了,同样通过一个类来控制其所有行为。

  1. # 定义敌机类
  2. class Enemy(pygame.sprite.Sprite):
  3.     def __init__(self):
  4.         super().__init__()
  5.         self.image = enemy_image
  6.         self.rect = self.image.get_rect()
  7.         self.rect.x = random.randint(0, WINDOW_WIDTH - self.rect.width)
  8.         self.rect.y = random.randint(-100, -self.rect.height)
  9.         self.speed = random.randint(1, 2)
  10.     # 移动
  11.     def update(self):
  12.         self.rect.y += self.speed
  13.         if self.rect.top > WINDOW_HEIGHT:
  14.             self.kill()
复制代码

玩家小飞机可以射杀飞船、当飞船碰到小飞机GAMEOVER,飞船碰到地面也GAMEOVER

  1.     # 生成敌机
  2.     curTime = time.time()
  3.      
  4.     if len(enemies) < 10 and curTime - last_move_time>random.randint(3,enemy_speed+3):
  5.         print(enemy_speed)
  6.         last_move_time=time.time()
  7.         enemy = Enemy()
  8.         all_sprites.add(enemy)
  9.         enemies.add(enemy)
  10.     # 检测子弹是否击中敌机
  11.     hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
  12.     for hit in hits:
  13.         score += 10
  14.     #随得分增加,加大敌机生成频率和生成子弹频率
  15.     if score<1000:
  16.       enemy_speed=10-int(score/100)
  17.       player.shoot_speed=1-int(score/100)/10
  18.     else:
  19.       enemy_speed=1
  20.       player.shoot_speed=0.1
  21.     # 检测敌机是否撞击玩家
  22.     hits = pygame.sprite.spritecollide(player, enemies, False)
  23.     if len(hits) > 0:
  24.         game_over = True
复制代码
6.更新角色游戏状态

  1.     # 更新游戏状态
  2.     all_sprites.update()
  3.     # 清屏
  4.     window.fill(BLACK)
  5.     # 绘制背景
  6.     window.blit(background_image, (0, 0))
  7.     # 绘制精灵组中的所有元素
  8.     all_sprites.draw(window)
  9.     # 显示得分
  10.     score_text = font.render(f'Score: {score}', True, WHITE)
  11.     window.blit(score_text, (10, 10))
  12.    
  13.     # 更新屏幕
  14.     pygame.display.flip()
  15.     # 控制帧率
  16.     clock.tick(60)
复制代码
7.游戏结束
  1. # 游戏结束,显示最终得分
  2. game_over_text = font.render('Game Over', True, RED)
  3. score_text = font.render(f'Final Score: {score}', True, WHITE)
  4. window.blit(game_over_text, (WINDOW_WIDTH // 2 - game_over_text.get_width() // 2, WINDOW_HEIGHT // 2 - game_over_text.get_height() // 2 - 30))
  5. window.blit(score_text, (WINDOW_WIDTH // 2 - score_text.get_width() // 2, WINDOW_HEIGHT // 2 - score_text.get_height() // 2 + 30))
  6. pygame.display.flip()
  7. # 等待 10 秒后关闭窗口
  8. pygame.time.wait(10000)
  9. pygame.quit()
复制代码

8.完整代码
  1. import pygame
  2. import random
  3. import time
  4. # 定义窗口的大小
  5. WINDOW_WIDTH = 240
  6. WINDOW_HEIGHT = 320
  7. # 初始化 Pygame
  8. pygame.init()
  9. # 创建窗口 设置屏幕的分辨率
  10. window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
  11. pygame.display.set_caption('Plane Fight')
  12. # 加载角色图片
  13. background_image = pygame.image.load('background.png')
  14. player_image = pygame.image.load('player.png')
  15. enemy_image = pygame.image.load('enemy.png')
  16. bullet_image = pygame.image.load('bullet.png')
  17. # 定义颜色
  18. BLACK = (0, 0, 0)
  19. WHITE = (255, 255, 255)
  20. RED = (255, 0, 0)
  21. # 定义字体
  22. font = pygame.font.Font(None, 36)
  23. # 定义玩家类
  24. class Player(pygame.sprite.Sprite):
  25.     def __init__(self):
  26.         super().__init__()
  27.         self.image = player_image
  28.         self.rect = self.image.get_rect()
  29.         self.rect.centerx = WINDOW_WIDTH // 2
  30.         self.rect.bottom = WINDOW_HEIGHT - 10
  31.         self.speed = 5
  32.         self.mv_right = False
  33.         self.mv_left = False
  34.         self.mv_shoot= False
  35.         self.Bullet_num=10
  36.         self.shoot_speed=1
  37.         self.last_shoot_time=time.time()
  38.     # 移动
  39.     # 定义一个调整小飞机位置的方法
  40.     def update(self):
  41.         # 根据标志位的调整小飞机的位置
  42.         
  43.         if self.mv_right:
  44.             self.rect.centerx += self.speed
  45.         if self.mv_left:
  46.             self.rect.centerx -= self.speed
  47.         if self.rect.left < 0:
  48.             self.rect.left = 0
  49.         elif self.rect.right > WINDOW_WIDTH:
  50.             self.rect.right = WINDOW_WIDTH
  51.         if self.mv_shoot:
  52.                 curTime_shoot = time.time()
  53.                 if curTime_shoot-self.last_shoot_time>self.shoot_speed:
  54.                    self.last_shoot_time = time.time()
  55.                    player.shoot()
  56.     # 射击
  57.     def shoot(self):
  58.         bullet = Bullet(self.rect.centerx, self.rect.top)
  59.         all_sprites.add(bullet)
  60.         bullets.add(bullet)
  61. # 定义敌机类
  62. class Enemy(pygame.sprite.Sprite):
  63.     def __init__(self):
  64.         super().__init__()
  65.         self.image = enemy_image
  66.         self.rect = self.image.get_rect()
  67.         self.rect.x = random.randint(0, WINDOW_WIDTH - self.rect.width)
  68.         self.rect.y = random.randint(-100, -self.rect.height)
  69.         self.speed = random.randint(1, 2)
  70.     # 移动
  71.     def update(self):
  72.         self.rect.y += self.speed
  73.         if self.rect.top > WINDOW_HEIGHT:
  74.             self.kill()
  75. # 定义子弹类
  76. class Bullet(pygame.sprite.Sprite):
  77.     def __init__(self, x, y):
  78.         super().__init__()
  79.         self.image = bullet_image
  80.         self.rect = self.image.get_rect()
  81.         self.rect.centerx = x
  82.         self.rect.bottom = y
  83.         self.speed = -10
  84.     # 移动
  85.     def update(self):
  86.         self.rect.y += self.speed
  87.         if self.rect.bottom < 0:
  88.             self.kill()
  89.    
  90. # 创建精灵组
  91. all_sprites = pygame.sprite.Group()
  92. enemies = pygame.sprite.Group()
  93. bullets = pygame.sprite.Group()
  94. # 创建玩家并添加到精灵组
  95. player = Player()
  96. all_sprites.add(player)
  97. # 定义游戏循环
  98. clock = pygame.time.Clock()
  99. score = 0
  100. game_over = False
  101. last_move_time=time.time()
  102. enemy_speed=10
  103. while not game_over:
  104.     # 处理事件
  105.     for event in pygame.event.get():
  106.         if event.type == pygame.QUIT:
  107.             game_over = True
  108.         
  109.         elif event.type == pygame.KEYDOWN:
  110.             if event.key == pygame.K_RIGHT:
  111.                 # 当用户按下键位时标志位为True
  112.                 player.mv_right = True
  113.             elif event.key == pygame.K_LEFT:
  114.                 player.mv_left = True
  115.             if event.key == pygame.K_SPACE:
  116.                
  117.                    player.mv_shoot = True
  118.                
  119.         elif event.type == pygame.KEYUP:
  120.             if event.key == pygame.K_RIGHT:
  121.                 # 当用户松开键位为false
  122.                 player.mv_right = False
  123.             elif event.key == pygame.K_LEFT:
  124.                 player.mv_left = False   
  125.             if event.key == pygame.K_SPACE:
  126.                
  127.                 player.mv_shoot = False
  128.             
  129.     # 更新游戏状态
  130.     all_sprites.update()
  131.    
  132.     # 生成敌机
  133.     curTime = time.time()
  134.      
  135.     if len(enemies) < 10 and curTime - last_move_time>random.randint(3,enemy_speed+3):
  136.         print(enemy_speed)
  137.         last_move_time=time.time()
  138.         enemy = Enemy()
  139.         all_sprites.add(enemy)
  140.         enemies.add(enemy)
  141.     # 检测子弹是否击中敌机
  142.     hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
  143.     for hit in hits:
  144.         score += 10
  145.     #随得分增加,加大敌机生成频率和生成子弹频率
  146.     if score<1000:
  147.       enemy_speed=10-int(score/100)
  148.       player.shoot_speed=1-int(score/100)/10
  149.     else:
  150.       enemy_speed=1
  151.       player.shoot_speed=0.1
  152.     # 检测敌机是否撞击玩家
  153.     hits = pygame.sprite.spritecollide(player, enemies, False)
  154.     if len(hits) > 0:
  155.         game_over = True
  156.     # 清屏
  157.     window.fill(BLACK)
  158.     # 绘制背景
  159.     window.blit(background_image, (0, 0))
  160.     # 绘制精灵组中的所有元素
  161.     all_sprites.draw(window)
  162.     # 显示得分
  163.     score_text = font.render(f'Score: {score}', True, WHITE)
  164.     window.blit(score_text, (10, 10))
  165.    
  166.     # 更新屏幕
  167.     pygame.display.flip()
  168.     # 控制帧率
  169.     clock.tick(60)
  170. # 游戏结束,显示最终得分
  171. game_over_text = font.render('Game Over', True, RED)
  172. score_text = font.render(f'Final Score: {score}', True, WHITE)
  173. window.blit(game_over_text, (WINDOW_WIDTH // 2 - game_over_text.get_width() // 2, WINDOW_HEIGHT // 2 - game_over_text.get_height() // 2 - 30))
  174. window.blit(score_text, (WINDOW_WIDTH // 2 - score_text.get_width() // 2, WINDOW_HEIGHT // 2 - score_text.get_height() // 2 + 30))
  175. pygame.display.flip()
  176. # 等待 3 秒后关闭窗口
  177. pygame.time.wait(10000)
  178. pygame.quit()
复制代码

【俄罗斯方块】
  1. import sys
  2. import time
  3. import pygame
  4. from pygame.locals import *
  5. import blocks
  6. SIZE = 10  # 每个小方格大小
  7. BLOCK_HEIGHT = 32  # 游戏区高度
  8. BLOCK_WIDTH = 20   # 游戏区宽度
  9. BORDER_WIDTH = 4   # 游戏区边框宽度
  10. BORDER_COLOR = (40, 40, 200)  # 游戏区边框颜色
  11. SCREEN_WIDTH = SIZE * (BLOCK_WIDTH + 4)  # 游戏屏幕的宽
  12. SCREEN_HEIGHT = SIZE * BLOCK_HEIGHT      # 游戏屏幕的高
  13. BG_COLOR = (40, 40, 60)  # 背景色
  14. BLOCK_COLOR = (20, 128, 200)  #
  15. BLACK = (0, 0, 0)
  16. RED = (200, 30, 30)      # GAME OVER 的字体颜色
  17. def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
  18.   imgText = font.render(text, True, fcolor)
  19.   screen.blit(imgText, (x, y))
  20. def main():
  21.   pygame.init()
  22.   screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
  23.   pygame.display.set_caption('俄罗斯方块')
  24.   font1 = pygame.font.SysFont('SimHei', 14)  # 黑体24
  25.   font2 = pygame.font.Font(None, 55)  # GAME OVER 的字体
  26.   font_pos_x = BLOCK_WIDTH * SIZE + BORDER_WIDTH + 2  # 右侧信息显示区域字体位置的X坐标
  27.   gameover_size = font2.size('GAME OVER')
  28.   font1_height = int(font1.size('score')[1])
  29.   cur_block = None   # 当前下落方块
  30.   next_block = None  # 下一个方块
  31.   cur_pos_x, cur_pos_y = 0, 0
  32.   game_area = None    # 整个游戏区域
  33.   game_over = True
  34.   start = False       # 是否开始,当start = True,game_over = True 时,才显示 GAME OVER
  35.   score = 0           # 得分
  36.   orispeed = 0.5      # 原始速度
  37.   speed = orispeed    # 当前速度
  38.   pause = False       # 暂停
  39.   last_drop_time = None   # 上次下落时间
  40.   last_press_time = None  # 上次按键时间
  41.   def _dock():
  42.       nonlocal cur_block, next_block, game_area, cur_pos_x, cur_pos_y, game_over, score, speed
  43.       for _i in range(cur_block.start_pos.Y, cur_block.end_pos.Y + 1):
  44.           for _j in range(cur_block.start_pos.X, cur_block.end_pos.X + 1):
  45.               if cur_block.template[_i][_j] != '.':
  46.                   game_area[cur_pos_y + _i][cur_pos_x + _j] = '0'
  47.       if cur_pos_y + cur_block.start_pos.Y <= 0:
  48.           game_over = True
  49.       else:
  50.           # 计算消除
  51.           remove_idxs = []
  52.           for _i in range(cur_block.start_pos.Y, cur_block.end_pos.Y + 1):
  53.               if all(_x == '0' for _x in game_area[cur_pos_y + _i]):
  54.                   remove_idxs.append(cur_pos_y + _i)
  55.           if remove_idxs:
  56.               # 计算得分
  57.               remove_count = len(remove_idxs)
  58.               if remove_count == 1:
  59.                   score += 100
  60.               elif remove_count == 2:
  61.                   score += 300
  62.               elif remove_count == 3:
  63.                   score += 700
  64.               elif remove_count == 4:
  65.                   score += 1500
  66.               speed = orispeed - 0.03 * (score // 10000)
  67.               # 消除
  68.               _i = _j = remove_idxs[-1]
  69.               while _i >= 0:
  70.                   while _j in remove_idxs:
  71.                       _j -= 1
  72.                   if _j < 0:
  73.                       game_area[_i] = ['.'] * BLOCK_WIDTH
  74.                   else:
  75.                       game_area[_i] = game_area[_j]
  76.                   _i -= 1
  77.                   _j -= 1
  78.           cur_block = next_block
  79.           next_block = blocks.get_block()
  80.           cur_pos_x, cur_pos_y = (BLOCK_WIDTH - cur_block.end_pos.X - 1) // 2, -1 - cur_block.end_pos.Y
  81.   def _judge(pos_x, pos_y, block):
  82.       nonlocal game_area
  83.       for _i in range(block.start_pos.Y, block.end_pos.Y + 1):
  84.           if pos_y + block.end_pos.Y >= BLOCK_HEIGHT:
  85.               return False
  86.           for _j in range(block.start_pos.X, block.end_pos.X + 1):
  87.               if pos_y + _i >= 0 and block.template[_i][_j] != '.' and game_area[pos_y + _i][pos_x + _j] != '.':
  88.                   return False
  89.       return True
  90.   while True:
  91.       for event in pygame.event.get():
  92.           if event.type == QUIT:
  93.               sys.exit()
  94.           elif event.type == KEYDOWN:
  95.               if event.key == K_RETURN:
  96.                   if game_over:
  97.                       start = True
  98.                       game_over = False
  99.                       score = 0
  100.                       last_drop_time = time.time()
  101.                       last_press_time = time.time()
  102.                       game_area = [['.'] * BLOCK_WIDTH for _ in range(BLOCK_HEIGHT)]
  103.                       cur_block = blocks.get_block()
  104.                       next_block = blocks.get_block()
  105.                       cur_pos_x, cur_pos_y = (BLOCK_WIDTH - cur_block.end_pos.X - 1) // 2, -1 - cur_block.end_pos.Y
  106.               elif event.key == K_SPACE:
  107.                   if not game_over:
  108.                       pause = not pause
  109.               elif event.key in (K_w, K_UP):
  110.                   if 0 <= cur_pos_x <= BLOCK_WIDTH - len(cur_block.template[0]):
  111.                       _next_block = blocks.get_next_block(cur_block)
  112.                       if _judge(cur_pos_x, cur_pos_y, _next_block):
  113.                           cur_block = _next_block
  114.               elif event.key in (K_a, K_LEFT):
  115.                       if time.time() - last_press_time > 0.1:
  116.                         last_press_time = time.time()
  117.                         if cur_pos_x > - cur_block.start_pos.X:
  118.                           if _judge(cur_pos_x - 1, cur_pos_y, cur_block):
  119.                               cur_pos_x -= 1
  120.               elif event.key in (K_d, K_RIGHT):
  121.                       if time.time() - last_press_time > 0.1:
  122.                         last_press_time = time.time()
  123.                       # 不能移除右边框
  124.                         if cur_pos_x + cur_block.end_pos.X + 1 < BLOCK_WIDTH:
  125.                           if _judge(cur_pos_x + 1, cur_pos_y, cur_block):
  126.                               cur_pos_x += 1
  127.               elif event.key in (K_s, K_DOWN):
  128.                       if time.time() - last_press_time > 0.1:
  129.                         last_press_time = time.time()
  130.                         if not _judge(cur_pos_x, cur_pos_y + 1, cur_block):
  131.                           _dock()
  132.                         else:
  133.                           last_drop_time = time.time()
  134.                           cur_pos_y += 1
  135.       if event.type == pygame.KEYDOWN:
  136.           if event.key == pygame.K_LEFT:
  137.               if not game_over and not pause:
  138.                   if time.time() - last_press_time > 0.1:
  139.                       last_press_time = time.time()
  140.                       if cur_pos_x > - cur_block.start_pos.X:
  141.                           if _judge(cur_pos_x - 1, cur_pos_y, cur_block):
  142.                               cur_pos_x -= 1
  143.           if event.key == pygame.K_RIGHT:
  144.               if not game_over and not pause:
  145.                   if time.time() - last_press_time > 0.1:
  146.                       last_press_time = time.time()
  147.                       # 不能移除右边框
  148.                       if cur_pos_x + cur_block.end_pos.X + 1 < BLOCK_WIDTH:
  149.                           if _judge(cur_pos_x + 1, cur_pos_y, cur_block):
  150.                               cur_pos_x += 1
  151.           if event.key == pygame.K_DOWN:
  152.               if not game_over and not pause:
  153.                   if time.time() - last_press_time > 0.1:
  154.                       last_press_time = time.time()
  155.                       if not _judge(cur_pos_x, cur_pos_y + 1, cur_block):
  156.                           _dock()
  157.                       else:
  158.                           last_drop_time = time.time()
  159.                           cur_pos_y += 1
  160.       _draw_background(screen)
  161.       _draw_game_area(screen, game_area)
  162.       _draw_gridlines(screen)
  163.       _draw_info(screen, font1, font_pos_x, font1_height, score)
  164.       # 画显示信息中的下一个方块
  165.       _draw_block(screen, next_block, font_pos_x, 30 + (font1_height + 6) * 5, 0, 0)
  166.       if not game_over:
  167.           cur_drop_time = time.time()
  168.           if cur_drop_time - last_drop_time > speed:
  169.               if not pause:
  170.                   if not _judge(cur_pos_x, cur_pos_y + 1, cur_block):
  171.                       _dock()
  172.                   else:
  173.                       last_drop_time = cur_drop_time
  174.                       cur_pos_y += 1
  175.       else:
  176.           if start:
  177.               print_text(screen, font2,
  178.                          (SCREEN_WIDTH - gameover_size[0]) // 2, (SCREEN_HEIGHT - gameover_size[1]) // 2,
  179.                          'GAME OVER', RED)
  180.       # 画当前下落方块
  181.       _draw_block(screen, cur_block, 0, 0, cur_pos_x, cur_pos_y)
  182.       pygame.display.flip()
  183. # 画背景
  184. def _draw_background(screen):
  185.   # 填充背景色
  186.   screen.fill(BG_COLOR)
  187.   # 画游戏区域分隔线
  188.   pygame.draw.line(screen, BORDER_COLOR,
  189.                    (SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, 0),
  190.                    (SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, SCREEN_HEIGHT), BORDER_WIDTH)
  191. # 画网格线
  192. def _draw_gridlines(screen):
  193.   # 画网格线 竖线
  194.   for x in range(BLOCK_WIDTH):
  195.       pygame.draw.line(screen, BLACK, (x * SIZE, 0), (x * SIZE, SCREEN_HEIGHT), 1)
  196.   # 画网格线 横线
  197.   for y in range(BLOCK_HEIGHT):
  198.       pygame.draw.line(screen, BLACK, (0, y * SIZE), (BLOCK_WIDTH * SIZE, y * SIZE), 1)
  199. # 画已经落下的方块
  200. def _draw_game_area(screen, game_area):
  201.   if game_area:
  202.       for i, row in enumerate(game_area):
  203.           for j, cell in enumerate(row):
  204.               if cell != '.':
  205.                   pygame.draw.rect(screen, BLOCK_COLOR, (j * SIZE, i * SIZE, SIZE, SIZE), 0)
  206. # 画单个方块
  207. def _draw_block(screen, block, offset_x, offset_y, pos_x, pos_y):
  208.   if block:
  209.       for i in range(block.start_pos.Y, block.end_pos.Y + 1):
  210.           for j in range(block.start_pos.X, block.end_pos.X + 1):
  211.               if block.template[i][j] != '.':
  212.                   pygame.draw.rect(screen, BLOCK_COLOR,
  213.                                    (offset_x + (pos_x + j) * SIZE, offset_y + (pos_y + i) * SIZE, SIZE, SIZE), 0)
  214. # 画得分等信息
  215. def _draw_info(screen, font, pos_x, font_height, score):
  216.   print_text(screen, font, pos_x, 10, f'score: ')
  217.   print_text(screen, font, pos_x, 10 + font_height + 6, f'{score}')
  218.   print_text(screen, font, pos_x, 20 + (font_height + 6) * 2, f'speed:')
  219.   print_text(screen, font, pos_x, 20 + (font_height + 6) * 3, f'{score // 10000}')
  220.   print_text(screen, font, pos_x, 30 + (font_height + 6) * 4, f'next:')
  221. if __name__ == '__main__':
  222.   main()
复制代码
【贪吃蛇】
  1. import random
  2. import sys
  3. import time
  4. import pygame
  5. from pygame.locals import *
  6. from collections import deque
  7. SCREEN_WIDTH = 240      # 屏幕宽度
  8. SCREEN_HEIGHT = 320     # 屏幕高度
  9. SIZE = 20               # 小方格大小
  10. LINE_WIDTH = 1          # 网格线宽度
  11. # 游戏区域的坐标范围
  12. SCOPE_X = (0, SCREEN_WIDTH // SIZE - 1)
  13. SCOPE_Y = (2, SCREEN_HEIGHT // SIZE - 1)
  14. # 食物的分值及颜色
  15. FOOD_STYLE_LIST = [(10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))]
  16. LIGHT = (100, 100, 100)
  17. DARK = (200, 200, 200)      # 蛇的颜色
  18. BLACK = (0, 0, 0)           # 网格线颜色
  19. RED = (200, 30, 30)         # 红色,GAME OVER 的字体颜色
  20. BGCOLOR = (40, 40, 60)      # 背景色
  21. def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
  22.   imgText = font.render(text, True, fcolor)
  23.   screen.blit(imgText, (x, y))
  24. # 初始化蛇
  25. def init_snake():
  26.   snake = deque()
  27.   snake.append((2, SCOPE_Y[0]))
  28.   snake.append((1, SCOPE_Y[0]))
  29.   snake.append((0, SCOPE_Y[0]))
  30.   return snake
  31. def create_food(snake):
  32.   food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
  33.   food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
  34.   while (food_x, food_y) in snake:
  35.       # 如果食物出现在蛇身上,则重来
  36.       food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
  37.       food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
  38.   return food_x, food_y
  39. def get_food_style():
  40.   return FOOD_STYLE_LIST[random.randint(0, 2)]
  41. def main():
  42.   pygame.init()
  43.   screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
  44.   pygame.display.set_caption('贪吃蛇')
  45.   font1 = pygame.font.SysFont('SimHei', 23)  # 得分的字体
  46.   font2 = pygame.font.Font(None, 55)  # GAME OVER 的字体
  47.   fwidth, fheight = font2.size('GAME OVER')
  48.   # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAME OVER
  49.   # b 变量就是用于防止这种情况的发生
  50.   b = True
  51.   # 蛇
  52.   snake = init_snake()
  53.   # 食物
  54.   food = create_food(snake)
  55.   food_style = get_food_style()
  56.   # 方向
  57.   pos = (1, 0)
  58.   game_over = True
  59.   start = False       # 是否开始,当start = True,game_over = True 时,才显示 GAME OVER
  60.   score = 0           # 得分
  61.   orispeed = 0.5      # 原始速度
  62.   speed = orispeed
  63.   last_move_time = None
  64.   pause = False       # 暂停
  65.   while True:
  66.       for event in pygame.event.get():
  67.           if event.type == QUIT:
  68.               sys.exit()
  69.           elif event.type == KEYDOWN:
  70.               if event.key == K_RETURN:
  71.                   if game_over:
  72.                       start = True
  73.                       game_over = False
  74.                       b = True
  75.                       snake = init_snake()
  76.                       food = create_food(snake)
  77.                       food_style = get_food_style()
  78.                       pos = (1, 0)
  79.                       # 得分
  80.                       score = 0
  81.                       last_move_time = time.time()
  82.               elif event.key == K_SPACE:
  83.                   if not game_over:
  84.                       pause = not pause
  85.               elif event.key in (K_w, K_UP):
  86.                   # 这个判断是为了防止蛇向上移时按了向下键,导致直接 GAME OVER
  87.                   if b and not pos[1]:
  88.                       pos = (0, -1)
  89.                       b = False
  90.               elif event.key in (K_s, K_DOWN):
  91.                   if b and not pos[1]:
  92.                       pos = (0, 1)
  93.                       b = False
  94.               elif event.key in (K_a, K_LEFT):
  95.                   if b and not pos[0]:
  96.                       pos = (-1, 0)
  97.                       b = False
  98.               elif event.key in (K_d, K_RIGHT):
  99.                   if b and not pos[0]:
  100.                       pos = (1, 0)
  101.                       b = False
  102.       # 填充背景色
  103.       screen.fill(BGCOLOR)
  104.       # 画网格线 竖线
  105.       for x in range(SIZE, SCREEN_WIDTH, SIZE):
  106.           pygame.draw.line(screen, BLACK, (x, SCOPE_Y[0] * SIZE), (x, SCREEN_HEIGHT), LINE_WIDTH)
  107.       # 画网格线 横线
  108.       for y in range(SCOPE_Y[0] * SIZE, SCREEN_HEIGHT, SIZE):
  109.           pygame.draw.line(screen, BLACK, (0, y), (SCREEN_WIDTH, y), LINE_WIDTH)
  110.       if not game_over:
  111.           curTime = time.time()
  112.           if curTime - last_move_time > speed:
  113.               if not pause:
  114.                   b = True
  115.                   last_move_time = curTime
  116.                   next_s = (snake[0][0] + pos[0], snake[0][1] + pos[1])
  117.                   if next_s == food:
  118.                       # 吃到了食物
  119.                       snake.appendleft(next_s)
  120.                       score += food_style[0]
  121.                       speed = orispeed - 0.03 * (score // 100)
  122.                       food = create_food(snake)
  123.                       food_style = get_food_style()
  124.                   else:
  125.                       if SCOPE_X[0] <= next_s[0] <= SCOPE_X[1] and SCOPE_Y[0] <= next_s[1] <= SCOPE_Y[1] \
  126.                               and next_s not in snake:
  127.                           snake.appendleft(next_s)
  128.                           snake.pop()
  129.                       else:
  130.                           game_over = True
  131.       # 画食物
  132.       if not game_over:
  133.           # 避免 GAME OVER 的时候把 GAME OVER 的字给遮住了
  134.           pygame.draw.rect(screen, food_style[1], (food[0] * SIZE, food[1] * SIZE, SIZE, SIZE), 0)
  135.       # 画蛇
  136.       for s in snake:
  137.           pygame.draw.rect(screen, DARK, (s[0] * SIZE + LINE_WIDTH, s[1] * SIZE + LINE_WIDTH,
  138.                                           SIZE - LINE_WIDTH * 2, SIZE - LINE_WIDTH * 2), 0)
  139.       print_text(screen, font1, 5, 10, f'speed: {score//100}')
  140.       print_text(screen, font1, 105, 10, f'score: {score}')
  141.       if game_over:
  142.           if start:
  143.               print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)
  144.       pygame.display.update()
  145. if __name__ == '__main__':
  146.     main()
复制代码

RRoy  超级版主

发表于 2023-9-18 16:45:01

666
回复

使用道具 举报

快看擎天猪  中级技师

发表于 2023-9-26 19:10:26

666666666666666666
回复

使用道具 举报

Amos Young  中级技师

发表于 2023-10-4 14:55:41

这个创意有趣,云天老师好帅!
回复

使用道具 举报

_深蓝_  高级技师

发表于 2023-10-16 17:23:11

这个创意有趣,云天老师好帅!
回复

使用道具 举报

easylot  初级技师 来自手机

发表于 2023-11-14 16:34:33

好教程
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail