Arcade 游戏编程教程(五)
在本练习中,我们将创建三个自定义计算器程序。为了帮助创建这些练习,请查看第二章中的代码。特别是,本章末尾的示例程序为本练习所需的代码提供了一个很好的模板。确保你能写出简单的程序,就像这个练习中布置的那样。既能凭记忆做,也能写在纸上。这些程序遵循一种非常常见的计算模式:程序从数据库、3D 模型、游戏控制器、键盘和互联网等来源获取数据。它们执行计算并输出结果。有时我们甚至每秒钟循环数千次。将计算与数据
二十一、格式化
这里有一个快速表格,用于在设置文本格式时参考。有关文本格式如何工作的详细解释,请继续阅读。
| 数字 | 格式 | 输出 | 描述 | | --- | --- | --- | --- | | `3.1415926` | `{:.2f}` | `3.14` | 两位小数 | | `3.1415926` | `{:+.2f}` | `+3.14` | 带符号的 2 位小数 | | `-1` | `{:+.2f}` | `-1.00` | 带符号的 2 位小数 | | `3.1415926` | `{:.0f}` | `3` | 无小数位(将四舍五入) | | `5` | `{:0>2d}` | `05` | 左边用零填充 | | `1000000` | `{:,}` | `1,000,000` | 带逗号分隔符的数字格式 | | `0.25` | `{:.2%}` | `25.00%` | 格式化百分比 | | `1000000000` | `{:.2e}` | `1.00e+09` | 指数符号 | | `11` | `{:>10d}` | `11` | 右对齐 | | `11` | `{:<10d}` | `11` | 左对齐 | | `11` | `{:¹⁰d}` | `11` | 居中对齐 |十进制数字
尝试运行下面的程序,打印出几个随机数。
import
random
for i in range(10):
x = random.randrange(20)
print(x)
输出是左对齐的,数字看起来很糟糕:
16
13
2
0
10
3
18
1
14
5
我们可以使用字符串格式,通过右对齐使数字列表看起来更好。第一步是在管柱上使用format
命令。见下文:
import
random
for i in range(10):
x = random.randrange(20)
print("{}".format(x) )
这使我们的程序更接近正确的数字,但我们还没有完全实现。看字符串如何以.format(x)
结尾。所有字符串实际上都是名为String
的类的实例。该类有可以调用的方法。其中之一就是format
。
format
函数不会打印出花括号{}
,而是用x
中的值替换它们。输出(如下)看起来就像我们之前看到的一样。
7
15
4
12
3
8
7
15
12
8
为了右对齐,我们添加了更多关于如何格式化花括号之间的数字的信息:
import random
for i in range(10):
x = random.randrange(20)
print("{:2}".format(x) )
输出:
7
15
4
12
3
8
7
15
12
8
这样更好;我们有右对齐的数字!但是它是如何工作的呢?我们添加的:2
不太直观。
下面是分解情况:{ }
告诉计算机我们要格式化一个数字。在花括号内的:
之后将是格式化信息。在这种情况下,我们给它一个2
来指定两个字符的字段宽度。字段宽度值告诉计算机尝试将数字放入两个字符宽的字段中。默认情况下,它会尝试右对齐数字和左对齐文本。
更好的是,程序不再需要调用str( )
来将数字转换成字符串。不考虑字符串转换。
如果你有很多数字呢?让我们制造更大的随机数:
import random
for i in range(10):
x = random.randrange(100000)
print("{:6}".format(x) )
这给出了右对齐的输出,但看起来仍然不太好:
18394
72242
97508
21583
11508
76064
88756
77413
7930
81095
逗号在哪里?这个列表在每三个数字之间用分隔符会更好看。请看下一个示例,了解它们是如何添加到中的:
import random
for i in range(10):
x = random.randrange(100000)
print("{:6,}".format(x) )
输出:
65,732
30,248
13,802
17,177
3,584
7,598
21,672
82,900
72,838
48,557
我们在字段宽度说明符后添加了一个逗号,现在我们的数字有了逗号。逗号必须在字段宽度说明符之后,而不是之前。计算字段宽度时包括逗号。例如,1,024
的字段宽度是 5,而不是 4。
我们可以打印多个值,并将这些值与文本结合起来。运行下面的代码。
x = 5
y = 66
z = 777
print("A - ’{}’ B - ’{}’ C - ’{}’".format(x, y, z))
程序会用数字代替花括号,并打印出字符串中的所有其他文本:
A - ’5’ B - ’66’ C - ’777’
如果有三组花括号,计算机将期望在format
命令中列出三个值。给定的第一个值将替换第一个大括号。
有时,我们可能希望将相同的值打印两次。或者以不同于输入到format
函数的顺序显示它们。
x = 5
y = 66
z = 777
print("C - ’{2}’ A - ’{0}’ B - ’{1}’ C again - ’{2}’".format(x, y, z))
请注意,通过在花括号中放置一个数字,我们可以指定哪个参数传递给了我们想要打印出来的format
函数。参数从 0 开始编号,所以x
被认为是参数 0。
我们仍然可以在冒号后指定格式信息。例如:
x = 5
y = 66
z = 777
print("C - ’{2:4}’ A - ’{0:4}’ B - ’{1:4}’ C again - ’{2:4}’".format(x, y, z))
我们可以看到上面的代码将显示字段宽度为 4 的右对齐值:
C - ’ 777’ A - ’ 5’ B - ’ 66’ C again - ’ 777’
用线串
让我们看看如何格式化字符串。
下面的列表看起来很可怕。
my_fruit = ["Apples","Oranges","Grapes","Pears"]
my_calories = [4, 300, 70, 30]
for i in range(4):
print(my_fruit[i], "are", my_calories[i], "calories.")
输出:
Apples are 4 calories.
Oranges are 300 calories.
Grapes are 70 calories.
Pears are 30 calories.
现在使用format
命令尝试一下。请注意我们如何将附加文本和多个值放入同一行。
my_fruit = ["Apples", "Oranges", "Grapes", "Pears"]
my_calories = [4, 300, 70, 30]
for i in range(4):
print("{:7} are {:3} calories.".format(my_fruit[i],my_calories[i]) )
输出:
Apples are 4 calories.
Oranges are 300 calories.
Grapes are 70 calories.
Pears are 30 calories.
这很酷,而且看起来是我们想要的样子。但是如果我们不希望数字右对齐,文本左对齐呢?我们可以使用<
和>
字符,如下例所示:
my_fruit = ["Apples", "Oranges", "Grapes", "Pears"]
my_calories = [4, 300, 70, 30]
for i in range(4):
print("{:>7} are {:<3} calories.".format(my_fruit[i],my_calories[i]) )
输出:
Apples are 4 calories.
Oranges are 300 calories.
Grapes are 70 calories.
Pears are 30 calories.
前导零
这会产生不正确的输出:
for hours in range(1,13):
for minutes in range(0,60):
print("Time {}:{}".format(hours, minutes))
不太好的输出:
Time 8:56
Time 8:57
Time 8:58
Time 8:59
Time 9:0
Time 9:1
Time 9:2
我们需要使用前导零来显示时钟中的数字。不要为字段宽度指定一个2
,而是使用02
。这将用零而不是空格填充字段。
for hours in range(1,13):
for minutes in range(0,60):
print("Time {:02}:{:02}".format(hours, minutes))
输出:
Time 08:56
Time 08:57
Time 08:58
Time 08:59
Time 09:00
Time 09:01
Time 09:02
浮点数
我们还可以控制浮点输出。检查以下代码及其输出:
x = 0.1
y = 123.456789
print("{:.1} {:.1}".format(x,y) )
print("{:.2} {:.2}".format(x,y) )
print("{:.3} {:.3}".format(x,y) )
print("{:.4} {:.4}".format(x,y) )
print("{:.5} {:.5}".format(x,y) )
print("{:.6} {:.6}".format(x,y) )
print()
print("{:.1f} {:.1f}".format(x,y) )
print("{:.2f} {:.2f}".format(x,y) )
print("{:.3f} {:.3f}".format(x,y) )
print("{:.4f} {:.4f}".format(x,y) )
print("{:.5f} {:.5f}".format(x,y) )
print("{:.6f} {:.6f}".format(x,y) )
下面是这段代码的输出:
0.1 1e+02
0.1 1.2e+02
0.1 1.23e+02
0.1 123.5
0.1 123.46
0.1 123.457
0.1 123.5
0.10 123.46
0.100 123.457
0.1000 123.4568
0.10000 123.
45679
0.100000 123.456789
.2
的格式表示以两位精度显示数字。不幸的是,这意味着如果我们显示有三个有效数字的数字123
,而不是四舍五入,我们得到的是科学记数法中的数字:1.2e+02
。
.2f
(注意f
的格式)表示显示小数点后两位数的数字。因此数字1
将显示为1.00
,数字1.5555
将显示为1.56
。
程序也可以指定字段宽度字符:
x = 0.1
y = 123.456789
print("’{:10.1}’ ’{:10.1}’".format(x,y) )
print("’{:10.2}’ ’{:10.2}’".format(x,y) )
print("’{:10.3}’ ’{:10.3}’".format(x,y) )
print("’{:10.4}’ ’{:10.4}’".format(x,y) )
print("’{:10.5}’ ’{:10.5}’".format(x,y) )
print("’{:10.6}’ ’{:10.6}’".format(x,y) )
print()
print("’{:10.1f}’ ’{:10.1f}’".format(x,y) )
print("’{:10.2f}’ ’{:10.2f}’".format(x,y) )
print("’{:10.3f}’ ’{:10.3f}’".format(x,y) )
print("’{:10.4f}’ ’{:10.4f}’".format(x,y) )
print("’{:10.5f}’ ’{:10.5f}’".format(x,y) )
print("’{:10.6f}’ ’{:10.6f}’".format(x,y) )
格式10.2f
不是指小数点前 10 位和小数点后 2 位。这意味着总字段宽度为 10。所以小数点前会有 7 位数,小数点后多算 1 位数,后面有 2 位数。
’ 0.1’ ’ 1e+02’
’ 0.1’ ’ 1.2e+02’
’ 0.1’ ’ 1.23e+02’
’ 0.1’ ’ 123.5’
’ 0.1’ ’ 123.46’
’ 0.1’ ’ 123.457’
’ 0.1’ ’ 123.5’
’ 0.10’ ’ 123.46’
’ 0.100’ ’ 123.457’
’ 0.1000’ ’ 123.4568’
’ 0.10000’ ’ 123.45679’
’ 0.100000’ ’123.
456789’
印刷美元和美分
如果你想打印一个浮点数,你可以使用一个f
。见下文:
cost1 = 3.07
tax1 = cost1 * 0.06
total1 = cost1 + tax1
print("Cost: ${0:5.2f}".format(cost1) )
print("Tax: {0:5.2f}".format(tax1) )
print("------------")
print("Total: ${0:5.2f}".format(total1) )
记住!很容易认为%5.2f
意味着 5 个数字,一个小数,后面跟着 2 个数字。但事实并非如此。这意味着字段总宽度为 8,包括小数和后面的两位数字。以下是输出结果:
Cost: $ 3.07
Tax: 0.18
------------
Total: $ 3.25
危险!上面的代码有一个错误,这个错误在处理金融交易时非常常见。你能发现它吗?尝试使用下面的扩展代码示例来发现它:
cost1 = 3.07
tax1 = cost1 * 0.06
total1 = cost1 + tax1
print("Cost: ${0:5.2f}".format(cost1) )
print("Tax: {0:5.2f}".format(tax1) )
print("------------")
print("Total: ${0:5.2f}".format(total1) )
cost2 = 5.07
tax2 = cost2 * 0.06
total2 = cost2 + tax2
print()
print("Cost: ${0:5.2f}".format(cost2) )
print("Tax: {0:5.2f}".format(tax2) )
print("------------")
print("Total: ${0:5.2f}".format(total2) )
print()
grand_total = total1 + total2
print("Grand total: ${0:5.2f}".format(grand_total) )
以下是输出结果:
Cost: $ 3.07
Tax: 0.18
------------
Total: $ 3.25
Cost: $ 5.07
Tax: 0.30
------------
Total: $ 5.37
Grand total: $ 8.63
发现错误?你必须小心舍入误差!看看那个例子;看起来总数应该是$ 8.62
但不是。
打印格式不改变数字,只改变输出的内容!如果我们更改打印格式,在小数点后包含三位数字,错误的原因将变得更加明显:
Cost: $3.070
Tax: 0.184
------------
Total: $3.254
Cost: $5.070
Tax: 0.304
------------
Total: $5.374
Grand total: $8.628
同样,显示格式不会改变数字。使用round
命令改变数值并真正取整。见下文:
cost1 = 3.07
tax1 = round(cost1 * 0.06, 2)
total1 = cost1 + tax1
print("Cost: ${0:5.2f}".format(cost1) )
print("Tax: {0:5.2f}".format(tax1) )
print("------------")
print("Total: ${0:5.2f}".format(total1) )
cost2 = 5.07
tax2 = round(cost2 * 0.06,2)
total2 = cost2 + tax2
print()
print("Cost: ${0:5.2f}".format(cost2) )
print("Tax: {0:5.2f}".format(tax2) )
print("------------")
print("Total: ${0:5.2f}".format(total2) )
print()
grand_total = total1 + total2
print("Grand total: ${0:5.2f}".format(grand_total) )
输出:
Cost: $ 3.
07
Tax: 0.18
------------
Total: $ 3.25
Cost: $ 5.07
Tax: 0.30
------------
Total: $ 5.37
Grand total: $ 8.62
round 命令控制我们四舍五入到小数点后多少位。它返回舍入值,但不改变原始值。见下文:
x = 1234.5678
print(round(x, 2))
print(round(x, 1))
print(round(x, 0))
print(round(x, -1))
print(round(x, -2))
参见下文,了解将round()
函数值(如-2
)输入小数点后的数字如何影响输出:
1234.57
1234.6
1235.0
1230.0
1200.0
在 Pygame 中使用
我们不仅仅需要为print
语句格式化字符串。示例 timer.py 使用字符串格式并将生成的文本直接传送到屏幕上,以创建一个屏幕计时器:
# Use python string formatting to format in leading zeros
output_string = "Time: {0:02}:{1:02}".format(minutes,seconds)
# Blit to the screen
text = font.render(output_string, True, BLACK)
screen.blit(text, [250, 250])
回顾
简答工作表
Take the following program: score = 41237
highscore = 1023407
print("Score: " + str(score) )
print("High score: " + str(highscore) )
Which right now outputs: Score: 41237
High score: 1023407
Use print formatting so that the output instead looks like: Score: 41,237
High score: 1,023,407
Make sure the print formatting works for any integer from zero to nine million. Create a program that loops from 1 to 20 and lists the decimal equivalent of their inverse. Use print formatting to exactly match the following output: 1/1 = 1.0
1/2 = 0.5
1/3 = 0.333
1/4 = 0.25
1/5 = 0.2
1/6 = 0.167
1/7 = 0.143
1/8 = 0.125
1/9 = 0.111
1/10 = 0.1
1/11 = 0.0909
1/12 = 0.0833
1/13 = 0.0769
1/14 = 0.0714
1/15 = 0.0667
1/16 = 0.0625
1/17 = 0.0588
1/18 = 0.0556
1/19 = 0.0526
1/20 = 0.05
Write a recursive function that will calculate the Fibonacci series, and use output formatting. Your result should look like: 1 - 0
2 - 1
3 - 1
4 - 2
5 - 3
6 - 5
7 - 8
8 - 13
9 - 21
10 - 34
11 - 55
12 - 89
13 - 144
14 - 233
15 - 377
16 - 610
17 - 987
18 - 1,597
19 - 2,584
20 - 4,181
21 - 6,765
22 - 10,946
23 - 17,711
24 - 28,657
25 - 46,368
26 - 75,025
27 - 121,393
28 - 196,418
29 - 317,811
30 - 514,229
31 - 832,040
32 - 1,346,269
33 - 2,178,309
34 - 3,524,578
35 - 5,702,887
Why does the problem above run so slow? How could it be made to run faster?
二十二、练习
| 练习 1:自定义计算器 | | 练习 2:创建一个测验 | | 练习 3:骆驼 | | 练习 4:创建一幅图片 | | 练习 5:多圈实验室 | | 练习 6:冒险! | | 练习 7:动画 | | 练习 8:函数 | | 练习 9:功能和用户控制 | | 练习 10:位图图形、声音效果和音乐 | | 练习 11:类和图形 | | 练习 12:收集雪碧 | | 练习 13:移动精灵 | | 练习 14:拼写检查 | | 练习 15:最终练习 |练习 1:自定义计算器
在本练习中,我们将创建三个自定义计算器程序。为了帮助创建这些练习,请查看第二章中的代码。特别是,本章末尾的示例程序为本练习所需的代码提供了一个很好的模板。
确保你能写出简单的程序,就像这个练习中布置的那样。既能凭记忆做,也能写在纸上。这些程序遵循一种非常常见的计算模式:
Take in data Perform calculations Output data
程序从数据库、3D 模型、游戏控制器、键盘和互联网等来源获取数据。它们执行计算并输出结果。有时我们甚至每秒钟循环数千次。
将计算与数据输出分开是一个好主意。虽然可以在 print 语句中进行计算,但最好是先进行计算,将其存储在一个变量中,然后再输出。这样计算和输出就不会混在一起。
编写程序时,使用空行来分隔代码的逻辑分组是一个好主意。例如,在输入语句、计算和输出语句之间放置一个空行。此外,在程序中添加注释来标记这些部分。
在本练习中,您将创建三个简短的程序:
程序
创建一个程序,要求用户输入华氏温度,然后打印出摄氏温度。在互联网上搜索正确的计算方法。查看第二章的每加仑英里数示例,了解应该做些什么。
样品运行:
Enter temperature in Fahrenheit: 32
The temperature in Celsius: 0.0
样品运行:
Enter temperature in Fahrenheit: 72
The temperature in Celsius: 22.2222222222
这个程序的数字格式不会很好。没关系。但是如果它困扰着你,向前看第二十一章,看看如何让你的输出看起来很棒!
程序
创建一个新的程序,要求用户提供计算梯形面积所需的信息,然后打印出面积。梯形的面积公式为:
样品运行:
Area of a trapezoid
Enter the height of the trapezoid: 5
Enter the length of the bottom base: 10
Enter the length of the top base: 7
The area is: 42.5
程序
创建您自己的原始问题,并让用户插入变量。如果你不想要任何原创的东西,从下面的列表中选择一个等式:
| 圆的面积 |  | | 椭圆的面积 |  | | 等边三角形的面积 |  | | 圆锥体的体积 |  | | 球体的体积 |  | | 任意三角形的面积 |  |完成后,检查以确保变量名以小写字母开头,并且在代码的逻辑分组之间使用空行。(在这种情况下,在输入、计算和输出之间。)
练习 2:创建一个测验
现在是你自己写测验的机会了。使用这些测验来筛选求职者,淘汰潜在的伴侣,或者只是有机会坐在桌子的另一边做测验,而不是参加测验。
本练习应用了第四章中关于使用if
语句的材料。这也需要一点第二章的内容,因为程序必须计算一个百分比。
描述
这是您的测验需要具备的功能列表:
Create your own quiz with five or more questions. You can ask questions that require:
- 一个数字作为答案(例如,1+1 是什么?)
- 正文(例如哈利波特姓什么?)
- 选择(这些选项中哪些是正确的?a,B,还是 C?)
If you have the user enter non-numeric answers, think and cover the different ways a user could enter a correct answer. For example, if the answer is “a,” would “A” also be acceptable? See Chapter 4 for a reminder on how to do this. Let the user know if they get the question correct. Print a message depending on the user’s answer. You need to keep track of how many questions they get correct. At the end of the program print the percentage of questions the user gets right.
创建程序时,请记住以下几点:
Variable names should start with a lowercase letter. Uppercase letters work, but it is not considered proper. (Right, you didn’t realize that programming was going to be like English Tea Time, did you?) To create a running total of the number correct, create a variable to store this score. Set it to zero. With an if
statement, add one to the variable each time the user gets a correct answer. (How do you know if they got it correct? Remember that if you are printing out “correct” then you have already done that part. Just add a line there to add one to the number correct.) If you don’t remember how to add one to a variable, go back and review Chapter 2. Treat true/false questions like multiple choice questions; just compare to “True” or “False.” Don’t try to do if a:
we’ll implement if
statements like that later on in the class, but this isn’t the place. Calculate the percentage by using a formula at the end of the game. Don’t just add 20% for each question the user gets correct. If you add 20% each time, then you have to change the program 5 places if you add a 6th question. With a formula, you only need 1 change. To print a blank line so that all the questions don’t run into each other, use the following code: print()
Remember the program can print multiple items on one line. This can be useful when printing the user’s score at the end. print("The value in x is", x)
Separate out your code by using blank lines to group sections together. For example, put a blank line between the code for each question. Sometimes it makes sense to reuse variables. Rather than having a different variable to hold the user’s answer for each question, you could reuse the same one. Use descriptive variable names. x
is a terrible variable name. Instead use something like number_correct
.
示例运行
这是我的程序中的一个例子:
Quiz time!
How many books are there in the Harry Potter series? 7
Correct!
What is 3*(2-1)? 3
Correct!
What is 3*2-1? 5
Correct!
Who sings Black Horse and the Cherry Tree?
1\. Kelly Clarkson
2\. K.T. Tunstall
3\. Hillary Duff
4\. Bon Jovi
? 2
Correct!
Who is on the front of a one dollar bill
1\. George Washington
2\. Abraham Lincoln
3\. John Adams
4\. Thomas Jefferson
? 2
No.
Congratulations, you got 4 answers right.
That is a score of 80.0 percent.
练习 3:骆驼
骆驼游戏的描述
骆驼的想法最初来自健康用户组,并于 1979 年发表在更基本的电脑游戏中。
这个想法是在被追赶的时候骑着你的骆驼穿越沙漠。你需要管理你的口渴,骆驼有多累,你领先土著多远。
这是我在 Apple //e 上编程的第一批游戏之一,游戏很灵活。我知道有人创造了这个游戏的星球大战主题版本,你需要骑着万帕穿越霍斯。很容易将沙尘暴和其他随机事件添加到游戏中,使其更加有趣。
骆驼试跑
这是一个游戏的运行示例:
Welcome to Camel!
You have stolen a camel to make your way across the great Mobi desert.
The natives want their camel back and are chasing you down! Survive your
desert trek and outrun the natives.
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? C
You traveled 12 miles.
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? C
You traveled 17 miles.
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? e
Miles traveled: 29
Drinks in canteen: 3
The natives are 31 miles behind you.
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? b
You traveled 6 miles.
...and so on until...
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? C
You traveled 12 miles.
The natives are getting close!
A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop and rest.
E. Status check.
Q. Quit.
Your choice? C
You traveled 11 miles.
The natives are getting close!
You made it across the desert! You won!
节目指南
下面是完成这个练习的步骤。请随意修改和增加练习内容。与朋友和家人一起尝试游戏。
Create a new program and print the instructions to the screen. Do this with multiple print
statements. Don’t use one print
statement and multiple \n
characters to jam everything on one line. Welcome to Camel!
You have stolen a camel to make your way across the great Mobi desert.
The natives want their camel back and are chasing you down! Survive your
desert trek and out run the natives.
Create a Boolean variable called done
and set to False
. Create a while
loop that will keep looping while done
is False. Inside the loop, print out the following: A. Drink from your canteen.
B. Ahead moderate speed.
C. Ahead full speed.
D. Stop for the night.
E. Status check.
Q. Quit.
Ask the user for their choice. Make sure to add a space before the quote so the user input doesn’t run into your text. If the user’s choice is Q, then set done
to True
. By doing something like user_choice.upper()
instead of just user_choice
in your if
statement you can make it case insensitive. Test and make sure that you can quit out of the game. Before your main program loop, create variables for miles traveled, thirst, and camel tiredness. Set these to zero. Create a variable for the distance the natives have traveled and set it to -20. (Twenty miles back.) Create and set an initial number of drinks in the canteen. Add an elif
in your main program loop and see if the user is asking for status. If so, print out something like this: Miles traveled: 0
Drinks in canteen: 3
The natives are 10 miles behind you.
Add an elif
in your main program loop and handle if the user wants to stop for the night. If the user does, reset the camel’s tiredness to zero. Print that the camel is happy, and move the natives up a random amount from 7 to 14 or so. Add an elif
in your main program loop and handle if the user wants to go ahead full speed. If the user does, go forward a random amount between 10 and 20 inclusive. Print how many miles the user traveled. Add 1 to thirst. Add a random 1 to 3 to camel tiredness. Move the natives up 7 to 14 miles. Add an elif
in your main program loop and handle if the user wants to go ahead moderate speed. If the user does, go forward a random amount between 5 and 12 inclusive. Print how many miles the user traveled. Add 1 to thirst. Add 1 to camel tiredness. Move the natives up 7 to 14 miles. Add an elif
in your main program loop and handle if the user wants to go ahead drink from the canteen. If the user does, make sure there are drinks in the canteen. If there are, subtract one drink and set the player’s thirst to zero. Otherwise print an error. In the loop, print “You are thirsty.” if the user’s thirst is above 4. Print “You died of thirst!” if the user’s thirst is above 6. Set done
to true. Make sure you create your code so that the program doesn’t print both “You are thirsty” and “You died of thirst!” Use elif
as appropriate. Print “Your camel is getting tired.” if the camel’s tiredness is above 5. Print “Your camel is dead.” if the camel’s tiredness is above 8. Like the prior steps, print one or the other. It is a good idea to include a check with the done
variable so that you don’t print that your camel is getting tired after you died of thirst. If the natives have caught up, print that they caught the player and end the game. Else if the natives are less than 15 miles behind, print “The natives are getting close!” If the user has traveled 200 miles across the desert, print that they won and end the game. Make sure they aren’t dead before declaring them a winner. Add a one-in-twenty chance of finding an oasis. Print that the user found it, refill the canteen, reset player thirst, and rest the camel. Play the game and tune the numbers so it is challenging but not impossible. Fix any bugs you find.
暗示
- 请记住,在程序中的代码逻辑分组之间放置空行是一个好主意。例如,在指令之后和每个用户命令之间有一个空行。
- 使用
while not done:
而不是while done == False:
被认为是更好的样式 - 以防止错误的消息组合,如打印“你渴死了。”和“你发现了一片绿洲!”在同一个转弯中,使用
and
操作符。如,if not done and thirst > 4:
练习 4:创建一幅图片
描述
你的任务是:画一幅漂亮的画。这个练习的目标是练习使用函数,使用for
循环,并介绍计算机图形学。
练习你所有的新技能:
- 拥有多种颜色的图像。
- 做出连贯的画面。不要只做形状随意的抽象艺术。那没有挑战性。
- 尝试几种类型的图形功能(例如,圆形、矩形、线条等。).
- 使用
while
或for
循环创建重复模式。不要在同一个位置重复画同样的东西 10 次。实际上,使用索引变量作为偏移量来替换您正在绘制的内容。请记住,您可以在一个循环中包含多个绘制命令,因此您可以绘制多个火车车厢。
对于要修改的模板程序,请查看以下示例程序:
ProgramArcadeGames.com/python_examples/f.php?file=pygame_base_template.py
ProgramArcadeGames.com/python_examples/f.php?file=simple_graphics_demo.py
参见第六章了解模板的说明。有关 draw 模块的官方文档:
http://www.pygame.org/docs/ref/draw.html
要选择新颜色,请使用
或者打开 Windows 画图程序,点击“编辑颜色”复制红色、绿色和蓝色的值。不要担心颜色的色调、饱和度或亮度。
请使用注释和空行,以便于跟踪您的计划。如果你有 5 条线画一个机器人,把它们组合在一起,上面和下面用空白的线。然后在顶部添加注释,告诉读者你在画什么。
练习 5:多圈实验室
第一部分
编写一个 Python 程序,它将打印以下内容:
10
11 12
13 14 15
16 17 18 19
20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36 37
38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54
第一部分的提示
- 使用两个
for
循环生成第一部分的输出,其中一个是嵌套的。 - 创建一个单独的变量来存储将要打印的数字。不要使用你在
for
循环中创建的变量。这将是第三个变量,从 10 开始,每次增加 1。
第二部分
用 n 行小 o 创建一个大盒子,表示任何所需的大小 n。使用input
语句允许用户输入 n 的值,然后打印大小合适的盒子。
E.g. n = 3
oooooo
o o
oooooo
E.g. n = 8
oooooooooooooooo
o o
o o
o o
o o
o o
o o
oooooooooooooooo
第三部分
对于任意正整数 n,打印以下内容。使用input
语句允许用户输入 n 的值,然后打印适当大小的框。
E.g. n = 3
1 3 5 5 3 1
3 5 5 3
5 5
5 5
3 5 5 3
1 3 5 5 3 1
E.g. n = 5
1 3 5 7 9 9 7 5 3 1
3 5 7 9 9 7 5 3
5 7 9 9 7 5
7 9 9 7
9 9
9 9
7 9 9 7
5 7 9 9 7 5
3 5 7 9 9 7 5 3
1 3 5 7 9 9 7 5 3 1
不要担心处理多位数的间距。如果你想向前看,第二十一章会谈到这一点,但这并不是必需的。
这部分练习很难。如果你对挑战不感兴趣,跳到第四部分。
第四部分
从 pygame 模板代码开始:
ProgramArcadeGames.com/python_examples/f.php?file=pygame_base_template.py
使用嵌套的for
循环绘制绿色小矩形。使图像看起来像下图。
Pygame Grid(游戏网格)
不要通过画线来创建网格;使用由矩形创建的网格。
如果这太无聊,创建一个类似的网格的东西。可以更改所绘制形状的颜色、大小和类型。只需习惯使用嵌套的for
循环来生成网格。
有时人们觉得需要在这个程序中给偏移量加一个零。提醒自己,在一个数字上加零有点傻。
练习 6:冒险!
冒险游戏的描述
我玩过的第一个游戏是一个叫做巨大洞穴探险的文本冒险。你可以在网上玩这个游戏,了解一下文字冒险游戏是什么样的。可以说这类游戏中最著名的是 Zork 系列。
我自己创建的第一个“大型”程序是文本冒险。开始这样的冒险很容易。这也是练习使用列表的好方法。我们这个练习的游戏将包括一个房间列表,可以通过向北、向东、向南或向西导航。每个房间将是一个房间描述的列表,然后是每个方向的房间。请参见下面的示例运行部分:
样品运行
You are in a dusty castle room.
Passages lead to the north and south.
What direction? n
You are in the armory.
There is a room off to the south.
What direction? s
You are in a dusty castle room.
Passages lead to the north and south.
What direction? s
You are in a torch-lit hallway.
There are rooms to the east and west.
What direction? e
You are in a bedroom. A window overlooks the castle courtyard.
A hallway is to the west.
What direction? w
You are in a torch-lit hallway.
There are rooms to the east and west.
What direction? w
You are in the kitchen. It looks like a roast is being made for supper.
A hallway is to the east.
What direction? w
Can’t go that way.
You are in the kitchen. It looks like a roast is being made for supper.
A hallway is to the east.
What direction?
创建你的地牢
在你开始之前,勾画出你想要创建的地牢。它可能看起来像这样:
接下来,从零开始给所有房间编号。
用这张草图来找出所有房间是如何连接的。例如,房间 0 连接到北面的房间 3,房间 1 连接到东面,而南面和西面没有房间。
逐步说明
Create an empty array called room_list
. Create a variable called room
. Set it equal to an array with five elements. For the first element, create a string with a description of your first room. The last four elements will be the number of the next room if the user goes north, east, south, or west. Look at your sketch to see what numbers to use. Use None
if no room hooks up in that direction. (Do not put None
in quotes. It is a special value that represents no value.) Append this room to the room list. Repeat the prior two steps for each room you want to create. Just reuse the room
variable. Create a variable called current_room
. Set it to zero. Print the room_list
variable. Run the program. You should see a really long list of every room in your adventure. (If you are using an IDE like Wing, don’t leave it scrolled way off to the right.) Adjust your print statement to only print the first room (element zero) in the list. Run the program and confirm you get output similar to: [’You are in a room. There is a passage to the north.’, 1, None, None, None]
Using current_room
and room_list
, print the current room the user is in. Since your first room is zero, the output should be the same as before. Change the print statement so that you only print the description of the room, and not the rooms that hook up to it. Remember if you are printing a list in a list the index goes after the first index. Don’t do this: [current_room[0]]
, do [current_room][0]
You are in a room. There is a passage to the north.
Create a variable called done
and set it to False. Then put the printing of the room description in a while
loop that repeats until done
is set to True
. Before printing the description, add a code to print a blank line. This will make it visually separate each turn when playing the game. After printing the room description, add a line of code that asks the user what direction they wish to go. Add an if
statement to see if the user wants to go north. If the user wants to go north, create a variable called next_room
and get it equal to room_list[current_room][1]
, which should be the number for what room is to the north. Add another if
statement to see if the next room is equal to None
. If it is, print “You can’t go that way.” Otherwise set current_room
equal to next_room
. Test your program. Can you go north to a new room? Add elif
statements to handle east, south, and west. Add an else
statement to let the user know the program doesn’t understand what she typed. Add several rooms, at least five. It may be necessary to draw out the rooms and room numbers to keep everything straight. Test out the game. You can use \n or triple quotes if you have a multiline room description. Optional: Add a quit command. Make sure that the program works for upper and lower case directions. Have the program work if the user types in “north” or “n.”
花一点时间让这个游戏变得有趣。不要简单地创造一个“东房间”和一个“西房间”。那太无聊了。
还要花一点时间仔细检查拼写和语法。在没有文字处理器检查你的写作的情况下,小心是很重要的。
使用\n
在你的描述中添加回车符,这样它们就不会在一行中全部打印出来。不要在\n
周围加空格,否则空格会被打印出来。
我喜欢这个程序是因为它很容易扩展成一个完整的游戏。使用所有八个基本方向(包括“西北”),连同“上”和“下”是相当容易的。管理可以存在于房间中、被拾取和丢弃的物品的清单也是保存列表的问题。
将这个程序扩展成一个完整的游戏是最后练习的两个选项之一。
练习 7:动画
要求
修改之前的“创建图片”练习,或者开始一个新的练习。
动画图像。尝试以下一种或多种方法:
- 在屏幕上移动项目。
- 来回移动项目。
- 向上/向下/斜向移动。
- 转圈。
- 让人挥动手臂。
- 创建一个改变颜色的交通信号灯。
记住,天赋越多越好!享受这个练习,花点时间看看你能做什么。
练习 8:函数
把这个写成一个程序。整个东西应该可以直接穿过去。
这个程序有几个部分。以下是每个部分的描述:
Write a function called min3
that will take three numbers as parameters and return the smallest value. If more than one number tied for smallest, still return that smallest number. Use a proper if
/elif
/else
chain. Once you’ve finished writing your function, copy/paste the following code and make sure that it runs against the function you created: print(min3(4, 7, 5))
print(min3(4, 5, 5))
print(min3(4, 4, 4))
print(min3(-2, -6, -100))
print(min3("Z", "B", "A"))
You should get this result: 4
4
4
-100
A
The function should return the value, not print the value. Also, while there is a min
function built into Python, don’t use it. Please use if
statements and practice creating it yourself. Leave the testing statements in the program so the instructor can check the program. If you also get None
to print out, then chances are you are using print
instead of return
in your function. Write a function called box
that will output boxes given a height and width. Once you’ve finished writing your function, copy and paste the following code after it and make sure it works with the function you wrote: box(7,5) # Print a box 7 high, 5 across
print() # Blank line
box(3,2) # Print a box 3 high, 2 across
print() # Blank line
box(3,10) # Print a box 3 high, 10 across
You should get the following results from the sample code: *****
*****
*****
*****
*****
*****
*****
**
**
**
**********
**********
**********
Go back and look at Chapter 7if you’ve forgotten how to do this. Write a function called find
that will take a list of numbers, my_list
, along with one other number, key
. Have it search the list for the value contained in key
. Each time your function finds the key value, print the array position of the key. You will need to juggle three variables: one for the list, one for the key, and one for the position of where you are in the list. This code will look similar to the Chapter 8 code for iterating though a list using the range
and len
functions. Start with that code and modify the print
to show each element and its position. Then instead of just printing each number, add an if
statement to only print the ones we care about. Copy/paste this code to test it: my_list = [36, 31, 79, 96, 36, 91, 77, 33, 19, 3, 34, 12, 70, 12, 54, 98, 86, 11, 17, 17]
find(my_list, 12)
find(my_list, 91)
find(my_list, 80)
. . . check for this output: Found 12 at position 11
Found 12 at position 13
Found 91 at position 5
Use a for
loop with an index variable and a range
. Inside the loop use an if
statement. The function can be written in about four lines of code. Write one program that has the following:
- 功能:
- 编写一个名为
create_list
的函数,它接受一个列表大小并返回一个从 1 到 6 的随机数列表(即,调用create_list(5)
应该返回 5 个从 1 到 6 的随机数。(记住,第八章有代码展示了如何做类似的事情,用用户输入的五个数字创建一个列表。这里,您需要创建随机数,而不是询问用户。)为了测试,对您编写的函数使用下面的代码:my_list = create_list(5)
print(my_list)
,您应该得到五个随机元素的输出,看起来像:[2,5,1,6,3]
- 编写一个名为
count_list
的函数,它接受一个列表和一个数字。让函数返回指定数字在列表中出现的次数。为了测试,对您编写的函数使用下面的代码:count = count_list([1,2,3,3,3,4,2,1],3)
print(count)
,您应该得到类似于3
的输出 - 编写一个名为
average_list
的函数,返回传递给它的列表的平均值。为了测试,对您编写的函数使用下面的代码:avg = average_list([1,2,3])
print(avg)
,您应该得到类似于2
的输出
- 编写一个名为
- 现在已经创建了这些函数,在一个主程序中使用它们,它将:
- 创建一个包含 10,000 个从 1 到 6 的随机数的列表。这应该需要一行代码。使用您之前在练习中创建的函数。)
- 打印从 1 到 6 的计数。(即打印 1 在 10000 次中出现的次数。然后对 2-6 做同样的事情。)
- 打印所有 10,000 个随机数的平均值。
练习 9:用户控制
这个练习给你一个机会练习用一个函数画一个对象,并允许用户控制它。
创建一个包含以下内容的程序:
Create at least two different functions that draw an object to the screen. For example, draw_bird
and draw_tree
. Do not draw a stick figure; we did that one already. Create your own unique item. If you created your own object in the create-a-picture exercise feel free to adapt it to this exercise. In Chapter 11, we talked about moving graphics with the keyboard, a game controller, and the mouse. Pick two of those and use them to control two different items on the screen. In the case of the game controller and the keyboard, make sure to add checks so that your object does not move offscreen and get lost.
练习 10:位图图形和用户控件
创建一个基于图形的程序。你可以开始一个新的程序或继续先前的练习。
这是完成本练习的清单:
- 确保这个程序是在它自己的目录中创建的。使用您已有的空目录,或创建一个新目录。
- 至少包含一个在屏幕上绘制项目的功能。该函数应该获取指定在何处绘制项目的位置数据。(注意:您还需要传递一个对“屏幕”的引用另一个注意:这对于从文件中加载的图像来说是很难做到的。我建议只使用常规的绘图命令。)
- 添加通过鼠标、键盘或游戏控制器控制项目的功能。
- 包括某种位图图形。不要将位图图形作为“用函数绘图”的一部分在我们了解更多一点之前,这不会有什么效果。
- 包括声音。当用户点击鼠标、击键、移动到某个位置等时,你可以发出声音。如果声音有问题,尝试使用 Audacity 程序加载声音,然后将其导出为。ogg 文件。
- 如果您将此程序发送给某人,请确保发送了所有文件。很容易忘记添加图像和声音文件。
示例代码:
ProgramArcadeGames.com/index.php?chapter=example_code
您可以使用的声音和位图:
可以使用之前练习中的代码,例如练习 5。
练习 11:类和图形
图形提供了一个使用类的绝佳机会。每个图形对象可以由一个对象表示。每种类型的图形对象都可以用一个类来表示。对象的位置、速度和颜色可以存储在属性中。
说明
Start a new program with: ProgramArcadeGames.com/python_examples/f.php?file=pygame_base_template.py
Right after the default colors are defined in the example program, create a class called Rectangle
.
- 添加
x
和y
属性,用于存储对象的位置。 - 创建一个
draw
方法。让这个方法在x
和y
中存储的位置创建一个绿色的 10×10 的矩形。不要忘记在变量前使用self.
。该方法需要接受对screen
的引用,以便pygame.draw.rect
函数可以将矩形绘制到正确的屏幕上。
Before the program loop, create a variable called my_object
and set it equal to a new instance of Rectangle
. Inside the main program loop, call my_object
’s draw()
method. Checkpoint: Make sure your program works, and the output looks like this figure.
Rectangle in top left corner Right after the program creates the instance of Rectangle
, set the x and y values to something new, like 100, 200. Run the program again to make sure it works and the rectangle moves to the new coordinates. Add attributes to the class for height and width. Draw the rectangle using these new attributes. Run the program and make sure it works. Get the object to move:
- 为
change_x
和change_y
添加属性。 - 创建一个名为
move()
的新方法,根据change_x
和change_y
调整 x 和 y。(注意,move 方法不需要 screen 作为参数,因为它不会在屏幕上绘制任何东西。) - 将
my_object
的change_x
和change_y
设置为数值,如 2 和 2。 - 在主程序循环中调用
move()
方法。 - 测试以确保对象移动。
Randomize the object
- 导入随机库
- 将 x 位置设置为 0 到 700 之间的一个随机数。您可以在创建对象的循环中这样做,也可以在
__init__
方法中这样做。 - 将 y 位置设置为 0 到 500 之间的随机数。
- 将高度和宽度设置为 20 到 70 之间的任意数字。
- 将
change_x
和change_y
设置为-3 和 3 之间的随机数。 - 测试并确保它看起来像这个图形。
Rectangle in random spot Create and display a list of objects
- 在创建
my_object
的代码之前,创建一个空列表,名为my_list
- 创建一个循环 10 次的
for
循环。 - 将创建
my_object
的代码放入for
循环中 - 将
my_object
追加到my_list
上。 - 在主程序循环内,循环通过
my_list
的每一项。 - 为列表中的每一项调用 draw 和 move 方法。
- 确保代码调用了
for
循环拉出的元素的 draw 方法,不要只使用my_object.draw()
。这是最常见的错误之一。
- 确保代码调用了
- 测试一下,看看你的程序看起来是否像下图。
Ten rectangles Use inheritance
- 在
Rectangle
类之后,创建一个名为Ellipse
的新类。 - 将
Rectangle
设置为Ellipse
的父类。 - 您不需要创建新的
___init__
;我们将只是继承父类的方法。 - 创建一个绘制椭圆而不是矩形的新绘制方法。
- 创建一个新的
for
循环,除了 10 个矩形之外,还将 10 个Ellipse
实例添加到my_list
中。(就用两个独立的for
循环。) - 请确保不要创建新列表;只需将它们添加到同一个
my_list
。 - 因为矩形和椭圆都被添加到同一个列表中,所以只需要一个循环就可以遍历列表并绘制两者。不要犯有两个循环的错误,一个用于矩形,一个用于椭圆。事情不是这样的。
- 测试一下,看看你的程序是否像下图这样。
Rectangles and ellipses Make it more colorful
- 调整程序,让颜色成为
Rectangle
的一个属性。 - 使用新颜色绘制矩形和椭圆。
- 在
for
循环中,将形状设置为随机颜色。记住,颜色是由列表中的三个数字指定的,所以你需要一个由三个随机数组成的列表(r, g, b)
。 - 测试一下,看看你的程序看起来是否像下图。
Colorful shapes Try it with more than 10 items of each type. This next figure shows 1,000 shapes. You are done! Turn in your program.
Shapes gone crazy
练习 12:收集雪碧
本练习练习使用 pygame 精灵,如第十四章所述。
Make sure this program is created in its own directory. Start with the following program: ProgramArcadeGames.com/python_examples/f.php?file=sprite_collect_blocks.py
Update the comments at the beginning to reflect that it is now your program, not mine. Modify it so the player moves with the keyboard rather than the mouse. Take a look at the move_sprite_keyboard_smooth.py
program also available on the example page: ProgramArcadeGames.com/python_examples/f.php?file=move_sprite_keyboard_smooth.py
- 从这个文件中,您需要获取
Player
类,并将其移动到您自己的程序中。不要去掉Block
类。在你的程序中你将同时拥有Block
和Player
两个职业。 - 现在,你的玩家是
Block
的一个实例。您需要对它进行修改,以便创建一个Player
的实例。注意,Player
的构造函数与Block
采用不同的参数。 - 更新您的事件循环,使其像这个新示例一样响应键盘输入。
- 删除用鼠标移动播放器的代码。
- 让玩家变蓝。
- 确保在主程序循环中有一个对
all_sprites_list.update()
的调用。这将调用每个 sprite 中的update()
方法。 - 测试并确保它现在工作。
Create both good sprites and bad sprites
- 好雪碧
- 你现在创建 50 个块,不是把它们添加到一个叫做
block_list
的列表中,而是把它们添加到一个叫做good_block_list
的列表中。 - 把积木变成绿色。
- 在主循环中检查块冲突的地方,更新检查,使其使用
good_block_list
。
- 你现在创建 50 个块,不是把它们添加到一个叫做
- 坏精灵不会在你添加坏方块或玩家之前重新创建列表。
- 复制这段代码,并将另外 50 个块添加到名为
bad_block_list
的新列表中。 - 确保你的程序只创建一个
all_sprites_list
。Don’t re-create the list right before you add bad blocks or the player. - 把积木涂成红色。
- 复制代码并对照
bad_block_list
进行检查。降低分数而不是增加分数。 - 测试并确保它正在工作。
- 复制这段代码,并将另外 50 个块添加到名为
- 使用图形来表示好/坏精灵,如
sprite_collect_graphic.py
示例文件所示。不使用图形只是罚两分。
Rather than simply use print
to display the score on the console, display the score on the graphics window. Go back to the end of Chapter 6 and look up the section on drawing text. Add sound effects for when the user hits good blocks, or bad blocks. Here are a couple from OpenGameArt.org
: ProgramArcadeGames.com/labs/sprite_collecting/good_block.wav
ProgramArcadeGames.com/labs/sprite_collecting/bad_block.wav
Looking back at how we made a sound to begin with, we triggered the sound with a mouse click event. We won’t be doing that here. Find the code that you already have that detects when a collision occurs. Play the sound when you have a collision. Also, remember that when you load a sound, it needs to be done before the main loop, but after the pygame.init()
command. Add a check and make sure the player doesn’t slide off the end of the screen. This check should go in the update
method of the Player
class. There should be four if
statement checks, one for each border. If the player’s x and y get outside the bounds of the screen, reset the player back inside the screen. Do not modify change_x
or change_y
. That doesn’t work for player-controlled objects. Don’t forget to check the right and bottom borders; they are easy to get wrong. Download a wav or ogg file and have it play a sound if the user tries to slide off the screen. Here’s one sound you can use: ProgramArcadeGames.com/labs/sprite_collecting/bump.wav
Check to make sure the bump sound doesn’t continually play when the user is at the edge of the screen. If it does, the program is checking the edge incorrectly. If you send your program to anyone, remember they will need all the files, not just the Python program.
练习 13:精灵移动
这个练习使用 pygame 精灵,如第十四章中所述,并且将职业分成不同的文件,如第十五章中所述。
Make sure this program is created in its own directory. Start with a copy of the program you wrote for Exercise 12: Sprite Collecting. Copy those files into the directory for this exercise. Move the Block
class into a new file. Many people get confused between the name of the library file, the name of the class, and the variable that points to the instance of the object. Library files should be all lowercase. I’d recommend calling your new file that you put the Block class into block_library.py
. Make sure your program runs like before. Adjust import
statements as needed. Remember that you prepend the library name to the class, not the variable that points to the instance of the class. For example: my_dog = dog_library.Dog()
and NOT dog_library.my_dog = Dog()
because Dog
is what is in the library, not my_dog
. Define a GoodBlock
class in a new file, and inherit from your Block
class. I’d recommend using the file name goodblock_library.py
to keep with the pattern we set up before. Remember, define the class. Don’t create an instance of it. Your for
loop that creates the instances does not move. Add a new update
method. (You probably don’t need a new __init__
method.) Make the good block randomly move up, down, left or right each update. (Change self.rect.x
and self.rect.y
randomly each time the update
function is called. Not to a completely new number, but add a random number from -3 to 3 or so. Remember that random.randrange(-3,3)
does not generate a random number from -3 to 3.) Change your for
loop so that it creates instances of the GoodBlock
class and not your old regular Block
class. Call update
on the list of all the sprites you have. Do this in the main program loop so the blocks keep moving, not just once at the start of the program. Test and make sure it works. It is ok if the sprites move off the screen, but a common mistake results in the sprites all moving up and to the left off the screen. If that happens, go back four steps and check your random range. Double-check, and make sure GoodBlock
inherits from the Block
class. If done correctly, GoodBlock
won’t need an __init__
method because it will get this method from Block
. Create a BadBlock
class in a new file and inherit from the Block
class. Make an update
function and have the bad block sprites move down the screen, similar to what was done in Chapter 14. Extra kudos if you make a bouncing rectangle. Test, and make sure it works. Double-check to make sure each class is in its own file. If you have extra time, you can look at the sprite examples section on the web site and see how to get sprites to bounce or move in circles.
练习 14:拼写检查
本练习展示了如何创建拼写检查器。要准备练习,请访问:
ProgramArcadeGames.com/index.php?chapter=examples list
。。。并下载下面列出的文件。这些文件也在“搜索和排序示例”部分。
AliceInWonderLand.txt
——《爱丽丝梦游仙境》正文AliceInWonderLand200.txt
——《爱丽丝梦游仙境》第一章dictionary.txt
-一串单词
要求
用 Python 写一个检查《爱丽丝梦游仙境》第一章拼写的程序。首先使用线性搜索,然后使用二分搜索法。打印行号和字典中不存在的单词。
请仔细遵循以下步骤。如果你不知道如何完成一个步骤,在进入下一步之前问一下。
要完成的步骤:
If you work off the BitBucket template, skip ahead to step 6. Find or create a directory for your project. Download the dictionary to the directory. Download first 200 lines of Alice In Wonderland to your directory. Start a Python file for your project. It is necessary to split apart the words in the story so that they may be checked individually. It is also necessary to remove extra punctuation and white space. Unfortunately, there is not any good way of doing this with what the book has covered so far. The code to do this is short, but a full explanation is beyond the scope of this class. Include the following function in your program. Remember, function definitions should go at the top of your program just after the imports. We’ll call this function in a later step. import re
# This function takes in a line of text and returns
# a list of words in the line.
def split_line(line):
return re.findall(’[A-Za-z]+(?:\’[A-Za-z]+)?’,line)
This code uses a regular expression to split the text apart. Regular expressions are very powerful and relatively easy to learn. To learn more about regular expressions, see: http://en.wikipedia.org/wiki/Regular_expression
Read the file dictionary.txt
into an array. Go back to the chapter on Searching, or see the searching_example.py
for example code on how to do this. This does not have anything to do with the import
command, libraries, or modules. Don’t call the dictionary word_list
or something generic because that will be confusing. Call it dictionary_list
or something similar. Close the file. Print --- Linear Search ---
Open the file AliceInWonderLand200.txt
We are not going to read the story into a list. Do not create a new list here like you did with the dictionary. Start a for
loop to iterate through each line. Call the split_line
function to split apart the line of text in the story that was just read in. Store the list that the function returns in a new variable named words
. Remember, just calling the function won’t do anything useful. You need to assign a variable equal (words
) to the result. If you’ve forgotten now to capture the return value from a function, flip back to the functions chapter to find it. Start a nested for
loop to iterate through each word in the words list. This should be inside the for
loop that runs through each line in the file. (One loop for each line, another loop for each word in the line.) Using a linear search, check the current word against the words in the dictionary. Check the chapter on searching or the searching_example.py
for example code on how to do this. The linear search is just three lines long. When comparing to the word to the other words in the dictionary, convert the word to uppercase. In your while
loop just use word.upper()
instead of word
for the key. This linear search will exist inside the for
loop created in the prior step. We are looping through each word in the dictionary, looking for the current word in the line that we just read in. If the word was not found, print the word. Don’t print anything if you do find the word; that would just be annoying. Close the file. Make sure the program runs successfully before moving onto the next step. Create a new variable that will track the line number that you are on. Print this line number along with the misspelled from the prior step. Make sure the program runs successfully before moving onto the next step. Print --- Binary Search ---
The linear search takes quite a while to run. To temporarily disable it, it may be commented out by using three quotes before and after that block of code. Ask if you are unsure how to do this. Repeat the same pattern of code as before, but this time use a binary search. Much of the code from the linear search may be copied, and it is only necessary to replace the lines of code that represent the linear search with the binary search. Note the speed difference between the two searches. Make sure the linear search is re-enabled, if it was disabled while working on the binary search. Upload the final program or check in the final program.
示例运行
--- Linear Search ---
Line 3 possible misspelled word: Lewis
Line 3 possible misspelled word: Carroll
Line 46 possible misspelled word: labelled
Line 46 possible misspelled word: MARMALADE
Line 58 possible misspelled word: centre
Line 59 possible misspelled word: learnt
Line 69 possible misspelled word: Antipathies
Line 73 possible misspelled word: curtsey
Line 73 possible misspelled word: CURTSEYING
Line 79 possible misspelled word: Dinah’ll
Line 80 possible misspelled word: Dinah
Line 81 possible misspelled word: Dinah
Line 89 possible misspelled word: Dinah
Line 89 possible misspelled word: Dinah
Line 149 possible misspelled word: flavour
Line 150 possible misspelled word: toffee
Line 186 possible misspelled word: croquet
--- Binary Search ---
Line 3 possible misspelled word: Lewis
Line 3 possible misspelled word: Carroll
Line 46 possible misspelled word: labelled
Line 46 possible misspelled word: MARMALADE
Line 58 possible misspelled word: centre
Line 59 possible misspelled word: learnt
Line 69 possible misspelled word: Antipathies
Line 73 possible misspelled word: curtsey
Line 73 possible misspelled word: CURTSEYING
Line 79 possible misspelled word: Dinah’ll
Line 80 possible misspelled word: Dinah
Line 81 possible misspelled word:
Dinah
Line 89 possible misspelled word: Dinah
Line 89 possible misspelled word: Dinah
Line 149 possible misspelled word: flavour
Line 150 possible misspelled word: toffee
Line 186 possible misspelled word: croquet
练习 15:最终练习
最后的练习有两个选项:“视频游戏选项”和“文本冒险选项”
视频游戏选项
就是这里!这是你发挥创造力的机会,真正展示你在自己的游戏中所能创造的东西。
这个最后的练习分为三个部分。每一部分都提高了你的游戏需要具备的能力。
第一部分的要求:
- 打开一个屏幕。
- 设置要在屏幕上绘制的项目。
- 通过鼠标、键盘或游戏控制器提供一些基本的玩家动作。
提示:
- 如果你的程序会涉及到互相碰撞的东西,从使用精灵开始。不要从使用绘图命令开始,并期望以后添加精灵。这是行不通的,你需要从头开始。这将是可悲的。
- 如果你正在编写一个类似扫雷或连接四的程序,不要使用精灵。因为不需要碰撞检测,所以没有必要搞乱精灵。
- 在“更长的游戏示例”下,我有两个程序展示了如何创建 pong 或 breakout 风格的游戏。不要只是把这些作为第一部分上交;在它真正合格之前,你需要增加很多。
OpenGameArt.org
有很多图片和声音你可以免费使用。Kenney.nl
有许多形象和声音。
第二部分的要求:
对于最后的练习第二部分,你的游戏应该是功能性的。一个人应该能够坐下来玩几分钟游戏,让它感觉像一个真正的游戏。以下是您可能想要添加的一些内容:
- 能够碰撞物体。
- 如果发生不好的事情,玩家可能会输掉游戏。
- 屏幕配乐。
- 一些初始音效。
- 屏幕上其他字符的移动。
- 点击地雷或空点的能力。
第三部分的要求:
最后,为你的游戏添加最后的润色。以下是您可能想要添加的一些内容:
- 多层次
- 声音
- 多重“生命”
- 标题和说明屏幕
- 背景音乐
- 热追踪导弹
- 隐藏的门
- 扫雷游戏中的“清扫”动作或放置“旗帜”的能力
文本冒险选项
对电子游戏不感兴趣?继续你的工作从“冒险!”游戏。
第一部分的要求:
Rather than have each room be a list of [description, north, east, south, west], create a Room
class. The class should have a constructor that takes in (description, north, east, south, west) and sets fields for the description and all of the directions. Get the program working with the new class. Expand the game so that a person can travel up and down. Also expand it so the person can travel northwest, southwest, northeast, and southeast. Create another class for Object
. Give the object fields for name, description, and current room. For example, you might have a name of “key,” a description of “This is a rusty key that looks like it would fit in an old lock. It has not been used in a long time.” The current room number would be 3 if the key was in room 3. If the player is carrying the key then the current room for the object will be -1. Create a list for objects, and add several objects to the list. The code for this will be very similar to the list of rooms that you created and added to the list of rooms. After printing the description of the room, have the program search the entire list of objects, and print if the room of the object matches the room the player is in. For example, if current_room == current_object.room
then print: “There is a key here.” Test your game and make sure it works.
第二部分的要求:
Add the ability to pick up an object. If the user types get key
then: Split the user input so you split out and just have a variable equal to “key.” Search the list until you find an object that matches what the user is trying to pick up. If the object isn’t found, or if the object isn’t in the current room, print an error. If the object is found and it is in the current room, then set the object’s room number to -1. Add the ability to drop an object. Add a command for “inventory” that will print every object who’s room number is equal to -1. Add the ability to use the objects. For example “use key” or “swing sword” or “feed bear.”
第三部分的要求:
将游戏再扩展一些。尝试以下一些想法:
Create a file format that allows you to load the rooms and objects from a file rather than write code for it. Have monsters with hit points. Split the code up into multiple files for better organization. Remove globals using a main
function as shown at the end of the chapter about functions. Have objects with limited use. Like a bow that only has so many arrows. Have creatures with limited health, and weapons that cause random damage and have a random chance to hit.

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)