进一步完善服务器功能,添加远程命令系统,踢人系统
This commit is contained in:
307
Scene/SmallGame/2048Game.gd
Normal file
307
Scene/SmallGame/2048Game.gd
Normal file
@@ -0,0 +1,307 @@
|
||||
extends Panel
|
||||
|
||||
# 游戏常量
|
||||
const GRID_SIZE = 4
|
||||
const CELL_SIZE = 90
|
||||
const CELL_MARGIN = 10
|
||||
|
||||
# 数字颜色配置
|
||||
const NUMBER_COLORS = {
|
||||
0: Color.TRANSPARENT,
|
||||
2: Color(0.93, 0.89, 0.85),
|
||||
4: Color(0.93, 0.88, 0.78),
|
||||
8: Color(0.95, 0.69, 0.47),
|
||||
16: Color(0.96, 0.58, 0.39),
|
||||
32: Color(0.96, 0.49, 0.37),
|
||||
64: Color(0.96, 0.37, 0.23),
|
||||
128: Color(0.93, 0.81, 0.45),
|
||||
256: Color(0.93, 0.80, 0.38),
|
||||
512: Color(0.93, 0.78, 0.31),
|
||||
1024: Color(0.93, 0.77, 0.25),
|
||||
2048: Color(0.93, 0.76, 0.18)
|
||||
}
|
||||
|
||||
const TEXT_COLORS = {
|
||||
2: Color.BLACK,
|
||||
4: Color.BLACK,
|
||||
8: Color.WHITE,
|
||||
16: Color.WHITE,
|
||||
32: Color.WHITE,
|
||||
64: Color.WHITE,
|
||||
128: Color.WHITE,
|
||||
256: Color.WHITE,
|
||||
512: Color.WHITE,
|
||||
1024: Color.WHITE,
|
||||
2048: Color.WHITE
|
||||
}
|
||||
|
||||
# 游戏变量
|
||||
var grid = []
|
||||
var score = 0
|
||||
var best_score = 0
|
||||
var game_over = false
|
||||
var won = false
|
||||
var can_continue = true
|
||||
|
||||
# 节点引用
|
||||
@onready var game_board = $GameBoard
|
||||
@onready var score_label = $ScoreLabel
|
||||
@onready var best_label = $BestLabel
|
||||
@onready var game_over_label = $GameOverLabel
|
||||
@onready var win_label = $WinLabel
|
||||
|
||||
func _ready():
|
||||
# 设置游戏板样式
|
||||
game_board.modulate = Color(0.7, 0.6, 0.5)
|
||||
|
||||
# 初始化游戏
|
||||
init_game()
|
||||
|
||||
func init_game():
|
||||
# 重置游戏状态
|
||||
game_over = false
|
||||
won = false
|
||||
can_continue = true
|
||||
score = 0
|
||||
|
||||
# 初始化网格
|
||||
grid.clear()
|
||||
for y in range(GRID_SIZE):
|
||||
var row = []
|
||||
for x in range(GRID_SIZE):
|
||||
row.append(0)
|
||||
grid.append(row)
|
||||
|
||||
# 添加两个初始数字
|
||||
add_random_number()
|
||||
add_random_number()
|
||||
|
||||
# 更新UI
|
||||
update_ui()
|
||||
hide_labels()
|
||||
|
||||
queue_redraw()
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed:
|
||||
if game_over:
|
||||
if event.keycode == KEY_R:
|
||||
init_game()
|
||||
return
|
||||
|
||||
if won and not can_continue:
|
||||
if event.keycode == KEY_C:
|
||||
can_continue = true
|
||||
win_label.visible = false
|
||||
return
|
||||
|
||||
# 移动控制
|
||||
var moved = false
|
||||
match event.keycode:
|
||||
KEY_UP, KEY_W:
|
||||
moved = move_up()
|
||||
KEY_DOWN, KEY_S:
|
||||
moved = move_down()
|
||||
KEY_LEFT, KEY_A:
|
||||
moved = move_left()
|
||||
KEY_RIGHT, KEY_D:
|
||||
moved = move_right()
|
||||
KEY_R:
|
||||
init_game()
|
||||
return
|
||||
|
||||
if moved:
|
||||
add_random_number()
|
||||
update_ui()
|
||||
check_game_state()
|
||||
queue_redraw()
|
||||
|
||||
func move_left() -> bool:
|
||||
var moved = false
|
||||
for y in range(GRID_SIZE):
|
||||
var row = grid[y].duplicate()
|
||||
var new_row = merge_line(row)
|
||||
if new_row != grid[y]:
|
||||
moved = true
|
||||
grid[y] = new_row
|
||||
return moved
|
||||
|
||||
func move_right() -> bool:
|
||||
var moved = false
|
||||
for y in range(GRID_SIZE):
|
||||
var row = grid[y].duplicate()
|
||||
row.reverse()
|
||||
var new_row = merge_line(row)
|
||||
new_row.reverse()
|
||||
if new_row != grid[y]:
|
||||
moved = true
|
||||
grid[y] = new_row
|
||||
return moved
|
||||
|
||||
func move_up() -> bool:
|
||||
var moved = false
|
||||
for x in range(GRID_SIZE):
|
||||
var column = []
|
||||
for y in range(GRID_SIZE):
|
||||
column.append(grid[y][x])
|
||||
|
||||
var new_column = merge_line(column)
|
||||
var changed = false
|
||||
for y in range(GRID_SIZE):
|
||||
if grid[y][x] != new_column[y]:
|
||||
changed = true
|
||||
grid[y][x] = new_column[y]
|
||||
|
||||
if changed:
|
||||
moved = true
|
||||
return moved
|
||||
|
||||
func move_down() -> bool:
|
||||
var moved = false
|
||||
for x in range(GRID_SIZE):
|
||||
var column = []
|
||||
for y in range(GRID_SIZE):
|
||||
column.append(grid[y][x])
|
||||
|
||||
column.reverse()
|
||||
var new_column = merge_line(column)
|
||||
new_column.reverse()
|
||||
|
||||
var changed = false
|
||||
for y in range(GRID_SIZE):
|
||||
if grid[y][x] != new_column[y]:
|
||||
changed = true
|
||||
grid[y][x] = new_column[y]
|
||||
|
||||
if changed:
|
||||
moved = true
|
||||
return moved
|
||||
|
||||
func merge_line(line: Array) -> Array:
|
||||
# 移除零
|
||||
var filtered = []
|
||||
for num in line:
|
||||
if num != 0:
|
||||
filtered.append(num)
|
||||
|
||||
# 合并相同数字
|
||||
var merged = []
|
||||
var i = 0
|
||||
while i < filtered.size():
|
||||
if i < filtered.size() - 1 and filtered[i] == filtered[i + 1]:
|
||||
# 合并
|
||||
var new_value = filtered[i] * 2
|
||||
merged.append(new_value)
|
||||
score += new_value
|
||||
i += 2
|
||||
else:
|
||||
merged.append(filtered[i])
|
||||
i += 1
|
||||
|
||||
# 填充零到指定长度
|
||||
while merged.size() < GRID_SIZE:
|
||||
merged.append(0)
|
||||
|
||||
return merged
|
||||
|
||||
func add_random_number():
|
||||
var empty_cells = []
|
||||
for y in range(GRID_SIZE):
|
||||
for x in range(GRID_SIZE):
|
||||
if grid[y][x] == 0:
|
||||
empty_cells.append(Vector2(x, y))
|
||||
|
||||
if empty_cells.size() > 0:
|
||||
var random_cell = empty_cells[randi() % empty_cells.size()]
|
||||
var value = 2 if randf() < 0.9 else 4
|
||||
grid[random_cell.y][random_cell.x] = value
|
||||
|
||||
func check_game_state():
|
||||
# 检查是否达到2048
|
||||
if not won:
|
||||
for y in range(GRID_SIZE):
|
||||
for x in range(GRID_SIZE):
|
||||
if grid[y][x] == 2048:
|
||||
won = true
|
||||
can_continue = false
|
||||
win_label.visible = true
|
||||
return
|
||||
|
||||
# 检查是否游戏结束
|
||||
if not can_move():
|
||||
game_over = true
|
||||
if score > best_score:
|
||||
best_score = score
|
||||
game_over_label.visible = true
|
||||
|
||||
func can_move() -> bool:
|
||||
# 检查是否有空格
|
||||
for y in range(GRID_SIZE):
|
||||
for x in range(GRID_SIZE):
|
||||
if grid[y][x] == 0:
|
||||
return true
|
||||
|
||||
# 检查是否可以合并
|
||||
for y in range(GRID_SIZE):
|
||||
for x in range(GRID_SIZE):
|
||||
var current = grid[y][x]
|
||||
# 检查右边
|
||||
if x < GRID_SIZE - 1 and grid[y][x + 1] == current:
|
||||
return true
|
||||
# 检查下面
|
||||
if y < GRID_SIZE - 1 and grid[y + 1][x] == current:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func update_ui():
|
||||
score_label.text = "分数: " + str(score)
|
||||
best_label.text = "最高分: " + str(best_score)
|
||||
|
||||
func hide_labels():
|
||||
game_over_label.visible = false
|
||||
win_label.visible = false
|
||||
|
||||
func _draw():
|
||||
if not game_board:
|
||||
return
|
||||
|
||||
# 获取游戏板位置
|
||||
var board_pos = game_board.position
|
||||
|
||||
# 绘制网格背景
|
||||
for y in range(GRID_SIZE):
|
||||
for x in range(GRID_SIZE):
|
||||
var cell_x = board_pos.x + x * (CELL_SIZE + CELL_MARGIN) + CELL_MARGIN
|
||||
var cell_y = board_pos.y + y * (CELL_SIZE + CELL_MARGIN) + CELL_MARGIN
|
||||
var rect = Rect2(cell_x, cell_y, CELL_SIZE, CELL_SIZE)
|
||||
|
||||
# 绘制单元格背景
|
||||
draw_rect(rect, Color(0.8, 0.7, 0.6), true)
|
||||
|
||||
# 绘制数字
|
||||
var value = grid[y][x]
|
||||
if value > 0:
|
||||
# 绘制数字背景
|
||||
var bg_color = NUMBER_COLORS.get(value, Color.GOLD)
|
||||
draw_rect(rect, bg_color, true)
|
||||
|
||||
# 绘制数字文本
|
||||
var text = str(value)
|
||||
var font_size = 24 if value < 100 else (20 if value < 1000 else 16)
|
||||
var text_color = TEXT_COLORS.get(value, Color.WHITE)
|
||||
|
||||
# 获取默认字体
|
||||
var font = ThemeDB.fallback_font
|
||||
|
||||
# 计算文本尺寸
|
||||
var text_size = font.get_string_size(text, HORIZONTAL_ALIGNMENT_CENTER, -1, font_size)
|
||||
|
||||
# 计算文本位置(居中)
|
||||
var text_pos = Vector2(
|
||||
cell_x + (CELL_SIZE - text_size.x) / 2,
|
||||
cell_y + (CELL_SIZE - text_size.y) / 2 + text_size.y
|
||||
)
|
||||
|
||||
# 绘制文本
|
||||
draw_string(font, text_pos, text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, text_color)
|
||||
Reference in New Issue
Block a user