(二刷) godot4 游戏篇之官方2d教程 - 2024年亲测有效

1,274 阅读1分钟

初刷之际,对godot游戏开发之思路, 算是得了一些基本的要领。 然较于其他游戏引擎,这godot实有独特之所在, 此独特之处,不可不琢磨。 逐起了二刷之念, 只为更深入地消化这godot游戏开发精髓,为后续之学习筑牢更为坚实之根基。

image.png

初刷文章传送门(比较详细)

1. 项目设置

游戏素材下载

创建项目

image.png

设置窗口

image.png

2. 主角场景

外观

动画

image.png

碰撞

image.png

代码

按键

image.png

移动

image.png

动画

image.png

碰撞

image.png

开始状态

image.png

完整 playerr_Area2d.gd

extends Area2D

signal player_hit

var velocity
@export var speed = 300

func _ready() -> void:
	hide()
	pass 

func _process(delta: float) -> void:
	player_move(delta)
	player_animated()
	pass

#1. 移动 (函数名规范)
func player_move(delta) :
	velocity = Vector2(0,0)
	
	if Input.is_action_pressed("move_right") :
		velocity.x += 1
	if Input.is_action_pressed("move_left") :
		velocity.x -= 1
	if Input.is_action_pressed("move_up") :
		velocity.y -= 1
	if Input.is_action_pressed("move_down") :
		velocity.y += 1
	
	position += ( velocity.normalized() * speed * delta )
	
	position = position.clamp( Vector2.ZERO, get_viewport_rect().size )
	
#2. 动画 (函数名规范)
func player_animated() :
	if velocity.length() > 0 :
		$player_AnimatedSprite2D.play()
	else :
		$player_AnimatedSprite2D.stop()
		
	if velocity.x != 0 :
		$player_AnimatedSprite2D.animation = "walk"
		$player_AnimatedSprite2D.flip_h = (velocity.x < 0)
		$player_AnimatedSprite2D.flip_v = false
	
	if velocity.y != 0 :
		$player_AnimatedSprite2D.animation = "up"
		$player_AnimatedSprite2D.flip_v = (velocity.y > 0)
		
#3. 碰撞
func _on_body_entered(body: Node2D) -> void:
	hide()
	player_hit.emit()
	$player_CollisionShape2D.set_deferred("disabled",true)
	pass # Replace with function body.

#4. 开始状态 (函数名规范)
func player_start(pos) :
	position = pos
	show()
	$player_CollisionShape2D.disabled = false

3. 配角场景

外观

刚体

image.png

动画

image.png

碰撞

image.png

剔除

image.png

分组

image.png

代码

动画

image.png

剔除

image.png

完整 npc_RigidBody2D.gd

extends RigidBody2D

func _ready() -> void:
	npc_animated()
	pass 

func _process(delta: float) -> void:
	pass

#1. 动画
func npc_animated() :
	var npc_names = $npc_AnimatedSprite2D.sprite_frames.get_animation_names()
	var npc_name = npc_names[ randi() % npc_names.size() ]
	$npc_AnimatedSprite2D.play( npc_name )

#2. 剔除
func _on_npc_visible_on_screen_notifier_2d_screen_exited() -> void:
	queue_free()
	pass

4. GUI场景

外观

显示计分

image.png

显示内容

image.png

开始按钮

image.png

内容计时器

image.png

代码

显示分数

image.png

显示内容

image.png

按钮事件

image.png

内容计时器

image.png

游戏结束

image.png

完整 gui_CanvasLayer.gd

extends CanvasLayer

signal start_game

func _ready() -> void:
	pass

func _process(delta: float) -> void:
	pass

#1. 显示分数
func show_score(score) :
	$score_Label.text = str( score )

#2. 显示内容
func show_message(text) :
	$message_Label.text = text
	$message_Label.show()
	$message_Timer.start()

#3. 按钮事件
func _on_start_button_pressed() -> void:
	$start_Button.hide()
	start_game.emit()
	pass

#4. 内容计时
func _on_message_timer_timeout() -> void:
	$message_Label.hide()
	pass

#5. 游戏结束
func show_gameover() :
	show_message("游戏gg啦!")
	await $message_Timer.timeout
	
	#单独定制新的内容和计时器
	$message_Label.text = "再战300回合!!!"
	$message_Label.show()
	await get_tree().create_timer(1.0).timeout
	
	$start_Button.show()

5. 舞台场景

外观

主角登场

image.png

计时器

image.png

主角初始位置

image.png

配角登场区域

创建路径

image.png

跟踪路径

image.png

gui登场

image.png

背景幕布

image.png

背景音乐

image.png

image.png

结束音乐

image.png

代码

主角

image.png

配角准备登场

image.png

配角登场

image.png

配角下台

超出屏幕,销毁npc

image.png

记录分数

image.png

开始计时

image.png

重新开始游戏

image.png

gui连接重新开始游戏

image.png

gui增加游戏结束

image.png

gui增加 分数计时

image.png

背景音乐播放

image.png

结束音乐

image.png

完整 main_Node.gd

extends Node

@export var npc :PackedScene
var score

func _ready() -> void:
	pass 

func _process(delta: float) -> void:
	pass

#1. 主角受伤 游戏结束
func _on_player_hit_game_over() -> void:
	$npc_Timer.stop()
	$score_Timer.stop()
	
	$gui_CanvasLayer.show_gameover()
	
	$bgm_AudioStreamPlayer2D.stop()
	$gg_AudioStreamPlayer2D.play()
	pass 

#2. 配角登场
func _on_npc_timer_timeout() -> void:
	var npc_follow = $npc_Path2D/npc_PathFollow2D
	npc_follow.progress_ratio = randf()
	
	var rd_rotation = npc_follow.rotation + PI / 2
	rd_rotation += randf_range( -PI/4 , PI/4)
	
	var linear_speed = Vector2( randf_range(150.0 , 250.0) , 0.0 )
	
	var npcs = npc.instantiate()
	npcs.position = npc_follow.position
	npcs.rotation = rd_rotation
	npcs.linear_velocity = linear_speed.rotated( rd_rotation )
	add_child( npcs )
	
	pass

#3. 记录分数
func _on_score_timer_timeout() -> void:
	score += 1
	
	$gui_CanvasLayer.show_score( score )
	pass

#4. 开始计时
func _on_start_timer_timeout() -> void:
	$npc_Timer.start()
	$score_Timer.start()
	pass

#5. 开始游戏
func new_game() :
	score = 0
	$playerr_Area2D.player_start( $player_Marker2D.position )
	$start_Timer.start()
	
	get_tree().call_group("npc_group1","queue_free")
	
	$gui_CanvasLayer.show_score( score )
	$gui_CanvasLayer.show_message("准备开始喽!")
	
	$bgm_AudioStreamPlayer2D.play()

展示篇

image.png

游戏运行成功, 整理思绪费了些精力, 颇有收获!!!

如有不通之处, 清留言,观后解答