pong_Day 3:AI 对手球拍 + 计分系统 + 胜负判定

pong_Day 3:AI 对手球拍 + 计分系统 + 胜负判定

对pong这个游戏我们不必要真的接入一个ai,我们只需要对手球拍能追踪球y轴方位移动就行了

1. 创建 AI 球拍

复制player,并改名为ai_player

ai_player脚本(一定要先分离原来player脚本在创建一个新脚本):

extends CharacterBody2D @export var ai_paddle_speed:float=280 var ball:CharacterBody2D = null func _physics_process(delta:float): if ball == null: return var dif_y=ball.position.y - position.y if abs(dif_y)>10 : velocity.y = sign(dif_y) * ai_paddle_speed else: velocity.y = 0 velocity.x = 0 move_and_slide() position.y=clamp(position.y,40,440)

将ai_player添加到game场景里,调整位置 x : 560 y : 240

2.让ai看见球

给game场景添加脚本

extends Node2D func _ready() -> void: # $节点名 var ai = $ai_player var ball = $Ball #让ai这个节点识别到球 ai.ball = ball

3.创建得分检测区域

创建area2D和collisionshape2d,一个不可视的区域,当有物体进入该区域就会发出信号

更名为LeftScoreZone

将碰撞层尺寸和位置修改一下

重复上面步骤把右边的得分区也做了

4.创建 UI 显示分数

在game节点下创建canvaslayer

改名叫UI(不论背景怎么动,这个canvaslayer上的节点都不会动,很适合用于做UI)

再在UI节点下创建label用来做比分

改名score

设置水平居中,垂直居中

将字的大小调整到 48

size x : 200 y : 67

position x : 220 y : 30

再创建一个label,改名为message

和上面的操作差不多,就参数上再微调一下(这里是未来的我,size.x调成500,position.x调成70会更好,其他不变)

visible关掉,默认隐藏

5.给 Game 脚本添加计分逻辑

extends Node2D # 分数变量 var player_score : int = 0 var ai_score : int= 0 var win_score : int= 11 # 这的enum和c语言中一样 # 游戏状态 enum GameState {PLAYING,PLAYER_WIN,AI_WIN} var game_state : GameState = GameState.PLAYING # @onready可以理解成我们ready执行前才执行 # 如果不加上的话,ai_player等节点还没有被创建 # 最后会被赋值null @onready var ai : CharacterBody2D = $ai_player @onready var ball : CharacterBody2D = $Ball @onready var score_label : Label = $UI/score @onready var message_label : Label = $UI/message func _ready() -> void: ai.ball = ball # body_entered :检测是否有东西进入 # 若有则触发_on_left_score函数 $leftscorezone.body_entered.connect(_on_left_score) $rightscorezone.body_entered.connect(_on_right_score) update_score_display() func _on_left_score(body): # ai进球得分 if game_state != GameState.PLAYING : return if body == ball : ai_score += 1 check_winner() func _on_right_score(body): # 玩家进球得分 if game_state != GameState.PLAYING : return if body == ball : player_score += 1 check_winner() func check_winner(): if player_score >= win_score: game_state = GameState.PLAYER_WIN message_label.text = "You win!\n press space to restart" message_label.visible = true elif ai_score >= win_score: game_state = GameState.AI_WIN message_label.text = "AI win!\n press space to restart" message_label.visible = true else : ball.reset_ball() update_score_display() # 更新比分 func update_score_display(): score_label.text = str(player_score) + " - " + str(ai_score) # _input(event)特殊函数,当有输入的时候自动调用 func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_accept"): if game_state == GameState.PLAYER_WIN or game_state == GameState.AI_WIN : restart_game() # 重开游戏 func restart_game(): player_score = 0 ai_score = 0 message_label.visible = false game_state = GameState.PLAYING update_score_display() ball.reset_ball()

这是程序流程图可以和代码配合来看

6.结果展示

7.个人错误改证

ball要改一下初始位置,因为我们原来的初始位置就在leftscorezone上,ai会在游戏刚开始时多得一分