基于BP神经网络及Pygame创做坦克自动扫雷机(二)

前言

本文章是基于BP神经网络及Pygame创做坦克自动扫雷机的第二篇,该案例将涵括深度学习神经网络,数据处理,数据产生以及Pygame,Tensorflow,Keras,Matplotlib,Pandas,numpy等库综合的使用.本文将讲述坦克自动扫雷机利用Pygame库生成的游戏界面以及运动分析.

以下是本篇文章正文内容

一、Pygame快速操作

Pygame库是一个强大的开源库,我们能利用其做出许多优美有趣的游戏,但在本案例中我们只需要做出简单的扫雷机游戏即可,话不多说,我们开始吧.

1.创建一个窗口

调用Pygame时要先调用库并且初始化,然后对窗口长宽大小,颜色,窗口名字进行一个定义.为保证窗口能够持续出现,加入while True循环;为确保能够退出,加入sys.exit退出程序.如图所示

import sys
import pygame

def run_game():
     # 初始化pygame,创建喜欢的窗口类型
	 pygame.init()
	 screen = pygame.display.set_mode((1200, 800))
	 pygame.display.set_caption("Mine Clearing")
	 # 背景颜色
	 bg_color = (230, 230, 230)
	 # 游戏窗口循环
	 while True:
		 # 如果按下退出键,则退出
		 for event in pygame.event.get():
			 if event.type == pygame.QUIT:
			 sys.exit()
		 # 填充颜色
		 screen.fill(bg_color)
		 # 把窗口展示出来
		 pygame.display.flip()
run_game()

运行上述代码,我们可以得到一个灰色界面的窗口
在这里插入图片描述

2.放入地雷图像

接下来,我们需要将地雷加入程序中。为了在屏幕上绘制地雷,我们将加载一幅图像,再使用 Pygame方法绘制它。在主项目中新建一个文件夹叫 images,将如下图片放入其中
地雷在这里
!!!地雷在上面↑!!!
这里,加载地雷图片的函数是

image = pygame.image.load('images/mine.png').convert_alpha()
#括号里面字符串是地雷图片的存放位置.

当然,仅仅调用一个加载函数是不行的,因为计算机不知道你把它加载在哪个地方,所以还要对其位置进行约束.为了后期方便调用函数,我们创建一个设置类和地雷类 mine.py.
在设置类里,我们将窗口的宽,高以及颜色进行定义,如下所示

class Settings(object):
	 def __init__(self):
		 self.screen_width = 1200
		 self.screen_height = 800
		 self.bg_color = (230,230,230)

在地雷类里,我们将定义地雷位置,将其放入之前的创建的窗口中,这里说明一下:为什么是获取地雷图片矩形大小呢?虽然我们看到的地雷好像不是矩形,但实际上图片都是以矩形形式展示的,我们肉眼只是看到有信息的图像,在地雷图片中,周围白色区域也属于该图片大小,因此在地雷初始化函数里,获取的是图片矩形大小.

class Mine(Sprite):
	#地雷初始化函数 
	def __init__(self, ai_settings, screen):
		 super().__init__()
			 self.screen = screen
			 self.ai_settings = ai_settings
			 self.image = pygame.image.load('images/mine.png').convert_alpha()
			 self.rect = self.image.get_rect()
			 self.radius = self.rect.width
			 self.rect.x = self.rect.width
			 self.rect.y = self.rect.height
	#地雷展示函数
	def blitme(self):
	 	self.screen.blit(self.image, self.rect)

在运行的类中,调用地雷类和设置类以及在主函数中调用blitme()地雷展示函数即可看到地雷出现在窗口中.如图所示.
在这里插入图片描述
(1).构建多地雷随机分布场景
1个地雷当然不够我们扫,因此我们设置地雷数量为20个,当然也可以设置30,40个,添加函数使用.add()即可.
为了更好集中体现游戏性,我们创建一个游戏功能类,将所有有趣的代码放到这个类里面去.
在 Settings()类中设置地雷数量:

self.mine_number = 20

在 game_functions (游戏功能)类添加 create_mine()函数

def create_mine(ai_settings, screen, mines):
	 mine = Mine(ai_settings, screen)
	 mine.rect.x = random.randint(50, ai_settings.screen_width - 50)
	 mine.rect.y = random.randint(50, ai_settings.screen_height - 50)
	 mines.add(mine)

运行代码,多个地雷随机分布在窗口:
在这里插入图片描述
是不是有内味了呢,但我们还没完.

扫雷机运动模型

(1)添加扫雷机图像
接下来,我们需要将扫雷机加入程序中。与地雷图片处理类似,在 images 将 png 图片放入其中。
在这里插入图片描述
为了方便,接下来,我们创建扫雷机类 sweeper.py.操作方法和地雷一模一样,这里不再过多叙述,只是扫雷机位置放在窗口中央,只有一个扫雷机就好.
在这里插入图片描述
(2)驱动扫雷机前行
扫雷机当然和地雷不一样,扫雷机需要运动,首先我们有定义它的运动速度和运动角度.

# 初始角度
self.angle = 0
self.moving_speed = [1, 1]
self.moving_pos = [self.rect.centerx, self.rect.centery]

扫雷机的位置是不断变化的.加入 update()函数,更新扫雷机位置:

def update(self):
	self.moving_pos[0] -= math.sin(self.angle / 180 * math.pi) * 
	self.moving_speed[0]
	self.moving_pos[1] -= math.cos(self.angle / 180 * math.pi) * 
	self.moving_speed[1]
	self.rect.centerx = self.moving_pos[0]
	self.rect.centery = self.moving_pos[1]

以上函数意思是将扫雷机图片中心位置坐标X,Y不断刷新,更新位置.
但是这样其运动速度过快,且会跑出边界消失。因此,在窗口函数中引入clock()类控制循环时间:

clock = pygame.time.Clock()
while True:
	 gf.check_events()
	 sweeper.update()
	 gf.update_screen(ai_settings, screen, mines, sweeper)
	 pygame.display.flip()
	 clock.tick(100) 

为防止扫雷机跑出边界消失,在update刷新函数中加一个逻辑判断,碰到窗口边界进行反弹:

# 上下边界反弹的处理
if (self.rect.top <= 0 and -90 < self.angle < 90) or (
self.rect.bottom >= self.screen_rect.height and (self.angle > 
90 or self.angle < -90)):
	self.angle = 180 - self.angle

(3)驱动扫雷机转弯
你肯定会有疑惑,怎么让扫雷机转弯呢.这里我们首先要实现的就是可通过左右箭头键来控制扫雷机的左转与右转。为允许不断转弯,例如按住右箭头不放时,扫雷机能不断地右转,直到松开为止,这里我们通过 KEYDOWN 和 KEYUP 事件来判断。因此我们设置一个标志位 moving_right 来实现持续右转。这个转弯属性是扫雷机属性的一种,我们用 sweeper 类来控制,
因此我们给这个类增加一个属性名称叫moving_right 以及一个update()方法来检测标志 moving_right 的状态。
sweeper类中:

	 self.moving_right = False
 	 self.moving_left = False
 def update(self):
	 # 右转的处理
	 if self.moving_right:
	 self.angle -= 1
	 if self.angle < -180:
	 self.angle = 360 + self.angle

game_functions游戏功能类中

def check_keydown_events(event, sweeper):
	 if event.key == pygame.K_RIGHT:
	 # move right
	 	sweeper.moving_right = True
	 elif event.key == pygame.K_LEFT:
	 # move left
	 	sweeper.moving_left = True
def check_keyup_events(event, sweeper):
	 if event.key == pygame.K_RIGHT:
	 	sweeper.moving_right = False
	 elif event.key == pygame.K_LEFT:
	 	sweeper.moving_left = False

该函数意思就是根据键盘左右按键进行位置更改.
最后在update刷新函数里调用即可.

(4)扫雷机图像转动
虽然我们实现了扫雷机的转弯运动,但其图片并没有随之转动,因此,我们需要利用 pygame.transform.rotate()函数里旋转图片。
使用到的函数是:

new_sweeper.image = pygame.transform.rotate(self.image, self.angle)

就是根据原图以及更改的角度获取一个新的图片位置
(5)扫雷机与地雷碰撞检测
扫雷机与地雷 的 碰撞检测可以利用
**pygame.sprite.spritecollide(sprite,sprite_group,bool)**函数。调用这个函数的时候,一个组中的所有精灵都会逐个地对另外一个单个精灵进行冲突检测,发生冲突的精灵会作为一个列表返回。这个函数的第一个参数就是单个精灵,第二个参数是精灵组,第三个参数是一个 bool 值,最后这个参数起了很大的作用。当为 True 的时候,会删除组中所有冲突的精灵,False 的时候不会删除冲突的精灵。

当然,我们将这个有趣的函数放到game_functions游戏功能类中

def check_sweeper_mine_collisions(sweeper, mines):
	pygame.sprite.spritecollide(sweeper, mines, True, None)

运行后,我们可以发现扫雷机能够吃掉地雷了,是不是很有趣呢.

总结

好了,以上就是今天要讲的内容,本文简单介绍了Pygame创建一个简单的扫雷机游戏,看似复杂,实则理解好Pygame库的调用以及类的使用,可以发现整体很简单.后面我们将进行扫雷机的自动扫雷,也就是BP神经网络模型的建模和训练,调用,谢谢大家的观看.

以下使整个工程项目的代码,大家可自行参考。
BP神经网络及Pygame创做坦克自动扫雷机

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个使用Pygame制作的简单扫雷游戏示例: ```python import pygame import random # 初始化pygame pygame.init() # 设置游戏窗口的大小 screen_width = 400 screen_height = 400 screen = pygame.display.set_mode((screen_width, screen_height)) # 设置游戏标题 pygame.display.set_caption("扫雷游戏") # 设置游戏背景颜色 background_color = (255, 255, 255) # 设置游戏结束的标志 game_over = False # 设置游戏时钟 clock = pygame.time.Clock() # 定义方格的大小和数量 grid_size = 20 grid_count_x = screen_width // grid_size grid_count_y = screen_height // grid_size # 定义雷的数量 mine_count = 20 # 随机生成雷的位置 mines = [] for _ in range(mine_count): mine = [random.randint(0, grid_count_x - 1), random.randint(0, grid_count_y - 1)] if mine not in mines: mines.append(mine) # 定义方格状态 grid_status = [[0] * grid_count_x for _ in range(grid_count_y)] # 0代表未揭示,1代表揭示,2代表标记雷 # 游戏循环 while not game_over: # 处理游戏事件 for event in pygame.event.get(): if event.type == pygame.QUIT: game_over = True elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: # 左键点击 mouse_pos = pygame.mouse.get_pos() grid_x = mouse_pos[0] // grid_size grid_y = mouse_pos[1] // grid_size if grid_status[grid_y][grid_x] == 0: if [grid_x, grid_y] in mines: # 点到雷,游戏结束 game_over = True else: # 统计周围雷的数量 count = 0 for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if dx == 0 and dy == 0: continue nx = grid_x + dx ny = grid_y + dy if nx >= 0 and nx < grid_count_x and ny >= 0 and ny < grid_count_y: if [nx, ny] in mines: count += 1 grid_status[grid_y][grid_x] = count + 1 elif event.button == 3: # 右键点击 mouse_pos = pygame.mouse.get_pos() grid_x = mouse_pos[0] // grid_size grid_y = mouse_pos[1] // grid_size if grid_status[grid_y][grid_x] == 0: grid_status[grid_y][grid_x] = 2 elif grid_status[grid_y][grid_x] == 2: grid_status[grid_y][grid_x] = 0 # 绘制游戏界面 screen.fill(background_color) for y in range(grid_count_y): for x in range(grid_count_x): rect = pygame.Rect(x * grid_size, y * grid_size, grid_size, grid_size) pygame.draw.rect(screen, (192, 192, 192), rect) if grid_status[y][x] == 1: pygame.draw.rect(screen, (128, 128, 128), rect) if [x, y] in mines: pygame.draw.circle(screen, (0, 0, 0), (x * grid_size + grid_size // 2, y * grid_size + grid_size // 2), grid_size // 4) else: if grid_status[y][x] > 1: font = pygame.font.SysFont(None, grid_size // 2) text = font.render(str(grid_status[y][x] - 1), True, (0, 0, 0)) screen.blit(text, (x * grid_size + grid_size // 3, y * grid_size + grid_size // 3)) elif grid_status[y][x] == 2: font = pygame.font.SysFont(None, grid_size // 2) text = font.render("雷", True, (255, 0, 0)) screen.blit(text, (x * grid_size + grid_size // 3, y * grid_size + grid_size // 3)) # 更新游戏显示 pygame.display.update() # 控制游戏帧率 clock.tick(30) # 退出游戏 pygame.quit() ``` 这个扫雷游戏使用方格来表示雷区,玩家可以通过左键点击方格来揭示方格,如果揭示到雷,游戏结束;如果揭示到的方格周围有雷,方格上方会显示雷的数量;玩家可以通过右键点击方格来标记可能的雷。游戏界面使用了灰色的方格表示未揭示的方格,揭示后的方格会变成浅灰色,雷会显示为黑色圆圈,标记雷的方格会显示红色的"雷"字样。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fantaley

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值