基于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()

运行上述代码,我们可以得到一个灰色界面的窗口
基于BP神经网络及Pygame创做坦克自动扫雷机(二)_第1张图片

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()地雷展示函数即可看到地雷出现在窗口中.如图所示.
基于BP神经网络及Pygame创做坦克自动扫雷机(二)_第2张图片
(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)

运行代码,多个地雷随机分布在窗口:
基于BP神经网络及Pygame创做坦克自动扫雷机(二)_第3张图片
是不是有内味了呢,但我们还没完.

扫雷机运动模型

(1)添加扫雷机图像
接下来,我们需要将扫雷机加入程序中。与地雷图片处理类似,在 images 将 png 图片放入其中。
在这里插入图片描述
为了方便,接下来,我们创建扫雷机类 sweeper.py.操作方法和地雷一模一样,这里不再过多叙述,只是扫雷机位置放在窗口中央,只有一个扫雷机就好.
基于BP神经网络及Pygame创做坦克自动扫雷机(二)_第4张图片
(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神经网络模型的建模和训练,调用,谢谢大家的观看.

你可能感兴趣的