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

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

1. 创建 AI 球拍

复制player,并改名为ai_player

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

python 复制代码
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场景添加脚本

python 复制代码
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 脚本添加计分逻辑

python 复制代码
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会在游戏刚开始时多得一分

相关推荐
风子111 天前
pong_day02_让球飞来+碰撞反弹
godot
kyle~1 天前
Godot开源游戏引擎
开源·游戏引擎·godot
郝学胜-神的一滴2 天前
[简化版 GAMES 101] 计算机图形学 13:从光栅化到着色——赋予三维像素光影灵魂
c++·计算机视觉·unity·godot·图形渲染·opengl·unreal
Zwarwolf3 天前
Godot零散知识点项目汇总
游戏引擎·godot
caimouse5 天前
Godot Engine 最新版官方文档(简体中文完整翻译 & 精简梳理)
游戏引擎·godot
郝学胜-神的一滴6 天前
中级OpenGL教程 009:用环境光告别模型死黑
前端·c++·unity·godot·图形渲染·opengl·unreal
张学徒6 天前
Godot 4.x 中导入Excel文件的最简单的方式
游戏·godot·gdscript·游戏开发
caimouse7 天前
Godot 引擎官方常见问题(FAQ)整理
游戏引擎·godot
caimouse8 天前
Godot 4.7 内嵌 C# 模块切换到 .NET 9.0 编译指南
c#·.net·godot