进一步完善服务器功能,添加远程命令系统,踢人系统
This commit is contained in:
207
Scene/SmallGame/SnakeGame.gd
Normal file
207
Scene/SmallGame/SnakeGame.gd
Normal file
@@ -0,0 +1,207 @@
|
||||
extends Panel
|
||||
|
||||
# 游戏常量
|
||||
const GRID_SIZE = 20
|
||||
const GRID_WIDTH = 30
|
||||
const GRID_HEIGHT = 30
|
||||
|
||||
# 方向枚举
|
||||
enum Direction {
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
||||
|
||||
# 游戏变量
|
||||
var snake_body = []
|
||||
var snake_direction = Direction.RIGHT
|
||||
var next_direction = Direction.RIGHT
|
||||
var food_position = Vector2()
|
||||
var score = 0
|
||||
var game_over = false
|
||||
|
||||
# 节点引用
|
||||
@onready var game_area = $GameArea
|
||||
@onready var score_label = $ScoreLabel
|
||||
@onready var game_over_label = $GameOverLabel
|
||||
@onready var game_timer = $GameTimer
|
||||
|
||||
func _ready():
|
||||
# 连接定时器信号
|
||||
game_timer.timeout.connect(_on_game_timer_timeout)
|
||||
|
||||
# 设置游戏区域样式
|
||||
game_area.modulate = Color(0.2, 0.2, 0.2, 1.0)
|
||||
|
||||
# 初始化游戏
|
||||
init_game()
|
||||
|
||||
func init_game():
|
||||
# 重置游戏状态
|
||||
game_over = false
|
||||
score = 0
|
||||
snake_direction = Direction.RIGHT
|
||||
next_direction = Direction.RIGHT
|
||||
|
||||
# 初始化蛇身
|
||||
snake_body.clear()
|
||||
snake_body.append(Vector2(5, 5))
|
||||
snake_body.append(Vector2(4, 5))
|
||||
snake_body.append(Vector2(3, 5))
|
||||
|
||||
# 生成食物
|
||||
generate_food()
|
||||
|
||||
# 更新UI
|
||||
update_score()
|
||||
game_over_label.visible = false
|
||||
|
||||
# 启动定时器
|
||||
game_timer.start()
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed:
|
||||
if game_over:
|
||||
if event.keycode == KEY_SPACE:
|
||||
init_game()
|
||||
return
|
||||
|
||||
# 控制蛇的方向
|
||||
match event.keycode:
|
||||
KEY_UP, KEY_W:
|
||||
if snake_direction != Direction.DOWN:
|
||||
next_direction = Direction.UP
|
||||
KEY_DOWN, KEY_S:
|
||||
if snake_direction != Direction.UP:
|
||||
next_direction = Direction.DOWN
|
||||
KEY_LEFT, KEY_A:
|
||||
if snake_direction != Direction.RIGHT:
|
||||
next_direction = Direction.LEFT
|
||||
KEY_RIGHT, KEY_D:
|
||||
if snake_direction != Direction.LEFT:
|
||||
next_direction = Direction.RIGHT
|
||||
|
||||
func _on_game_timer_timeout():
|
||||
if game_over:
|
||||
return
|
||||
|
||||
# 更新方向
|
||||
snake_direction = next_direction
|
||||
|
||||
# 移动蛇
|
||||
move_snake()
|
||||
|
||||
# 检查碰撞
|
||||
check_collisions()
|
||||
|
||||
# 重绘游戏
|
||||
queue_redraw()
|
||||
|
||||
func move_snake():
|
||||
var head = snake_body[0]
|
||||
var new_head = head
|
||||
|
||||
# 根据方向计算新的头部位置
|
||||
match snake_direction:
|
||||
Direction.UP:
|
||||
new_head = Vector2(head.x, head.y - 1)
|
||||
Direction.DOWN:
|
||||
new_head = Vector2(head.x, head.y + 1)
|
||||
Direction.LEFT:
|
||||
new_head = Vector2(head.x - 1, head.y)
|
||||
Direction.RIGHT:
|
||||
new_head = Vector2(head.x + 1, head.y)
|
||||
|
||||
# 添加新头部
|
||||
snake_body.insert(0, new_head)
|
||||
|
||||
# 检查是否吃到食物
|
||||
if new_head == food_position:
|
||||
# 增加分数
|
||||
score += 10
|
||||
update_score()
|
||||
|
||||
# 生成新食物
|
||||
generate_food()
|
||||
else:
|
||||
# 移除尾部
|
||||
snake_body.pop_back()
|
||||
|
||||
func check_collisions():
|
||||
var head = snake_body[0]
|
||||
|
||||
# 检查边界碰撞
|
||||
if head.x < 0 or head.x >= GRID_WIDTH or head.y < 0 or head.y >= GRID_HEIGHT:
|
||||
game_over = true
|
||||
show_game_over()
|
||||
return
|
||||
|
||||
# 检查自身碰撞
|
||||
for i in range(1, snake_body.size()):
|
||||
if head == snake_body[i]:
|
||||
game_over = true
|
||||
show_game_over()
|
||||
return
|
||||
|
||||
func generate_food():
|
||||
var attempts = 0
|
||||
while attempts < 100: # 防止无限循环
|
||||
food_position = Vector2(
|
||||
randi() % GRID_WIDTH,
|
||||
randi() % GRID_HEIGHT
|
||||
)
|
||||
|
||||
# 确保食物不在蛇身上
|
||||
var food_on_snake = false
|
||||
for segment in snake_body:
|
||||
if segment == food_position:
|
||||
food_on_snake = true
|
||||
break
|
||||
|
||||
if not food_on_snake:
|
||||
break
|
||||
|
||||
attempts += 1
|
||||
|
||||
func update_score():
|
||||
score_label.text = "分数: " + str(score)
|
||||
|
||||
func show_game_over():
|
||||
game_timer.stop()
|
||||
game_over_label.visible = true
|
||||
|
||||
func _draw():
|
||||
if not game_area:
|
||||
return
|
||||
|
||||
# 获取游戏区域的位置和大小
|
||||
var area_pos = game_area.position
|
||||
var area_size = game_area.size
|
||||
|
||||
# 计算网格大小
|
||||
var cell_width = area_size.x / GRID_WIDTH
|
||||
var cell_height = area_size.y / GRID_HEIGHT
|
||||
|
||||
# 绘制蛇身
|
||||
for i in range(snake_body.size()):
|
||||
var segment = snake_body[i]
|
||||
var rect = Rect2(
|
||||
area_pos.x + segment.x * cell_width,
|
||||
area_pos.y + segment.y * cell_height,
|
||||
cell_width - 1,
|
||||
cell_height - 1
|
||||
)
|
||||
|
||||
# 头部用不同颜色
|
||||
var color = Color.GREEN if i == 0 else Color.LIME_GREEN
|
||||
draw_rect(rect, color)
|
||||
|
||||
# 绘制食物
|
||||
var food_rect = Rect2(
|
||||
area_pos.x + food_position.x * cell_width,
|
||||
area_pos.y + food_position.y * cell_height,
|
||||
cell_width - 1,
|
||||
cell_height - 1
|
||||
)
|
||||
draw_rect(food_rect, Color.RED)
|
||||
Reference in New Issue
Block a user