License
license即为你放弃了自己的版权收入,将产品放在公共区域,给予别人特定的权力。他们没有义务把你列为原作者或是贡献者,但是你依然享有原著作权。还可以保证你的工作不为别人所剽窃。
GNU General Public License
GNU General Public License:开源项目比较常见的许可证,保证了开源项目着广泛的权力
1.用户可以无限制的复制软件
2.用户可以发布你想要发布的软件
3.提供软件时向别人收取费用,但是必须提供GPL的副本
4.修改其中的功能,但是必须按照GPL协议发布
GNU Lesser General Public License
GNU Lesser General Public License:授予的权限比GPL少,GPL不可以用于商用软件,LGPL可以用于商用软件,但是不能修改LGPL协议的代码
BSD License
BSD License:New BSD License/Modified BSD License 和Simplified BSD License/FreeBSD License。它们两者都是于GPL兼容的自由软件License。商业软件可以使用,也可以修改使用BSD协议的代码。
MIT License
基本没有什么限制,除了必须附有MIT授权协议
Apache License
商业软件可以使用,也可以修改使用Apache协议的代码。
1.需要给代码的用户一份Apache License。
2.如果你修改了代码,需要在被修改的文件中说明。
3.在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
4.如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache License。你可以在Notice中增加自己的许可,但不可以表现为对Apache License构成更改。
Eclipse Public License
EPL是一个与CPL相类似的许可证,任何扩展自Eclipse源码的代码也必须是开源的。
色彩
RGB
rgb为红绿蓝”三原色光“这三种光可以组成各种各样的色彩,这种色彩在机器上由三个数字组成每个数字的取值范围为0~255,当全为255叠加时为白色。
CMY
顾名思义是青(Cyan)、洋红(或品红)(翻译不一样实际上是同一种东西就像生理学和医学是同一个东西)(Magenta)和黄(Yellow)三种颜色的简写,加上黑色(Black)。它减少了为视觉系统识别颜色所需要的反射光。可以将颜色调的更为仔细。一般工业上使用,例如印刷工业。
YUV
这种色彩一般使用的比较少,在外国的电视上使用这种色彩。
YCbCr
YCbCr也是一种常见的色彩系统,JPEG(一种图片的格式,色位和像素比JPG高很多)就是使用的这种色彩。他是由YUV衍生出来的,能强化色彩和像素的清晰度。
图象通道数Channels
在opencv里面的图象通道,其中灰度图的通道数为,彩色图的通道数为3,四通道即为加上了一个透明度的通道,二通道的通道数还未见过,这可能只是为了编程的方便。
在使用灰度图的时候不能给他传递三个通道数,不然会报错。
cv2图片处理常用函数
cv2.waitKey()
cv2.waitKey(0)
cv2.waitKey() 括号里面可以放任意整数,代表的时等待键盘多久时间,单位为毫秒,如果在这段时间内没有检测到键盘的输入,则执行下一步代码,当里面为0时代表一直等待,直到你输入任意一个值结束。
当游戏中想要在任务行动时变换形状,可以使用。
cv2.cv2.cvtColor()
将图片转换为指定的类型例如
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
将img2这张图片转换为灰度图片。COLOR_BGR2GRAY2前面代表BGR格式,2后面代表转换为灰度格式
cv2.threshold()
将图片转换数值进行处理.
cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
小于200的置为0大于200的置为255,cv2.THRESH_BINARY代表要么为白色要么为黑色
cv2.bitwise_not()
将每个像素进行二进制非操作,与其类似的还有cv2.bitwise_add()、cv2.bitwise_not()、cv2.bitwise_xor()
cv2.bitwise_not(mask)
cv2.add()
将两张图片进行相加,但是与numpy加操作不同的是,numpy加操作大于最大值是取溢出值,而此处为取最大值
dst = cv2.add(img1_bg, img2_fg)
给图片添加文字
#添加文字
def cv2ImgAddText(img,text, left=600, top=50, textColor=(255,0, 0), textSize=10):
img2gray = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
#将图片转为数组
img = Image.fromarray(img2gray)
#定义图片可以背用来绘图,原图像会被覆盖
draw = ImageDraw.Draw(img)
#定义字体样式
fontText = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc',textSize, encoding="utf-8")
#对图片进行绘制
draw.text((left,top), text,textColor, font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
具体意义在代码里面有注释,此处就不废话了
opencv库简单使用详解
注意导入图片是需要在此路径下有此代码
import cv2 # 导入 opencv -python 库
from PIL import Image,ImageDraw,ImageFont
import numpy as np
#导入图片
imgmap = cv2.imread('./lib1.jpg')
imgactor = cv2.imread('./lib2.png')
imgcreeps = cv2.imread('./creeps.bmp')
imgactor1 = cv2.imread('./lib.jpg')
#设置图片大小
imgactor = cv2.resize(imgactor, (100, 100))
imgcreeps = cv2.resize(imgcreeps,(100,100))
imgactor1 = cv2.resize(imgactor1,(100,100))
#添加文字
def cv2ImgAddText(img,text, left=600, top=50, textColor=(255,0, 0), textSize=10):
img2gray = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
#将图片转为数组
img = Image.fromarray(img2gray)
#定义图片可以背用来绘图,原图像会被覆盖
draw = ImageDraw.Draw(img)
#定义字体样式
fontText = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc',textSize, encoding="utf-8")
#对图片进行绘制
draw.text((left,top), text,textColor, font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
def image_on_image(img1, img2,img3, x=100, y=100):
#获取图片大小和通道
rows, cols, channels = img2.shape
rows1,cols1,channels1 = img3.shape
roi = img1[0:rows, 0:cols]
#将图片叠加
img1[100:100+rows1,500:500+cols1] = img3
#将图片改为那种色彩cv2.COLOR_BGR2GRAY将BGR格式转换为灰度格式,只有一个通道
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
#将大于200的值置为255小于的值置为0,cv2.THRESH_BINARY灰度图片要么为黑色要么为白色,ret bool代表有没有读取到图片
ret, mask = cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
#将每个像素值进行二进制非操作mask掩膜对指定区域进行遮掩,操作不影响到这块区域
mask_inv = cv2.bitwise_not(mask)
#将每个像素值进行二进制与操作mask掩膜对指定区域进行遮掩,操作不影响到这块区域
img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
#将每个像素值进行二进制非操作mask掩膜对指定区域进行遮掩,操作不影响到这块区域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)
#将两张图片进行相加,当相加值大于最大值时,取最大值
dst = cv2.add(img1_bg, img2_fg)
img1[0 + y:rows + y, 0 + x:cols + x] = dst
#给图片添加文字
image = cv2ImgAddText(img=img1, text="南理RPG",textColor=(0, 255, 0), textSize=20)
cv2.imshow('res', image)
def main():
# image_on_image(img1,img2)
#当前状态,之前状态
cur_flag = -1
pre_flag = -1
#主角坐标
x,y = 100,100
delta = 15 #主角的步伐长度
while True:
#背景图片值拷贝
background = imgmap.copy()
#获取图象大小和通道值
rows, cols, channels = imgmap.shape
#主角图象值拷贝
actor = imgactor.copy()
actor1 = imgactor1.copy()
#野怪图象拷贝值
creeps = imgcreeps.copy()
#获取键盘事件,为0无限等待,其他的以ms为单位等待用户输入,在等待事件内没有输入则返回-1
flag = cv2.waitKey(0)
#Esc,退出
if flag == 27:
break
#判断是否按下其他键
if flag >-1 and flag != pre_flag:
cur_flag = flag
pre_flag = flag
#响应actor移动事件
if cur_flag == ord("w"):
if - delta > 0:
num = 15
else:
num = y
for i in range(num):
y = y - 1
image_on_image(background, actor1, creeps, x, y)
cv2.waitKey(5)
elif cur_flag == ord('s'):
if y + delta < rows - 200:
num = 15
else:
num = cols - y - 200
for i in range(num):
y = y + 1
image_on_image(background, actor1, creeps, x, y)
cv2.waitKey(5)
elif cur_flag == ord('a'):
if x - delta > 0:
num = 15
else:
num = x
for i in range(num):
x = x - 1
image_on_image(background, actor1, creeps, x, y)
cv2.waitKey(5)
elif cur_flag == ord('d'):
if x + delta < cols - 200:
num = 15
else:
num = rows - x - 200
for i in range(num):
x = x + 1
image_on_image(background, actor1, creeps, x, y)
cv2.waitKey(5)
elif cur_flag == ord('f'):
print("开始战斗")
elif cur_flag == ord('t'):
print("开始聊天")
else:
1+1
print("Actor(x,y)=("+str(x)+','+str(y)+")")
image_on_image(imgmap.copy(),actor,creeps,x,y)
#删除所有窗口,如需指定删除窗口则输入特定的窗口值
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
南理文字具体代码
w、s、a、d代表移动,f代表战斗,t键代表聊天
此代码只实现了图片和南理文字的简单结合,还有一些功能之类的还未完善,过两天将更新此代码
代码如下:
"""
有等级,血量,魔法,防御属性
调用100个同属性战斗时需再Fight_With里面的choose_action函数改为choose_action1并多加self.WAY以及int(i/2)值
其他需将Fight_With里面的choose_action1函数改为choose_action并减去self.WAY以及int(i/2)值
问题
2.没有考虑当选择越界问题
"""
# coding = "utf-8"
import time
import random
import threading
import copy
import cv2
from PIL import Image,ImageFont,ImageDraw
import numpy as np
VICTORY = []
SCRIPT_NPC_SCHOOL_SISTER=['你好!',
'你好!',
'你是新生吗?',
'是的',
'想要我教你魔法吗?',
'\n1、好的 \
\n2、不用了吧,我不和学姐学魔法!\n'
]
#世界里的魔法清单
MAGIC_BOOKS={
0:['火魔法',1],
1:['水魔法',2],
2:['土魔法',0.5],
3:["大地之盾",-1]
}
class Body():
ACCACK = 1
def __init__(self,img_,IS_HUMAN_= False,NAME_='Ice NPC',LOCATION_={"x":0,"y":0},WAY_ = [],HP_=5,MP_=3,MAX_HP_=5,MAX_MP_=3,ATTACK_=1,MAGIC_ATTACK_=1.3,DEFENSE_=0,LEVEL_=1,EXPRIENCE_=0,MAX_EXPRIENCE_ = 20,FUNCTION_POINT_=0,HAS_MAGIC_=[],POS_NAME_='南昌理工学院南大门'):
self.IS_HUMAN = IS_HUMAN_ #判断是否位人类
self.NAME = NAME_ #姓名
self.img = img_ #图片
self.LOCATION = LOCATION_ #坐标
self.WAY = WAY_
self.HP = HP_ #血量
self.MP = MP_ #魔法值
self.MAX_HP = MAX_HP_ #最大血量
self.MAX_MP = MAX_MP_ #最大魔法值
self.ATTACK = ATTACK_ #普通攻击
self.MAGIC_ATTACK = MAGIC_ATTACK_ #魔法攻击
self.DEFENSE = DEFENSE_ #防御
self.LEVEL = LEVEL_ #等级
self.EXPERIENCE = EXPRIENCE_ #经验值
self.MAX_EXPERIENCE = MAX_EXPRIENCE_ #升级所需经验值
self.FUNCTION_POINT = FUNCTION_POINT_ #功能点
self.POS_NAME = POS_NAME_ #地点
self.HAS_MAGIC = HAS_MAGIC_ #会的魔法
#加载中文
def cv2ImgAddText(self,textColor=(255,0, 0), textSize=10):
img2gray = cv2.cvtColor(self.img, cv2.COLOR_RGB2BGR)
img = Image.fromarray(img2gray)
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc',textSize, encoding="utf-8")
draw.text((30,10),self.NAME,textColor, font=fontText)
self.img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
def Display_Magic(self): #显示魔法
for i in self.HAS_MAGIC:
print(MAGIC_BOOKS[i][0]+"每次攻击消耗"+str(abs(MAGIC_BOOKS[i][1]))+"点魔法值")
def Display_Status(self): #显示人物状态
print('\n\r', ' 状态:' + self.NAME)
print("等级:"+str(self.LEVEL)+" 距离下次升级还需"+str(self.MAX_EXPERIENCE-self.EXPERIENCE)+"经验", end='')
print('\n血量:' + '❤' * int(self.HP), '\n 魔法值:' + '⚓' * int(self.MP),'\n 防御:' + '🛡' * int(self.DEFENSE))
print('地点:' + self.POS_NAME)
if self.HAS_MAGIC == []:
print('无魔法')
else:
self.Display_Magic()
#展示战斗状态
def display_status_fighting(self):
print('\n\r', ' 状态:' + self.NAME, end='')
print('\n血量:' + '❤' * int(self.HP), ' 魔法值:' + '⚓' * int(self.MP),' 防御:' + '🛡' * int(self.DEFENSE))
def Attack_One_Time(self,CHOOSE,NPC_): #对敌方进行一次攻击
if CHOOSE == -2:
self.Display_Magic()
elif CHOOSE == -1:
hit = 1 - NPC_.DEFENSE
if hit > 0:
NPC_.HP -= hit
print(self.NAME+"使用普攻攻击了"+NPC_.NAME+"造成了"+str(hit)+"点攻击")
else:
print(self.NAME + "使用普攻攻击了" + NPC_.NAME + "造成了0点攻击")
print("无魔法消耗")
else:
#是否有魔法
if CHOOSE in self.HAS_MAGIC:
if self.MP > MAGIC_BOOKS[CHOOSE][1]: #魔法值是否充足
if MAGIC_BOOKS[CHOOSE][1] > 0 :
hit = self.MAGIC_ATTACK * MAGIC_BOOKS[CHOOSE][1] - NPC_.DEFENSE
self.MP -= MAGIC_BOOKS[CHOOSE][1]
if hit > 0:
NPC_.HP -= hit
print(self.NAME + "使用" + MAGIC_BOOKS[CHOOSE][0] + "攻击了" + NPC_.NAME + "造成了" + str(
hit) + "点攻击")
print("消耗了" + str(abs(MAGIC_BOOKS[CHOOSE][1])) + "点魔法")
else:
print(self.NAME + "使用" + MAGIC_BOOKS[CHOOSE][0] + "攻击了" + NPC_.NAME + "造成了0点攻击")
else:
self.MP += MAGIC_BOOKS[CHOOSE][1]
self.HP -= self.MAGIC_ATTACK * MAGIC_BOOKS[CHOOSE][1]
print(self.NAME + "使用" + MAGIC_BOOKS[CHOOSE][0] + "回复了自身" + str(-self.MAGIC_ATTACK * MAGIC_BOOKS[CHOOSE][1])+"点生命值")
else:
print("魔法值不足")
hit = 1 - NPC_.DEFENSE
if hit > 0:
NPC_.HP -= hit
print(self.NAME + "使用普攻攻击了" + NPC_.NAME + "造成了" + str(hit) + "点攻击")
else:
print(self.NAME + "使用普攻攻击了" + NPC_.NAME + "造成了0点攻击")
else:
print("你没有此魔法")
hit = 1 - NPC_.DEFENSE
if hit > 0:
NPC_.HP -= hit
print(self.NAME + "使用普攻攻击了" + NPC_.NAME + "造成了" + str(hit) + "点攻击")
else:
print(self.NAME + "使用普攻攻击了" + NPC_.NAME + "造成了0点攻击")
if NPC_.HP <= 0:
return 1
else:
return 0
def talk_to(self, NPC_, NPC_SCRIPT_, delay=0):
# 按剧本和NPC聊天
print('在' + self.POS_NAME + '遇到 ' + NPC_.NAME)
for i in range(len(NPC_SCRIPT_)):
if i % 2 == 1: # 判断当前说话的人
TURN = self.NAME
else:
TURN = NPC_.NAME
print(TURN + ':' + NPC_SCRIPT_[i])
time.sleep(delay)
def display_magic(self): # 显示魔法
print(self.MP,self.NAME + '会如下几种魔法:')
print('魔法名 ,消耗点数')
i = 0
for iMagic in self.HAS_MAGIC:
print('第', i+1, '个魔法:', MAGIC_BOOKS[iMagic])
i = i + 1
def Learn_Magic_From(self,NPC_): #学习魔法
NPC_.display_magic()
CHOOSE = input("是否学习魔法y/n:")
if CHOOSE == "y":
for i in NPC_.HAS_MAGIC:
print('恭喜'+self.NAME+'学会'+MAGIC_BOOKS[i][0]+
',每次使用消耗'+str(abs(MAGIC_BOOKS[i][1]))+'MP.')
self.HAS_MAGIC.append(i)
self.Display_Magic()
elif CHOOSE == "n":
print("由于你的固执,你只能普攻")
else:
print("不知道你在说什么")
def npc_learn_Magic_from(self,NPC_):
for i in NPC_.HAS_MAGIC:
print('恭喜' + self.NAME + '学会' + MAGIC_BOOKS[i][0] +
',每次使用消耗' + str(abs(MAGIC_BOOKS[i][1])) + 'MP.')
self.HAS_MAGIC.append(i)
self.Display_Magic()
#NPC选择最优攻击方式
def Choose_Action(self,NPC_):
if self.HP < 2:
if 3 in self.HAS_MAGIC:
return 3
else:
HAS_MAGIC = [MAGIC_BOOKS[i][1] for i in self.HAS_MAGIC]
HAS_MAGIC.sort()
HAS_MAGIC.reverse()
for i in HAS_MAGIC:
for key, value in MAGIC_BOOKS.items():
if i in value:
if self.MP >= i:
return key
else:
HAS_MAGIC = [MAGIC_BOOKS[i][1] for i in self.HAS_MAGIC]
HAS_MAGIC.sort()
HAS_MAGIC.reverse()
for i in HAS_MAGIC:
for key, value in MAGIC_BOOKS.items():
if i in value:
if self.MP >= i:
return key
return -1
#同属性战斗
def Choose_Action1(self,NPC_,WAY_,index1):
return WAY_[index1]
#玩家提升属性
def Add_Attribute(self):
print("恭喜你增加经验20")
self.EXPERIENCE += 20
while True:
if self.EXPERIENCE - self.MAX_EXPERIENCE >= 0:
self.LEVEL += 1
self.EXPERIENCE -= self.MAX_EXPERIENCE
self.MAX_EXPERIENCE *= 2
FUNCYTION_POINT = self.FUNCTION_POINT + self.LEVEL * 2 + 2
self.FUNCTION_POINT += FUNCYTION_POINT
print("恭喜等级提升到" + str(self.LEVEL) + "级", "\n 获得" + str(FUNCYTION_POINT) + "点功能点,可用来提升属性")
# 防止一次提升多次等级
if self.EXPERIENCE - self.MAX_EXPERIENCE < 0:
break
self.Display_Status()
for i in range(self.FUNCTION_POINT):
CHOOSE = input("你需要提升哪个属性?(HP/MP/DEFENCE)")
if CHOOSE == "HP":
self.HP += 1
elif CHOOSE == "MP":
self.MP += 1
elif CHOOSE == "DEFENCE":
self.DEFENSE += 1
self.Display_Status()
#挑战NPC
def Fight_With(self,NPC_):
print('【', self.NAME + '开始和' + NPC_.NAME + '战斗! !', '】')
MAX_ROUND = 100
IS_DEAD = 0
for i in range(MAX_ROUND):
if i%2==0:
if self.IS_HUMAN:
self.display_status_fighting() # 显示玩家状态
self.Display_Magic() # 显示玩家魔法
NPC_.display_status_fighting() # 显示NPC状态
HAS_MAGIC = []
for j in self.HAS_MAGIC:
HAS_MAGIC.append(str(j))
HAS_MAGIC = "/".join(HAS_MAGIC)
choose_magic = int(input('-----使用魔法/普通攻击(-1普通攻击,{}.魔法攻击,查看状态-2):'.format(HAS_MAGIC)))
IS_DEAD = self.Attack_One_Time(NPC_=NPC_, CHOOSE=choose_magic)
IS_DEAD = IS_DEAD * 2 # 用乘法,让我们不改变0,非0状态的情况下,标记是谁赢了
else:
choose_action = self.Choose_Action(NPC_)
IS_DEAD = self.Attack_One_Time(NPC_=NPC_, CHOOSE=choose_action)
IS_DEAD *= 2
if i%2 == 1:
if not NPC_.IS_HUMAN:
choose_action = NPC_.Choose_Action(self)
IS_DEAD = NPC_.Attack_One_Time(NPC_=self, CHOOSE=choose_action)
else:
self.display_status_fighting() # 显示玩家状态
self.Display_Magic() # 显示玩家魔法
NPC_.Display_Status() # 显示NPC状态
HAS_MAGIC = []
for j in self.HAS_MAGIC:
HAS_MAGIC.append(str(j))
HAS_MAGIC = "/".join(HAS_MAGIC)
choose_magic = int(input('-----使用魔法/普通攻击(-1普通攻击,{}.魔法攻击,查看状态-2):'.format(HAS_MAGIC)))
IS_DEAD = self.Attack_One_Time(NPC_=NPC_, CHOOSE=choose_magic)
IS_DEAD = IS_DEAD*4 #用乘法,让我们不改变0,非0状态的情况下,标记是谁赢了
if IS_DEAD>=1:
print('【战斗结束】')
#恢复状态
self.HP = self.MAX_HP
self.MP = self.MAX_MP
NPC_.MP = NPC_.MAX_MP
NPC_.HP = NPC_.MAX_HP
#判断胜利者
if IS_DEAD==2:
print('【',self.NAME+'战胜了'+NPC_.NAME,'】')
VICTORY.append(self)
if self.IS_HUMAN:
self.Add_Attribute()
elif IS_DEAD==4:
VICTORY.append(NPC_)
print('【',NPC_.NAME+'战胜了'+self.NAME,'】')
if NPC_.IS_HUMAN:
NPC_.Add_Attribute()
return IS_DEAD
else:
if i % 2 == 1:
print('【第' + str(1 + int(i / 2)) + '回合结束!】\n===================================')
class World:
# import sys
# # 如果确实需要很深的递归深度,可以使用sys模块中的setrecursionlimit()函数修改默认的最大深度限制。
# sys.setrecursionlimit(10000)
imgactor = cv2.imread('./lib2.png')
imgcreeps = cv2.imread('./creeps.bmp')
img2 = cv2.resize(imgactor, (100, 100))
img3 = cv2.resize(imgcreeps, (100, 100))
PLAYER = Body(DEFENSE_=0.5,IS_HUMAN_=True,img_= img2)
def __init__(self):
self.NPCs = {
'school elder sister': Body(NAME_='school elder sister',LOCATION_={"x":100,"y":500}, HAS_MAGIC_=[0, 1,3],img_=self.img3),
'ice monster': Body(NAME_='ice monster', LOCATION_={"x":100,"y":500},HAS_MAGIC_=[2],img_=self.img3),
'fire monster': Body(NAME_='fire monster', LOCATION_={"x":100,"y":500},HAS_MAGIC_=[0],img_=self.img3)
}
print("欢迎来到南理文字游戏")
self.PLAYER.NAME = input("请输入玩家姓名")
self.PLAYER.cv2ImgAddText()
print('....南理文字RPG0.2的世界开始了.....')
welcome_script = 'Hi,' + self.PLAYER.NAME + ',欢迎加入南理文字RPG0.2 '
# self.display_a_line(script=welcome_script)
print(welcome_script)
#给图片添加中文
def cv2ImgAddText(self,img, text, left=600, top=50, textColor=(255, 0, 0), textSize=10):
img2gray = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
img = Image.fromarray(img2gray)
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc', textSize, encoding="utf-8")
draw.text((left, top), text, textColor, font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
#展示画面
def image_on_image(self,img1,NPC,actor=None,num=0):
img = img1
if num == 0:
img2 = self.PLAYER.img
else:
img2 = actor
img3 = NPC.img
x = self.PLAYER.LOCATION["x"]
y = self.PLAYER.LOCATION["y"]
x1 = NPC.LOCATION["x"]
y1 = NPC.LOCATION["y"]
rows, cols, channels = self.PLAYER.img.shape
rows1, cols1, channels1 = NPC.img.shape
roi = img1[0 + y:rows + y, 0 + x:cols + x]
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 235, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)
dst = cv2.add(img1_bg, img2_fg)
img1[100 + y1:100 + y1 + rows1, 500 + x1:500 + x1 + cols1] = img3
img1[0 + y:rows + y, 0 + x:cols + x] = dst
image = self.cv2ImgAddText(img=img1, text="南理RPG", textColor=(0, 255, 0), textSize=20)
cv2.imshow('res', image)
return img1
def self_NPC_(self):
NPCs = []
t = []
for i in range(10):
NPC = Body(NAME_="NPC"+str(i),HP_=random.randint(3,6),MP_=random.randint(2,4),HAS_MAGIC_=[random.randint(0,3) for i in range(2)])
NPCs.append(NPC)
VICTORY.append(NPC)
for i in range(5):
NPC1 = random.choice(NPCs)
NPCs.remove(NPC1)
NPC2 = random.choice(NPCs)
NPCs.remove(NPC2)
t1 = threading.Thread(target=self.NPC,args=(NPC1,NPC2))
t.append(t1)
#开启线程
for i in t:
i.start()
#NPC遭遇
def NPC(self,NPC1,NPC2):
print(NPC1.NAME + "与" + NPC2.NAME)
NPC1.talk_to(NPC_=NPC2, NPC_SCRIPT_=SCRIPT_NPC_SCHOOL_SISTER)
NPC1.npc_learn_Magic_from(NPC2)
NPC1.Fight_With(NPC2)
#NPC比赛
def Game(self):
SILVER_MEDAL = []
BRONZE_MEDAL = []
t = []
for i in range(100):
NPC = Body(NAME_="NPC"+str(i),HP_=random.randint(3,6),MP_=random.randint(2,4),HAS_MAGIC_=[random.randint(0,3) for i in range(2)])
VICTORY.append(NPC)
while len(VICTORY) > 1:
if len(VICTORY) == 4:
BRONZE_MEDAL.extend(VICTORY)
if len(VICTORY) == 2:
SILVER_MEDAL.extend(VICTORY)
for i in range(int(len(VICTORY)/2)):
NPC1 = random.choice(VICTORY)
VICTORY.remove(NPC1)
NPC2 = random.choice(VICTORY)
VICTORY.remove(NPC2)
t1 = threading.Thread(target=NPC1.Fight_With, args=(NPC2,))
t.append(t1)
t1.start()
for i in t:
i.join()
player = [i.NAME for i in VICTORY]
print(player)
VICTORY1 = copy.deepcopy(VICTORY)
BRONZE_MEDAL = list(set(BRONZE_MEDAL) - set(SILVER_MEDAL))
SILVER_MEDAL = list(set(SILVER_MEDAL) - set(VICTORY))
VICTORY.clear()
BRONZE_MEDAL[0].Fight_With(BRONZE_MEDAL[1])
print("金牌:",VICTORY1[0].NAME)
print("银牌:",SILVER_MEDAL[0].NAME)
print("铜牌:",VICTORY[0].NAME)
#npc同属性战斗
def With_Game(self):
SILVER_MEDAL = []
BRONZE_MEDAL = []
t = []
for i in range(20):
NPC = Body(NAME_="NPC" + str(i), HP_=5, MP_=3,
HAS_MAGIC_=[0,1,3],WAY_= [1,1,0,3,-1,-1,-1,-1])
VICTORY.append(NPC)
for i in range(20,40):
NPC = Body(NAME_="NPC" + str(i), HP_=5, MP_=3,
HAS_MAGIC_=[0, 1, 3], WAY_=[0, 1, 0, 3, -1, -1, -1, -1])
VICTORY.append(NPC)
for i in range(40,60):
NPC = Body(NAME_="NPC" + str(i), HP_=5, MP_=3,
HAS_MAGIC_=[0,1,3],WAY_= [0,0,3,-1,-1,-1,-1,-1])
VICTORY.append(NPC)
for i in range(60,80):
NPC = Body(NAME_="NPC" + str(i), HP_=5, MP_=3,
HAS_MAGIC_=[0,1,3],WAY_= [1,1,3,-1,-1,-1,-1,-1])
VICTORY.append(NPC)
for i in range(80,100):
NPC = Body(NAME_="NPC" + str(i), HP_=5, MP_=3,
HAS_MAGIC_=[0,1,3],WAY_= [-1,-1,0,3,0,-1,-1,-1])
VICTORY.append(NPC)
while len(VICTORY) > 1:
if len(VICTORY) == 4:
BRONZE_MEDAL.extend(VICTORY)
if len(VICTORY) == 2:
SILVER_MEDAL.extend(VICTORY)
for i in range(int(len(VICTORY) / 2)):
NPC1 = random.choice(VICTORY)
VICTORY.remove(NPC1)
NPC2 = random.choice(VICTORY)
VICTORY.remove(NPC2)
t1 = threading.Thread(target=NPC1.Fight_With, args=(NPC2,))
t.append(t1)
t1.start()
for i in t:
i.join()
player = [i.NAME for i in VICTORY]
print(player)
VICTORY1 = copy.deepcopy(VICTORY)
BRONZE_MEDAL = list(set(BRONZE_MEDAL) - set(SILVER_MEDAL))
SILVER_MEDAL = list(set(SILVER_MEDAL) - set(VICTORY))
VICTORY.clear()
BRONZE_MEDAL[0].Fight_With(BRONZE_MEDAL[1])
print("金牌:", VICTORY1[0].NAME)
print("银牌:", SILVER_MEDAL[0].NAME)
print("铜牌:", VICTORY[0].NAME)
#随机选择NPC进行交流,学习,战斗
def Draw_NPC(self):
NPCs = [i for i in self.NPCs.keys()]
num = random.randint(0,len(NPCs)-1)
return self.NPCs[NPCs[num]]
#实现逻辑
def run(self):
# 随机选择NPVC
NPC_ = self.Draw_NPC()
#背景图片
img1 = cv2.imread('./lib1.jpg')
actor = cv2.imread('./lib.jpg')
actor = cv2.resize(actor,(100,100))
# 当前状态,之前状态
cur_flag = -1
pre_flag = -1
delta = 15 # 主角的步伐长度
while True:
#背景图片值拷贝
imgmap = img1.copy()
rows,cols,channels = imgmap.shape
print(rows,cols)
# 获取键盘事件,为0无限等待,其他的以ms为单位等待用户输入,在等待事件内没有输入则返回-1
flag = cv2.waitKey(0)
# Esc,退出
if flag == 27:
break
# 判断是否按下其他键
if flag > -1 and flag != pre_flag:
cur_flag = flag
pre_flag = flag
# 响应actor移动事件
if cur_flag == ord("w"):
if self.PLAYER.LOCATION["y"] - delta >0:
num = 15
else:
num = self.PLAYER.LOCATION["y"]
for i in range(num):
self.PLAYER.LOCATION["y"] = self.PLAYER.LOCATION["y"] - 1
self.image_on_image(img1=imgmap,actor=actor,NPC=NPC_,num=1)
cv2.waitKey(5)
elif cur_flag == ord('s'):
if self.PLAYER.LOCATION["y"] + delta < rows-200:
num = 15
else:
num = cols - self.PLAYER.LOCATION["y"]-200
for i in range(num):
self.PLAYER.LOCATION["y"] = self.PLAYER.LOCATION["y"] + 1
self.image_on_image(img1=imgmap,actor=actor, NPC=NPC_,num=1)
cv2.waitKey(5)
elif cur_flag == ord('a'):
if self.PLAYER.LOCATION["x"] - delta >0:
num = 15
else:
num = self.PLAYER.LOCATION["x"]
for i in range(num):
self.PLAYER.LOCATION["x"] = self.PLAYER.LOCATION["x"] - 1
self.image_on_image(img1=imgmap, actor=actor,NPC=NPC_,num=1)
cv2.waitKey(5)
elif cur_flag == ord('d'):
if self.PLAYER.LOCATION["x"] + delta < cols-200:
num = 15
else:
num = rows - self.PLAYER.LOCATION["x"]-200
for i in range(num):
self.PLAYER.LOCATION["x"] = self.PLAYER.LOCATION["x"] + 1
self.image_on_image(img1=imgmap,actor=actor, NPC=NPC_,num=1)
cv2.waitKey(5)
elif cur_flag == ord('f'):
# 随机挑战NPC
# NPC_ = self.Draw_NPC()
self.PLAYER.Fight_With(NPC_)
elif cur_flag == ord('t'):
# 遭遇NPC
self.PLAYER.talk_to(NPC_=NPC_, NPC_SCRIPT_=SCRIPT_NPC_SCHOOL_SISTER)
elif cur_flag == ord('l'):
# 向NPC进行学习
self.PLAYER.Learn_Magic_From(NPC_)
else:
1 + 1
print("Actor(x,y)=(" + str(self.PLAYER.LOCATION["x"]) + ',' + str(self.PLAYER.LOCATION["y"]) + ")")
self.image_on_image(img1=imgmap, NPC=NPC_)
# 删除所有窗口,如需指定删除窗口则输入特定的窗口值
cv2.destroyAllWindows()
#展示人物状态
self.PLAYER.Display_Status()
if __name__ == "__main__":
magic_world = World()
# #npc遭遇、交流、战斗
# magic_world.self_NPC_()
#玩家
magic_world.run()
# #npc比赛
# magic_world.Game()
# #npc同属性下比赛
# magic_world.With_Game()
物品框概想
主角的物品框可以使用一个二维数组来一个代表存放的物品,一个代表最大可以存放的量,一个代表存储的量。
参考:
本人学习所创,如有错误请多多指教
联系QQ1135999353