1.控制玩家移動(dòng)
在
func _process(delta):
中進(jìn)行處理 :
var velocity = Vector2()
if Input.is_action_pressed("ui_up"):
velocity.y -= 1
if Input.is_action_pressed("ui_down"):
velocity.y += 1
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed #velocity.normalized() 將向量變成一個(gè)單位比例
$AnimatedSprite.play() #播放動(dòng)畫(huà)
else:
$AnimatedSprite.stop()
position += velocity *delta # 變化位置
# 限制在 屏幕區(qū)域內(nèi)部
# screensize = get_viewport_rect().size 獲取 屏幕區(qū)域大小
position.x = clamp(position.x , 0 ,screensize.x)
position.y = clamp(position.y , 0 ,screensize.y)
# 設(shè)置動(dòng)畫(huà)方向诱建,默認(rèn) 右.上骗卜, 如果檢測(cè)到速度變化史侣,則 反轉(zhuǎn)動(dòng)畫(huà)方向
# 動(dòng)畫(huà)只需要設(shè)置一個(gè)方向即可枢贿。
if velocity.x != 0:
$AnimatedSprite.animation = "right"
$AnimatedSprite.flip_v = false
$AnimatedSprite.flip_h = (velocity.x < 0 )
if velocity.y != 0:
$AnimatedSprite.animation = "up"
$AnimatedSprite.flip_v = (velocity.y > 0 )
$AnimatedSprite.flip_h = false
動(dòng)畫(huà)部分改進(jìn): 如果同時(shí)按下 上嘁圈,右方向省骂,則導(dǎo)致 不現(xiàn)實(shí)幀動(dòng)畫(huà),具體改進(jìn)如下:
# 設(shè)置動(dòng)畫(huà)方向最住,默認(rèn) 右.上钞澳, 如果檢測(cè)到速度變化,則 反轉(zhuǎn)動(dòng)畫(huà)方向
# 動(dòng)畫(huà)只需要設(shè)置一個(gè)方向即可涨缚。
if velocity.x != 0 and (abs(velocity.x) > abs(velocity.y)):
$AnimatedSprite.animation = "right"
$AnimatedSprite.flip_v = false
$AnimatedSprite.flip_h = (velocity.x < 0 )
if velocity.y != 0 and (abs(velocity.x) < abs(velocity.y)):
$AnimatedSprite.animation = "up"
$AnimatedSprite.flip_v = (velocity.y > 0 )
Player 為Area2D 類(lèi)型轧粟,移動(dòng)的敵人是
Rigidbody2D
類(lèi)型,可以連接 body_entered 信號(hào),進(jìn)行檢測(cè)逃延,是否與敵人發(fā)生碰撞
func _on_Player_body_entered(body):
hide()
emit_signal("hit")
$CollisionShape2D.disabled = true
print('debug--> ',body)
2.敵人相關(guān):
VisibilityNotifier2D組建览妖,可以檢測(cè)是否移動(dòng)出了屏幕,進(jìn)行相關(guān)判斷揽祥,如果移動(dòng)出屏幕讽膏,則調(diào)度自己進(jìn)行刪除。
func _on_Visibility_screen_exited():
queue_free()
GDSCript 控制分組相關(guān):
- 將節(jié)點(diǎn)加入分組: xxx.add_to_group("enemies")
- 獲取分組拄丰,并且調(diào)用對(duì)應(yīng)的函數(shù): get_tree().call_group("enemies", "player_was_discovered")
- var enemies = get_tree().get_nodes_in_group("enemies") 獲取分組的所有節(jié)點(diǎn)
動(dòng)態(tài)加載場(chǎng)景府树,實(shí)例化,并且綁定信號(hào):
var player = load('res://Player.tscn') # 加載場(chǎng)景
player_inst = player.instance() # 實(shí)例化
add_child(player_inst) # 添加到節(jié)點(diǎn)
player_inst.connect('hit',self,'game_over') # 綁定信號(hào)
鼠標(biāo)輸入相關(guān)判斷:
extends Sprite
signal shoot(bullet, direction, location)
var Bullet = preload("res://Bullet.tscn")
func _input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.pressed:
emit_signal("shoot", Bullet, rotation, position)
func _process(delta):
look_at(get_global_mouse_position())
觸摸相關(guān) 屏幕相關(guān):
需要在項(xiàng)目設(shè)置中開(kāi)啟 模擬觸屏事件
第一步是打開(kāi)”P(pán)roject Settings”并找到 “Display” -> “Window” -> Handheld 部分料按。啟用 Emulate Touchscreen 選項(xiàng)奄侠。這使得您可以將鼠標(biāo)點(diǎn)擊事件視為觸摸事件
func _input(event):
if event is InputEventScreenTouch and event.is_pressed():
_isTouchControl = true
target = event.position
func _process(delta):
# # Called every frame. Delta is time since last frame.
# # Update game logic here.
if position.distance_to(target) > 10 :
velocity = (target-position).normalized() * speed
else:
# 鍵盤(pán)控制
velocity = Vector2()
_isTouchControl = false
手動(dòng)定義動(dòng)畫(huà) tween 的用法
Tween interpolate_property
方法。它需要七個(gè)參數(shù):
- 對(duì)擁有該屬性的節(jié)點(diǎn)進(jìn)行動(dòng)畫(huà)的引用
- 屬性的標(biāo)識(shí)符作為字符串
- 起始值
- 端值
- 動(dòng)畫(huà)以秒為單位的持續(xù)時(shí)間
- 過(guò)渡的類(lèi)型
- 過(guò)度類(lèi)型的參數(shù)载矿。
以下示例:相當(dāng)于在0.3秒內(nèi)垄潮,將animated_health 設(shè)置為 新值 health
然后在_process中 更新進(jìn)玩家的生命值度條
func _process(delta):
bar.value = animated_health
number_label.text = str(round(animated_health))
pass
# 更新 生命值
func update_health(health:int):
tween.interpolate_property(self,"animated_health",animated_health,health,0.3,Tween.TRANS_LINEAR,Tween.EASE_IN)
if !tween.is_active():
tween.set_active(true)
pass
示例效果 如下:(由于插值有可能是浮點(diǎn)數(shù),所以闷盔,需要使用函數(shù)將其轉(zhuǎn)換為整數(shù))
bar.value = animated_health
number_label.text = str(round(animated_health))
切換場(chǎng)景
change_scene ( String path )
change_scene_to ( PackedScene packed_scene )
返回值Error
Kinematic character (2D) 控制運(yùn)動(dòng)
var speed = 200
var gravity = 200
var velocity =Vector2()
func _ready():
pass # Replace with function body.
func get_input():
if Input.is_action_pressed("ui_right"):
velocity.x = speed
pass
elif Input.is_action_pressed("ui_left"):
velocity.x = -speed
else:
velocity.x = 0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
get_input()
velocity.y += gravity*delta
#move_and_collide(velocity)
move_and_slide(velocity,Vector2(0,-1))
蓄能
蓄能時(shí)間 需要根據(jù)實(shí)際 進(jìn)行適當(dāng)調(diào)整 弯洗, 另外設(shè)置最大值 , 蓄能可以從
-max_impulse 到 + max_impulse:float 逢勾,方便進(jìn)行方向控制
extends RigidBody2D
### 備注: 蓄能條核心代碼
###
### 瞬間沖力大小牡整,可以有方向,上方或者下方
var to_maximpulse_time = 2
var impulse:float =0
var max_impulse:float = 500
var acceleration # 計(jì)算得出
# Called when the node enters the scene tree for the first time.
func _ready():
acceleration = max_impulse / to_maximpulse_time
$ProgressBar.min_value = -max_impulse
$ProgressBar.max_value = max_impulse
pass # Replace with function body.
func _process(delta):
if Input.is_action_pressed("ui_select"):
#self.linear_velocity.y = -speed # y is down, we need player up
#
# 需要判斷 目前最大速度溺拱,否則速度太大 會(huì)導(dǎo)致穿過(guò)模型出去逃贝,
# 一個(gè)物理周期 的位移穿過(guò)了模型,導(dǎo)致檢測(cè)不到 碰撞了迫摔。
if self.linear_velocity.length() < 1000.0:
self.apply_central_impulse( Vector2(0,-impulse).rotated(self.rotation ) )
# update speed
_update_speed(delta)
$ProgressBar.value = impulse
pass
func _physics_process(delta):
pass
func _update_speed(delta):
if abs(impulse) > abs(max_impulse):
acceleration = -acceleration
impulse +=delta*acceleration