你好!
今天,我将详细描述如何在命令行上制作游戏,以及游戏的效果如何。
这个想法从何而来?
乍一看让我感到很受启发的想法,但同时在开发方面也很有趣。我想到了在游戏机中制作游戏的想法,这在开发方面很有趣,而且即使从外部(例如这款游戏)来看,也很有趣。
游戏引擎
因此,让我们从游戏的根本结构开始,以及它的工作理念是什么。
首先,我决定如何在游戏机上显示游戏世界。我意识到,为了显示游戏对象,我们需要一个列表,该列表存储包含符号的其他列表,这些列表随后在循环中显示在游戏场上
for
。
使用此代码:
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
在这里,我们从列表中绘制所有字符,然后转到新行以绘制下一个字符列表。
这就是存储符号列表的变量的样子:

在这里,我们立即决定如何在X和Y中显示对象,我们现在可以指定:
X-列表中的符号
Y-包含X的列表
因此,在字段上绘制一些符号...我们将在绘制游戏对象时使用它。
我们可以尝试在场上画一个“球”,用字母“ O”代替X和Y。
为此,请编写以下代码:
import os
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
OUTPUT_IMAGE[4][6] = "O"
os.system("cls||clear")
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")

因此,我们在运动场上绘制了一个对象。是的,X和Y坐标不是经典的。首先,我们先指出Y,然后再指出X,这不太符合经典,其次,为了增加物体,Y坐标应该增加,相反,在我们的情况下,Y坐标应该减少。
游戏中X和Y的图形:

稍后在控制台中发生对象碰撞时,也必须考虑此功能。
现在,我们可以尝试在运动场上移动我们的对象,即创造运动。
我们将需要清除控制台,以擦除比赛场地的旧图像。
我们将使用以下命令执行此操作:
os.system("cls||clear")
另外,我们需要覆盖变量
OUTPUT_IMAGE
,以清除先前在游戏场中绘制的所有对象。
我们还需要将所有这些都放入
while True
。
让我们添加
while True
功能time.sleep(1)
以限制FPS。
因此,代码被绘制在我们眼前:
from time import sleep
from os import system
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
x = 0
y = 0
while True:
sleep(1)
system("cls||clear")
OUTPUT_IMAGE[y][x] = "O"
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
y += 1
x += 1
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]

现在,我们可以在整个字段中分布对象。
的确,这些对象太原始了,我们将必须学习如何绘制复杂的对象,例如玩家,房屋,食物...
为了绘制一个复杂的对象,我们需要通过仅指定一次X和Y来了解并弄清楚如何绘制一个对象
。为此,我们需要接受图片(符号)X,Y的函数;
我们开工吧:
def SetImage(image: str, x: int, y: int):
pass
现在我们需要实现它。为此,您需要决定如何绘制沿X和Y轴延伸的图像,我想到了这一点:
通过将对象划分为符号来绘制对象,并在遇到“ \ n”字符后立即添加Y轴。
如我们所说,Y轴是不正确的,反向,因此我们添加它以降低对象。
根据我的原理绘制的图像示例:
image = " O\n'|'\n |"#
现在让我们在函数中对此进行描述:
def SetImage(x: int, y: int, image: str):
x_start = x
x = x
y = y
for word in image:
if word == "\n":
x = x_start
y += 1
else:
x += 1
try:
OUTPUT_IMAGE[y][x] = word
except IndexError:
break
try: except()
为了避免出现错误,如果对象的X和Y太小或太大,
我们添加。
x_start
这是X,增加Y时需要从此处开始绘制(带有“ \ n”
字符)现在我们可以使用我们的函数,将X和Y放到其中,然后绘制需要绘制的图片:
代码
from time import sleep
from os import system
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
def SetImage(x: int, y: int, image: str):
x_start = x
x = x
y = y
for word in image:
if word == "\n":
x = x_start
y += 1
else:
x += 1
try:
OUTPUT_IMAGE[y][x] = word
except IndexError:
break
while True:
sleep(1)
system("cls||clear")
SetImage(x=3,y=4,image=" O\n'|'\n |")
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
这就是我们得到的:

就像我们画的球一样,它可以沿X和Y轴移动。
代码
from time import sleep
from os import system
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
px = 0
py = 0
def SetImage(x: int, y: int, image: str):
x_start = x
x = x
y = y
for word in image:
if word == "\n":
x = x_start
y += 1
else:
x += 1
try:
OUTPUT_IMAGE[y][x] = word
except IndexError:
break
while True:
sleep(1)
system("cls||clear")
SetImage(x=px,y=py,image=" O\n'|'\n |")
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
px += 1
py += 1
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]

现在,玩家已经在地图上移动。
在这里,我们已经做了很多事情,已经有一个玩家,已经有一个地图,似乎已经可以制作游戏了,但是没有。我们需要一个函数来计算物体的碰撞,因为没有物体相互作用的游戏是什么?因此,让我们开始吧。
首先,我们需要创建一个函数来获取对象的纬度和高度,以便计算其命中框。
所以,我决定根据以下逻辑来使函数:
X -在X宽的物体的击中格,这是字符之间的最大字符数“\ n”个画面
ÿ - Y中的击中格是字符数“\ n”个图像
通过该逻辑不难制作一个拍摄图片的功能,为其计算“ \ n”之间的所有字符,然后从中选择最大数量的字符-获得纬度。
如我已经写过的,如果算上字符“ \ n”,就可以得到高度。
结果是这样的:
def GetSizeObject(img: str):
w = 0
weights = []
h = [word for word in img if word == "\n"]
for word in img:
if word == "\n":
weights.append(w)
w = 0
else:
w += 1
try:
return {"w": max(weights), "h":len(h)}
except ValueError:
return {"w": 0, "h":0}
为什么ValueError除了这里?
.
因此,让我们绘制播放器,并计算其宽度和长度。
绘图和计算纬度和高度的代码
from time import sleep
from os import system
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
px = 3
py = 3
def SetImage(x: int, y: int, image: str):
global OUTPUT_IMAGE
x_start = x
x = x
y = y
for word in image:
if word == "\n":
x = x_start
y += 1
else:
x += 1
try:
OUTPUT_IMAGE[y][x] = word
except IndexError:
break
def GetSizeObject(img: str):
w = 0
weights = []
h = [word for word in img if word == "\n"]
h.append(1)
for word in img:
if word == "\n":
weights.append(w)
w = 0
else:
w += 1
try:
return {"w": max(weights), "h":len(h)}
except ValueError:
return {"w": 0, "h":0}
player_image = " O\n'|'\n |"
def draw():
global OUTPUT_IMAGE
sleep(1)
system("cls||clear")
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
while True:
SetImage(x=px,y=py,image=player_image)
print(GetSizeObject(img=player_image))
draw()
万岁!我们有一个用于计算纬度和高度的函数,现在我们必须有一个用于计算对象的点击框和碰撞的函数。
让我们记住,我们的坐标系不是经典坐标系,所以,a,我们不能使用经典函数,我们必须自己创建。为此,我在发生碰撞的图形上绘制了2个正方形,从这张图片中可以得出计算碰撞的条件。
为了便于理解,我绘制了Hitboxs,即 方格:

言语逻辑
x — X
y — Y
h —
w —
x2 — X
y2 — Y
h2 —
w2 —
:
X, Y,
:
X
x — X
y — Y
h —
w —
x2 — X
y2 — Y
h2 —
w2 —
:
y
y2 - h2 + h
y - h
y2 + h2 - h
y2
y - h + h2
y2 - h2
y + h - h2
2 ?
2 , - / .
Y
Y
X, Y,
y
— x
, h
— w
.
:
x
x2 - w2 + w
x - w
x2 + w2 - w
x2
x - w + w2
x2 - w2
x + w - w2
X
代码中的逻辑
, :
def IsClash(x: int, y: int, h: int, w: int,x2: int, y2: int, h2: int, w2: int):
if (y >= y2 - h2 + h and y - h <= y2 + h2 - h) or (y2 >= y - h + h2 and y2 - h2 <= y + h - h2):
if (x >= x2 - w2 + w and x - w <= x2 + w2 - w) or (x2 >= x - w + w2 and x2 - w2 <= x + w - w2):
return True
return False
True
, False
.
我在比赛场地上画了一个额外的方块,以便玩家面对某人。
我尝试了碰撞计算功能的工作原理。
这是一个碰立方体的玩家:

但不要碰:

联络电话
/ :
from time import sleep
from os import system
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
def SetImage(x: int, y: int, image: str):
global OUTPUT_IMAGE
x_start = x
x = x
y = y
for word in image:
if word == "\n":
x = x_start
y += 1
else:
x += 1
try:
OUTPUT_IMAGE[y][x] = word
except IndexError:
break
def GetSizeObject(img: str):
w = 0
weights = []
h = [word for word in img if word == "\n"]
h.append(1)
for word in img:
if word == "\n":
weights.append(w)
w = 0
else:
w += 1
try:
return {"w": max(weights), "h":len(h)}
except ValueError:
return {"w": 0, "h":0}
def IsClash(x: int, y: int, h: int, w: int,x2: int, y2: int, h2: int, w2: int):
if (y >= y2 - h2 + h and y - h <= y2 + h2 - h) or (y2 >= y - h + h2 and y2 - h2 <= y + h - h2):
if (x >= x2 - w2 + w and x - w <= x2 + w2 - w) or (x2 >= x - w + w2 and x2 - w2 <= x + w - w2):
return True
return False
player_image = " O\n'|'\n |"
cube_image = "____\n| |\n----"
cx = 5#
cy = 4 #
px = 10 #
py = 3#
def draw():
global OUTPUT_IMAGE
sleep(1)
system("cls||clear")
for line_words in OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
OUTPUT_IMAGE = [
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
[".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".",],
]
while True:
SetImage(x=px,y=py,image=player_image)
SetImage(x=cx,y=cy,image=cube_image)
print("is clash: ",IsClash(
x=px,
x2=cx,
y=py,
y2=cy,
h=GetSizeObject(img=player_image)["h"],
h2=GetSizeObject(img=cube_image)["h"],
w=GetSizeObject(img=player_image)["w"],
w2=GetSizeObject(img=cube_image)["w"],
))
draw()
现在我们有了游戏的所有启动功能,事实上,我是根据这些功能编写的。
一个游戏
游戏的想法如下:
有一个玩家,他周围出现食物,他被迫收集以免死亡。该游戏还具有以下功能:拾取食物,放入库存,从库存中吃东西,从库存中将
物品放到地板上。我首先在3行游戏循环中开始,这很简单
While True
:
from time import sleep
while True:
sleep(0.1)
然后,我认为有必要创建一个类,在其中存储将来对象的所有功能。因此,我创建了一个main.py文件和一个lib文件夹,在其中放置了游戏类所在的lib.py文件。那些。游戏文件如下所示:
+----game
| + --
| | -- main.py
| \ --lib
| +--lib.py -> class Game()
| \
|
+---
以后,我主要在main.py中使用Game()类,我只是简单地调用它,创建起始对象并启动游戏。
在游戏类中,我创建了一个run()函数来启动游戏循环。还具有draw_all()函数,它会擦除所有过去的对象,绘制新的对象,并打印到运动场。
这是该类的样子:
from time import sleep
class Game():
def __init__(self):
self.OUTPUT_IMAGE = [] #
def draw_all(self):
for line_words in self.OUTPUT_IMAGE:
for word in line_words:
print(word, end="")
print("\n", end="")
def run(self):
while True:
self.draw_all()
sleep(0.1)
我加了类型的所有基本功能
set_image()
, size_object()
,is_clash()
,和所有那些谁是游戏引擎,以及我在上面已经描述。
作出了新的功能
create_object()
和变量self.OBJECTS
,函数create_object()
我用它来创建对象,它需要的参数img
,name
,x
,y
,up
,rigid
,data
。
img
-对象图片-对象
name
名称(房屋,草地,居民,食物等)
x
-X对象
y
-Y对象
up
-如果此参数为True,则将对象绘制在玩家身上,否则玩家将其重叠
rigid
-硬度,玩家无法遍历此对象(尚未实现)
data
-对象的个人数据,其个人特征
create_object()
:
def CreateObject(self,x: int, y: int, img: str, name: str = None, up: bool = False, rigid: bool = False, data: dict = {}):
size_object = self.GetSizeObject(img=img)
self.OBJECTS.append(
{"name": name,
"x": x,
"y": y,
"up": up,
"rigid": rigid,
"h":size_object["h"],
"w":size_object["w"],
"id":uuid4().hex,
"data":data,
"img": img}
)
那时,我已经添加了一个玩家,一所房子,一棵草和一个村民。
我决定在对象
up
中使用相同的参数,在对象中使用它Home
,即这样房子才能覆盖玩家。为此,我创建了CheckAll()函数,一个for循环遍历了所有对象,并将它们绘制在输出图片上,即使用SetImage(x:int,y:int,img:str)函数,提供对象的X和Y以及图片。
因此,他绘制了玩家可以关闭自己的对象。在同一周期中,我声明了一个list
up_of_payer_objects
,并且如果对象的up = True,则将其添加到列表中而不在字段上绘制它。之后,我自己绘制了播放器,然后才在up_of_payer_objects中的对象上进行for循环,将它们绘制出来,因此它们位于播放器上方。
def CheckAll(self):
up_of_payer_objects = []
for object_now in range(len(self.OBJECTS)):
if object_now["up"]:
up_of_payer_objects.append(object_now)
continue
self.SetImage(x=object_now["x"],y=object_now["y"],image=object_now["img"])
然后我开始移动播放器。为此,我将其创建为一个单独的对象,该对象不在列表中
self.OBJECTS
,但存储在变量中self.PLAYER
。
它的所有参数根据类型
X
,Y
,img
,ITP您可以使用键来获取它,换句话说,它是字典(dict)。使用这样的播放器和物体,已经可以进行工作,移动和计算碰撞。我从搬家开始。
我开始通过执行CheckKeysObjects()函数来创建运动,该函数负责跟踪击键,并且从一开始就在CheckAll()函数中进行调用
def CheckAll(self):
self.CheckKeysObjects()
....
为了跟踪击键,我使用了键盘库和4个变量: 事实证明一切都很简单,我们跟踪键,如果按下了键,就创建一个变量。 在函数的最开始,我们在中声明所有变量,以重置所有过去的结果,否则播放器不会停止。
self.WALK_LEFT_PLAYER
self.WALK_RIGHT_PLAYER
self.WALK_UP_PLAYER
self.WALK_DOWN_PLAYER
d
self.WALK_RIGHT_PLAYER
True
False
CheckKeysObjects()
def CheckKeysObjects(self):
# False,
self.WALK_LEFT_PLAYER = False
self.WALK_RIGHT_PLAYER = False
self.WALK_UP_PLAYER = False
self.WALK_DOWN_PLAYER = False
#
if keyboard.is_pressed("a"):
self.WALK_LEFT_PLAYER = True
elif keyboard.is_pressed("d"):
self.WALK_RIGHT_PLAYER = True
if keyboard.is_pressed("w"):
self.WALK_UP_PLAYER = True
elif keyboard.is_pressed("s"):
self.WALK_DOWN_PLAYER = True
之后,在函数中,我
CheckAll()
检查负责移动的所有变量,找出玩家正在移动的位置。
如果存在
True
,请找出其中一个,然后沿相反方向移动对象。
产生的运动代码
def CheckAll(self):
self.CheckKeysObjects() # check moves
up_of_payer_objects = []
for object_now in range(len(self.OBJECTS)):
self.PLAYER["img"] = self.PLAYER["image_normal"]
if self.WALK_LEFT_PLAYER:
self.OBJECTS[object_now]["x"] += 1
elif self.WALK_RIGHT_PLAYER:
self.OBJECTS[object_now]["x"] -= 1
if self.WALK_UP_PLAYER:
self.OBJECTS[object_now]["y"] += 1
elif self.WALK_DOWN_PLAYER:
self.OBJECTS[object_now]["y"] -= 1
是的,我们朝相反的方向移动物体以产生运动的错觉。如果玩家向右移动,那么环境中的所有对象都会向左移动。
然后我添加了更多的环境物品,并开始产卵,玩家的目标是收集食物,以免死亡。
对于食物产生时间的倒计时,我使用了一个简单的程序
time.sleep()
和一个库threading
-为了同时运行2个功能,食物产生和主游戏循环。食物生成函数SpawnEat()
只是一个函数,当启动该函数时,它会在随机的位置生成食物,并为每个食物单位调用一个函数CreateObject()
。
而且,一旦我完成了食物生成功能,就使播放器变了
self.PLAYER["hungry"]
,这是他的饥饿感,一开始它等于100个单位,如果玩家走路并花费能量(例如能量,不在游戏中),我将减少饥饿感;如果玩家吃了东西,则增加饥饿感。
我还做了一个函数
MinimizeHungry()
,它每5秒调用一次,它只需要从播放器中饥饿2个单位即可。我这样做是为了让玩家不得不移动,而不是停滞不前。
最后,在函数中
Eat()
,该函数在与游戏循环不同的线程上调用。她检查地图上是否有太多食物,如果食物超过10个单位。SpawnEat()
如果少于10个单位,则不会调用该函数。然后打电话SpawnEat()
。
结果是这样的:
吃 ()
def Eat(self):
while True:
sleep(4)
if len([i for i in self.OBJECTS if i["name"] == "meat"]) < 10:
self.SpawnEat()
sleep(1)
self.MinimizeHungry()
功能
Start()
来启动主循环:
开始()
def Start(self):
while True:
self.CheckAll()
self.DrawAll()
sleep(0.01)
并
run()
启动整个游戏的功能。
跑 ()
def run(self):
proc1 = threading.Thread(target=self.Start)
proc1.start()
proc2 = threading.Thread(target=self.Eat)
proc2.start()
就餐本身的过程,我仅在函数
CheckAll()
和中实现CheckKeysObjects()
。问:CheckKeysObjects()
我检查了玩家是否按下了按钮E
。如果按下,则将变量放入self.PRESS_E
中True
。
在循环中
CheckAll()
,我检查了循环中的当前对象是否是for
食物,食物是否没有检查玩家是否与食物相撞,如果食物相撞,则检查了变量self.PRESS_E
,然后它True
只是删除了该对象并增加了饥饿感,即 可变的self.PLAYER["hungry"]
。
这就是代码中的样子
for object_now in range(len(self.OBJECTS)):
....
if self.OBJECTS[object_now]["name"] == "meat":
items_objects.append(object_now)
is_clash = self.IsClash(
x=self.OBJECTS[object_now]["x"],
y=self.OBJECTS[object_now]["y"],
h=self.OBJECTS[object_now]["h"],
w=self.OBJECTS[object_now]["w"],
x2=self.PLAYER["x"],
y2=self.PLAYER["y"],
h2=self.PLAYER["h"],
w2=self.PLAYER["w"],
)
if is_clash:
if self.PRESS_E:
try:
self.PLAYER["hungry"] += self.HUNGRUY_ADD
del self.OBJECTS[object_now]
break
except IndexError:
pass
我先说,做库存时我需要重写所有这些内容
盘点
因此,很难,我们需要进行盘点。
困难在于,所有对象都需要在地板上显示,存储历史记录,删除,放置对象。
首先,向播放器添加一个新密钥,它是
self.PLAYER["inventory"]
,其中存储了4个单元格,如下所示:
"inventory":{
"0":{"status":"space","name":"#0", "minimize_image":"#0"},
"1":{"status":"space","name":"#1", "minimize_image":"#1"},
"2":{"status":"space","name":"#2", "minimize_image":"#2"},
"3":{"status":"space","name":"#3", "minimize_image":"#3"},
}
只是单元格编号。
status
-此键存储卵单元是否为空的值。如果为空,则为“空格”,如果有项,则该项的名称存储在此。
name
-存储物品的名称,当玩家放置物品时将使用该名称。
minimize_image
-这是播放器清单中显示的物品的一小张图片。
之后,我对我们进行了新的检查
CheckKeysObjects()
,当您单击该X
项目时,它将被扔到地上,并且当您单击按钮时,该E
函数将被称为self.UseEat()
,我们现在将对其进行分析。
所以功能
self.UseEat()
是通过库存中所有单元的通道,以寻找食物,如果找到了食物,则将其从库存中移除,并将10个单位添加到饥饿中。为了从库存中删除项目,我创建了一个函数self.DestroyItem()
,其中提供了单元格索引,并且默认情况下整个单元格只是空着,没有任何内容。
self.DestroyItem()
def DestroyItem(self,index_item: str):
item = self.PLAYER["inventory"][index_item]
self.PLAYER["inventory"][index_item] = self.PLAYER["default_inventory_item"](index_item)
self.PLAYER["inventory_must_update"] = True
return item
self.CheckKeysObjects()
def CheckKeysObjects(self):
self.WALK_LEFT_PLAYER = False
self.WALK_RIGHT_PLAYER = False
self.WALK_UP_PLAYER = False
self.WALK_DOWN_PLAYER = False
if key("a"):
self.WALK_LEFT_PLAYER = True
elif key("d"):
self.WALK_RIGHT_PLAYER = True
if key("w"):
self.WALK_UP_PLAYER = True
elif key("s"):
self.WALK_DOWN_PLAYER = True
if key("f"):
self.KEY_F = True
else:
self.KEY_F= False
if key("e"):
self.UseEat()
self.UseEat()
def UseEat(self):
for inventory_item in range(len(self.PLAYER["inventory"])):
if self.PLAYER["inventory"][str(inventory_item)]["name"] == "meat":
if self.PLAYER["hungry"] + self.ADD_HUNGRY_COUNT < 100.0:
self.PLAYER["hungry"] += self.ADD_HUNGRY_COUNT
self.DestroyItem(index_item=str(inventory_item))
接下来是将物体扔到地上的功能。
但是,没有什么复杂的,当您单击
X
调用该函数时self.QuitItem()
,for循环遍历清单的所有单元格,如果键["status"]
不相等"space"
,则使用先前考虑的函数删除此单元格self.DestroyItem()
,并根据单元格X和X中的内容创建一个对象。 Y将玩家视为已将其扔到他旁边。
self.Quititem()
def QuitItem(self):
for inventory_item in range(len(self.PLAYER["inventory"])):
if self.PLAYER["inventory"][str(inventory_item)]["status"] != "space":
self.CreateObject(
img=self.PLAYER["inventory"][str(inventory_item)]["img"],
x=self.PLAYER["x"],
y=self.PLAYER["y"],
name=self.PLAYER["inventory"][str(inventory_item)]["name"],
data=self.PLAYER["inventory"][str(inventory_item)]["data"],
)
self.DestroyItem(index_item=str(inventory_item))
break
然而,我没有说很多事情,T.K。尽管很有趣,但它们并不是游戏的主要部分。例如,关于以下信息的信息:是否可以拿起某项商品(当库存满时),添加了行走动画,制作了单独的图片库以及其他内容。
就这样?
不,我要使用我用Python编写的库为游戏添加一个神经网络,
我要使玩家与配备了神经网络的NPC互动,这是一个
小巧的情节,还为玩家提供了一些补给品,例如盔甲,食物。项,构建块的能力。
尝试游戏
可以从我的GitHub免费下载它,您只需要运行Python3和键盘库即可。您需要运行该文件
main.py
。
一个游戏