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

相关推荐
Python私教2 天前
Godot 4 角色移动为什么要用 CharacterBody2D?从 Input Map 到碰撞滑动一次讲透
godot
Python私教2 天前
Godot 4 TileMapLayer 入门:从图集、碰撞到可玩的 2D 关卡
godot
Python私教2 天前
Godot图片怎么导入?PNG、压缩、Mipmap与Reimport一次讲清
游戏引擎·godot
Python私教2 天前
Blender模型导入Godot完整教程:GLB、BLEND与继承场景怎么选
运维·godot·blender
寒水馨2 天前
Linux下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_linux.x86_64.zip)
linux·游戏引擎·godot·游戏开发·2d游戏·3d游戏·godot engine
寒水馨2 天前
macOS下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_macos.universal.zip)
macos·3d·游戏引擎·godot·跨平台·游戏开发·2d
Python私教3 天前
Godot怎么下载和安装?零基础完成第一次启动
人工智能·游戏·godot
Python私教8 天前
我用 AI 做出了第一个 Godot 贪吃蛇
人工智能·游戏引擎·godot
郝学胜-神的一滴11 天前
中级OpenGL教程 020:巧用数组与循环实现多点点光源渲染,告别冗余代码重构方案
c++·unity·游戏引擎·godot·图形渲染·unreal
KillJUMP16 天前
SDF函数
godot·着色器