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

相关推荐
weixin_404679312 天前
godot + vscode ai开发
ide·vscode·编辑器·游戏引擎·godot
松树戈5 天前
godot项目【宝石捕手】04~添加音效、记分
游戏引擎·godot
ue星空6 天前
【Godot】更换编辑器外观主题
编辑器·游戏引擎·godot
ue星空6 天前
Godot 2D像素游戏移动抖动、模糊问题解决方案
游戏·游戏引擎·godot
ue星空6 天前
【Godot】AudioStreamPlayer2D音频播放
游戏引擎·音视频·godot
松树戈7 天前
godot项目【宝石捕手】03~宝石刷新、游戏结束脚本逻辑
游戏·godot
刘欣的博客8 天前
godot 服务器客户端设计中的精灵更新
godot
卷无止境9 天前
当独立开发者也能造出3A画质的游戏:Godot引擎深度解析
后端·python·godot
Python私教18 天前
Blender 到 Godot 4 可交互宝箱:从低模资源到开箱逻辑的完整管线
godot