踢球程序

简介: 【10月更文挑战第24天】

image.png
这个程序是一个简单的足球射门游戏,它使用Python的pgzrun库来创建和管理游戏界面。游戏的目标是通过控制一个球员(皮皮)来踢五个球,并将它们射入球门。如果所有球都成功射入球门,则玩家获胜;否则,玩家失败。下面是对这个程序设计思路的总结分析,以及一个编程故事来讲解这个项目。

设计思路

  1. 初始化游戏元素

    • 使用字典pics来跟踪每个球是否已经被踢过。
    • 定义全局变量press_keykick_flagshootscore来控制游戏逻辑和得分。
  2. 绘制游戏界面

    • 使用draw_picture函数来绘制球和球员。
    • 使用for循环来初始化球场上的球。
  3. 控制球员移动和踢球

    • 使用on_key_down函数来检测空格键的按下,触发踢球动作。
    • 使用update函数来控制球员的左右移动和球的飞行轨迹。
  4. 球的物理运动

    • 使用三角函数和角度来计算球的移动方向和距离。
  5. 检测进球

    • 使用collide_point函数来检测球是否射入球门。
  6. 游戏状态管理

    • 使用state变量来管理游戏的不同状态,如开始、运行和结束。
  7. 声音和视觉效果

    • 使用musicsound模块来增加背景音乐和音效,提升游戏体验。

编程故事

很久很久以前,在一个充满激情的足球小镇上,居民们决定举办一场特别的足球比赛。这场比赛不同于普通的足球赛,它需要球员们用智慧和技巧来控制射门的角度和力量,以确保球能够准确地射入球门。

小镇的程序员们决定将这场比赛数字化,让全世界的人们都能参与。他们创建了一个名为“皮皮射门”的游戏,玩家将控制一个名叫皮皮的球员,通过键盘上的左右键来调整射门角度,空格键来踢球。

游戏开始时,皮皮站在球场中央,五个球随机分布在球场上。玩家的目标是踢中所有五个球,并将它们射入球门。每次成功的射门都会为皮皮赢得分数,而每次失败的射门都会让皮皮感到沮丧。

随着游戏的进行,皮皮的角度和力量控制得越来越好,他开始理解如何利用物理原理来提高射门的准确性。每当皮皮成功射入一个球,球场上就会响起欢呼声,激励他继续努力。

最终,如果皮皮能够成功射入所有五个球,他将赢得比赛,球场上会响起胜利的音乐。但如果他未能全部射中,游戏将结束,皮皮将不得不重新开始,直到他掌握射门的艺术。

这个游戏不仅考验了玩家的反应速度和策略思考,还向他们介绍了基本的物理概念,如角度、力量和运动轨迹。通过这个编程故事,程序员们不仅创造了一个有趣的游戏,还教育了下一代足球运动员。

'''
操作介绍:按键盘左右按键切换皮皮角度,(角度在-60~60之间)
点击空格键踢球,球的中心点在球门内则得分。
球场的球全部踢中就胜利,否则失败
'''
pics = {
   1: False,2: False,3: False,4: False,5: False}
# 画图函数
def draw_picture(d):
    if d in pics:
        pics[d] = True

press_key = 'SPACE'
kick_flag = False  
# 踢球函数
def kick():
    global kick_flag
    kick_flag = True
# 绘制足球和球员角色和球门(画图指令)
for i in range(1,5+1):
    draw_picture(i)
# 如果按下空格键,则踢球(if语句)
if press_key == 'SPACE':
    kick()

shoot = "YES"

# 进球得分,初始值为0
score = 0
# 当shoot变量的结果为'YES',表示射中了球门
if shoot == 'YES':
    # 累积得分
    score += 100

####################################################
from pgzrun import *
import math
start = Actor('开始',(336,147)) 
bg = Actor('bg')   
ball1 = Actor('ball1')  
ball2 = Actor('ball2')  
ball3 = Actor('ball3')  
ball4 = Actor('ball4')  
ball5 = Actor('ball5')
goal = Actor('球门')
over = Actor('win', (300,169))
player = Actor('球员')
ban = Actor('分数板子')
music.play('WeWillRockYou')
music.volume = 0.6
ball_list = [ball1,ball2,ball3,ball4,ball5]
isadd = False
show_num = 0  # 这个变量表示界面上画几个球
for i in pics:
    if not pics[i]:
        ball_list[int(i)-1].pos = (1000,10)
    else:
        show_num += 1

state = 'start'
real_score = 0
def draw():
    if state == 'start':
        start.draw()
    elif state == 'run':
        bg.draw()
        goal.draw()
        for i in ball_list:
            i.draw()
        player.draw()
        screen.draw.text('得分:'+str(real_score),(70,16),'white',25)
        if isadd:
            ban.pos = (t_x,t_y)
            ban.draw()
            screen.draw.text('+'+str(score),(t_x,t_y),'white',20)
    else:
        over.draw()

def change_run():
    global state
    state = 'run'

def stop_music():
    music.stop()

def change_state():
    global state
    if real_score!= 0 and real_score == show_num*score:
        state = 'win'
        sound.play('进球欢呼')
    else:
        state = 'lose'
        over.frame = 1
        sound.play('遗憾')
    clock.schedule(stop_music, 3)
frame_num = 0

def play_run():
    global frame_num
    player.frame = frame_num
    frame_num += 1
    if frame_num > 2:
        frame_num = 0

clock.schedule_interval(play_run, 0.1)

def play_kick():
    global frame_num
    player.frame = frame_num
    frame_num += 1
    if frame_num > 6:
        frame_num = 3



k_flag = []
def on_key_down(key):
    global k_flag,frame_num
    if key == 'SPACE':
        sound.play('踢球音效')
        clock.unschedule(play_run)
        frame_num = 3
        clock.schedule_interval(play_kick, 0.1)
        for i in ball_list:
            if i.collide_actor(player):
                k_flag.append(i)
                k_flag.append(player.angle)
# 画加分文字
def add():
    global isadd
    isadd =False

angle_change = 1
pipi_change = 5
kick_num = 0
ball_step = 8
t_x =0
t_y =0 

def update():
    global real_score,k_flag,pipi_change,kick_num,t_x,t_y,isadd
    if state=='start':
        clock.schedule(change_run,3)
    # 皮皮移动
    if len(k_flag)==0:
        player.x+=pipi_change
        clock.unschedule(play_kick)
        clock.schedule_interval(play_run, 0.1)
    if player.x<=20 or player.x>=580:
        pipi_change *= -1
    # 控制角度
    if keyboard.right:
        player.angle += angle_change
    elif keyboard.left:
        player.angle -= angle_change
    if player.angle>=60:
        player.angle = 60
    elif player.angle<=-60:
        player.angle = -60
    # 球的移动
    if kick_flag:
        if len(k_flag)!=0:

            k_flag[0].y -= math.cos((math.pi/180)*k_flag[1])*ball_step
            k_flag[0].x += math.sin((math.pi/180)*k_flag[1])*ball_step
            k_flag[0].frame = 1
            k_flag[0].angle += 10
            k_flag[0].scale -= 0.005
            # 是否进球
            if goal.collide_point(k_flag[0].pos):
                real_score += score
                isadd = True
                t_x=k_flag[0].x
                t_y =k_flag[0].y-30
                clock.schedule(add, 1.5)
                sound.play('胜利')
                player.angle = 0
                k_flag[0].pos = (1000,62)
                k_flag = []
                kick_num += 1
            elif k_flag[0].y < 20:
                player.angle = 0
                sound.play('失败')
                k_flag[0].pos =  (1000,62)
                k_flag = []
                kick_num += 1
            if kick_num == show_num:
                clock.schedule(change_state, 1.0)


go()
目录
相关文章
|
7月前
|
机器学习/深度学习 数据采集 算法
“开水白菜”——程序应用中的上等国宴
“开水白菜”——程序应用中的上等国宴
70 0
“开水白菜”——程序应用中的上等国宴
|
小程序 前端开发 程序员
【小程序】网络数据请求
【小程序】网络数据请求
260 0
【小程序】网络数据请求
程序人生 - 一直打嗝怎么办?
程序人生 - 一直打嗝怎么办?
111 0
|
算法
循序渐进写程序
【来信】   老师,我现在是初学编程,感觉自己的编程能力比较弱,如果做一道算法题,有时候需要两三个小时,做出来之后还没有答案上给的算法好,应该是练习比较少,我是应该多看别人写好的算法,然后多敲代码好呢,还是尽量自己写,写不出来再看答案好呢(感觉自己写好浪费时间) 【回复】   我们的学习,要讲究循序渐进。你出现这种情况,应该是做的题目中,包含了太多对你而言是“新知识”的
1024 1
程序24和程序25
【程序24】 题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。 $num = rand(1,99999); strlen($num); $arr_num = str_split($num); array_reverse($arr_num);strlen() 返回给定的字符串的长度。
584 0
程序30和程序31
【程序30】题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。 $marr = array(1,3,5,7,9,11,13,15); function setPosArr($num,$arr){ for($i=count($arr);$i>0;$i--...
662 0