您的位置:首页 > 大数据 > 人工智能

Pygame学习(2)------AI(人工智能)

2013-07-23 11:02 441 查看
为我们的游戏加上人工智能,也就是我们所谓的NPC.

好吧,开始类~目测我的NPC智商不会高,哈哈~~~

--------------------------------我是勤勤恳恳的分割线-------------------------------

做之前,我先要考虑好我的NPC到底长啥样,能做什么.

我就做一个超级玛丽里只会来回走动,碰壁就回头的小乌龟吧.嘿嘿~~~~~



资料图片: background
tortoise

一. 先搭建一个静态的"世界"

#!/usr/bin/env python
#coding=utf-8

#导入pygame库
import pygame
#导入一些常用的函数和常量
from pygame.locals import *
#向sys模块借一个exit函数用来退出程序
from sys import exit

#背景图片的大小
SCREEN_SIZE = (347, 268)
#墙的图片的大小
WALL_SIZE = (34,106)
#乌龟图片的大小
TORTOISE_SIZE = (40,42)
#图片中地面的高度
GROUD_LEVEL = 16

def run():
#初始化pygame,为使用硬件做准备
pygame.init()
#创建了一个窗口
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
#设置窗口标题
pygame.display.set_caption("AI")

#加载并转换图像
background = pygame.image.load("background.png").convert()
tortoise = pygame.image.load("tortoise.png").convert()
wall = pygame.image.load("wall.png").convert()

#游戏主循环
while True:

#接收到退出事件后退出程序
for event in pygame.event.get():
if event.type == QUIT:
exit()

#将背景和乌龟还有墙画上去
screen.blit(background, (0,0))
#图片怎么定置就不要多看了,因为图片是我乱找乱截的,有些蛋疼~~~~~
sw, sh = SCREEN_SIZE
tw, th = TORTOISE_SIZE
ww, wh = WALL_SIZE
screen.blit(tortoise, (sw-tw-ww,sh-th-GROUD_LEVEL))
screen.blit(wall, (sw-ww,sh-wh-GROUD_LEVEL))
screen.blit(wall, (0,sh-wh-GROUD_LEVEL))

#刷新一下画面
pygame.display.update()

if __name__ == "__main__":
run()


二. 开始写智能啦,虽然有点弱智就是走来走去~

上面其实只是把几张图片拼凑成了一个静态的图片~~~所以还要继续努力~嘿嘿~~~~

我要写一个描述整个游戏环境的世界类。这里的世界不需要多复杂,仅仅需要一个背景,和存储若干的实体位置就足够了

class World(object):
"""世界类"""
def __init__(self):
# 存放所有实体
self.entities = {}
# 初始实体id
self.entity_id = 0
#加载并转换图像,我的背景图片
self.background = pygame.image.load("background.png").convert()

def add_entity(self, entity):
"""增加一个新的实体"""
self.entities[self.entity_id] = entity
entity.id = self.entity_id
self.entity_id += 1

def remove_entity(self, entity):
"""删除一个新的实体"""
del self.entities[entity.id]

def process(self, time_passed_seconds):
"""让世界内每个实体做事情"""
for entity in self.entities.values():
entity.process(time_passed_seconds)

def render(self, surface):
"""绘制背景和每一个实体"""
surface.blit(self.background, (0, 0))
for entity in self.entities.values():
entity.render(surface)


这里只出现了两个实体(乌龟和墙壁),我要试着写一个通用的实体基类,如果之后要加入了其他实体,也能很方便的扩展出来

class Entity(object):
"""实体类"""
def __init__(self, name, image):
self.name = name
self.image = image
self.location = Vector2(0, 0)
self.destination = Vector2(0, 0)
self.speed = 0.
self.brain = StateMachine()
self.id = 0

def process(self, time_passed):
"""让实体做事情"""
self.brain.think()
if self.speed != 0. and self.location != self.destination:
vec_to_destination = self.destination - self.location
distance_to_destination = vec_to_destination.get_length()
heading = vec_to_destination.get_normalized()
travel_distance = min(distance_to_destination, time_passed * self.speed)
self.location += travel_distance * heading

def render(self, surface):
"""绘制自己"""
x, y = self.location
surface.blit(self.image, (x, y))


接着就是我们重要的大脑(状态机类)

class State(object):
"""
状态类,定义我们的状态,如进入状态,退出状态等

(其实这个简单的功能有几个状态是用不到的,但是之后还有写更多的东西,所以我都给加上了)
只用到了check_conditions,entry_actions
"""
def __init__(self, name):
self.name = name
def do_actions(self):
pass
def check_conditions(self):
pass
def entry_actions(self):
pass
def exit_actions(self):
pass

class StateMachine(object):
"""
状态机类
新增状态和控制状态间的执行和转换
"""
def __init__(self):
self.states = {}
self.active_state = None

def add_state(self, state):
"""新增状态"""
self.states[state.name] = state

def think(self):
"""检查当前有效状态并执行其动作,并会调用set_state来进入下一个状态"""
if self.active_state is None:
return
self.active_state.do_actions()
new_state_name = self.active_state.check_conditions()
if new_state_name is not None:
self.set_state(new_state_name)

def set_state(self, new_state_name):
"""更改状态,执行进入/退出动作"""
if self.active_state is not None:
self.active_state.exit_actions()
self.active_state = self.states[new_state_name]
self.active_state.entry_actions()


当然还有我们的乌龟类呀,墙的类的,实体的状态类(如向前行走)呀等等,下面是完整代码:

#!/usr/bin/env python
#coding=utf-8

#导入pygame库
import pygame
#导入一些常用的函数和常量
from pygame.locals import *
#向sys模块借一个exit函数用来退出程序
from sys import exit
from gameobjects.vector2 import Vector2
from random import randint

#背景图片的大小
SCREEN_SIZE = (347, 268)
#墙的图片的大小
WALL_SIZE = (34,106)
#乌龟图片的大小
TORTOISE_SIZE = (40,42)
#图片中地面的高度
GROUD_LEVEL = 16

SCREEN_W, SCREEN_H = SCREEN_SIZE
TORTOISE_W, TORTOISE_H = TORTOISE_SIZE
WALL_W, WALL_H = WALL_SIZE

#我们要产生的乌龟数量
TORTOISE_COUNT = 1

class State(object):
"""
状态类,定义我们的状态,如进入状态,退出状态等

(其实这个简单的功能有几个状态是用不到的,但是之后还有写更多的东西,所以我都给加上了)
只用到了check_conditions,entry_actions
"""
def __init__(self, name):
self.name = name
def do_actions(self):
pass
def check_conditions(self):
pass
def entry_actions(self):
pass
def exit_actions(self):
pass

class StateMachine(object):
"""
状态机类
控制新增状态和状态间的执行和转换
"""
def __init__(self):
self.states = {}
self.active_state = None

def add_state(self, state):
"""新增状态"""
self.states[state.name] = state

def think(self):
"""检查当前有效状态并执行其动作,并会调用set_state来进入下一个状态"""
if self.active_state is None:
return
self.active_state.do_actions()
new_state_name = self.active_state.check_conditions()
if new_state_name is not None:
self.set_state(new_state_name)

def set_state(self, new_state_name):
"""更改状态,执行进入/退出动作"""
if self.active_state is not None:
self.active_state.exit_actions()
self.active_state = self.states[new_state_name]
self.active_state.entry_actions()

class World(object): """世界类""" def __init__(self): # 存放所有实体 self.entities = {} # 初始实体id self.entity_id = 0 #加载并转换图像,我的背景图片 self.background = pygame.image.load("background.png").convert() def add_entity(self, entity): """增加一个新的实体""" self.entities[self.entity_id] = entity entity.id = self.entity_id self.entity_id += 1 def remove_entity(self, entity): """删除一个新的实体""" del self.entities[entity.id] def process(self, time_passed_seconds): """让世界内每个实体做事情""" for entity in self.entities.values(): entity.process(time_passed_seconds) def render(self, surface): """绘制背景和每一个实体""" surface.blit(self.background, (0, 0)) for entity in self.entities.values(): entity.render(surface)

class Entity(object): """实体类""" def __init__(self, name, image): self.name = name self.image = image self.location = Vector2(0, 0) self.destination = Vector2(0, 0) self.speed = 0. self.brain = StateMachine() self.id = 0 def process(self, time_passed): """让实体做事情""" self.brain.think() if self.speed != 0. and self.location != self.destination: vec_to_destination = self.destination - self.location distance_to_destination = vec_to_destination.get_length() heading = vec_to_destination.get_normalized() travel_distance = min(distance_to_destination, time_passed * self.speed) self.location += travel_distance * heading def render(self, surface): """绘制自己""" x, y = self.location surface.blit(self.image, (x, y))

class Tortoise(Entity):
"""乌龟"""
def __init__(self, image, world, status):

self.tortoise_image = image

# 执行基类构造方法
Entity.__init__(self, "tortoise", self.tortoise_image)

# 创建各种状态
move_ahead = TortoiseMoveAhead(self)
turn_round = TortoiseTurnRound(self)
self.brain.add_state(move_ahead)
self.brain.add_state(turn_round)

self.world = world

#显示乌龟往哪个方向走
self.status = status

class TortoiseMoveAhead(State):
"""前行(move_ahead) 乌龟向前运动"""
def __init__(self, tortoise):
State.__init__(self, "move_ahead")
self.tortoise = tortoise

def check_conditions(self):
"""
动作之间的链接,也就是转移条件:
碰壁(hit_wall):碰到障碍物
"""
if self.tortoise.location == self.tortoise.destination:
return "turn_round"

def entry_actions(self):
self.tortoise.speed = 50.
if self.tortoise.status == "turn_left":
self.tortoise.destination = Vector2(WALL_W, SCREEN_H-TORTOISE_H-GROUD_LEVEL)
else:
self.tortoise.destination = Vector2(SCREEN_W-WALL_W-TORTOISE_W, SCREEN_H-TORTOISE_H-GROUD_LEVEL)

class TortoiseTurnRound(State):
"""转身(turn_round) 向后改变方向"""
def __init__(self, tortoise):
State.__init__(self, "turn_round")
self.tortoise = tortoise

def entry_actions(self):
self.tortoise.world.remove_entity(self.tortoise)
image = pygame.transform.flip(self.tortoise.tortoise_image, True, False)
status = "turn_right" if self.tortoise.status == "turn_left" else "turn_left"
w = WALL_W if self.tortoise.status == "turn_left" else SCREEN_W-WALL_W-TORTOISE_W
tortoise = Tortoise(image, self.tortoise.world, status)
tortoise.location = Vector2(w, SCREEN_H-TORTOISE_H-GROUD_LEVEL)
tortoise.brain.set_state("move_ahead")
self.tortoise.world.add_entity(tortoise)

class Wall(Entity):
"""墙壁"""
def __init__(self):

self.wall_image = pygame.image.load("wall.png").convert()

# 执行基类构造方法
Entity.__init__(self, "wall", self.wall_image)

def run():
#初始化pygame,为使用硬件做准备
pygame.init()
#创建了一个窗口
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
#设置窗口标题
pygame.display.set_caption("AI")

clock = pygame.time.Clock()
world = World()

#生成乌龟
image = pygame.image.load("tortoise.png").convert()
for i in xrange(TORTOISE_COUNT):
tortoise = Tortoise(image, world,"turn_left")
tortoise.location = Vector2(randint(WALL_W, SCREEN_W-WALL_W), SCREEN_H-TORTOISE_H-GROUD_LEVEL)
tortoise.brain.set_state("move_ahead")
world.add_entity(tortoise)

#生成墙
wall_first = Wall()
wall_second = Wall()
wall_first.location = Vector2(SCREEN_W-WALL_W, SCREEN_H-WALL_H-GROUD_LEVEL)
wall_second.location = Vector2(0, SCREEN_H-WALL_H-GROUD_LEVEL)
world.add_entity(wall_first)
world.add_entity(wall_second)

#游戏主循环
while True:

#接收到退出事件后退出程序
for event in pygame.event.get():
if event.type == QUIT:
exit()

#让世界内每个东西执行自己的动作
time_passed = clock.tick(30)
time_passed_seconds = time_passed / 1000.0
world.process(time_passed_seconds)

#画出整个界面
world.render(screen)

#刷新一下画面
pygame.display.update()

if __name__ == "__main__":
run()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: