自己写远程控制软件之键鼠响应

上一篇说图像压缩和显示的时候,大家已经看到了在客户端的捕捉键鼠消息的代码,这里就直接说在服务器的实现了。

代码其实很简单但是需要注意的是,在网络接收消息后,不要在网络回调里,直接 mouse_event或者keybd_event 做其它事情也不行,除了缓冲区取一个缓冲区,然后 Post 到 IOCP 以外,否则,轻则影响效率,重则死锁当然接收的数据还是要处理的,用的是线程池函数 QueueUserWorkItem,你懂的。不过,QueueUserWorkItem 有时,有点问题(有时有 .Net 程序运行的时候,CPU 很高,原因不明,可能是要和 .Net 强线程吧),不过,我有仿 QueueUserWorkItem 的函数,可以避免这个问题,这里就不说了

DWORD WINAPI RunCommand(LPVOID lpParam)
{
	SOCKET_POST_CTRL *pRecv = (SOCKET_POST_CTRL *) lpParam;
	switch (pRecv->remoteCtrl.dwCtrl) {
		case CTRL_MOUSE:
			SetCursorPos(pRecv->remoteCtrl.x * GetSystemMetrics(SM_CXSCREEN) / pRecv->remoteCtrl.dwWidth, 
						 pRecv->remoteCtrl.y * GetSystemMetrics(SM_CYSCREEN) / pRecv->remoteCtrl.dwHeight);

			mouse_event(pRecv->remoteCtrl.dwFlags, 0, 0, 0, 0);
			break;
		case CTRL_KEYBOARD:
			::keybd_event((BYTE) pRecv->remoteCtrl.nChar, (BYTE) pRecv->remoteCtrl.nChar, pRecv->remoteCtrl.nFlags, 0);
			break;
		default:
			break;
	}
	SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
	return 0;
}


VOID OnRecv(SOCKET_POST *pPost)
{
	SOCKET_POST_CTRL *pRecv = (SOCKET_POST_CTRL *) pPost;
	if (pRecv->dwBytesTrans == 0) {
		IOCP_Close(pRecv->pInfo);
		SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
	}
	else {
		pRecv->dwLeftSize -= pRecv->dwBytesTrans;
		if (pRecv->dwLeftSize > 0) {
			pRecv->pWSABuf		= &(pRecv->wsaBuf[0]);
			pRecv->dwBufCount	= ItemCount(pRecv->wsaBuf);
			pRecv->wsaBuf[0].len= pRecv->dwLeftSize;
			pRecv->wsaBuf[0].buf= (PCHAR) &(pRecv->pktHead);
			pRecv->wsaBuf[0].buf+= (sizeof(pRecv->pktHead) + sizeof(pRecv->remoteCtrl) - pRecv->dwLeftSize);

			IOCP_PostRecv(m_hIOCP, pRecv->pInfo, pRecv);
		}
		else {
			switch (pRecv->pktHead.dwStamp) {
				case STAMP_PACKET:
					QueueUserWorkItem(RunCommand, pRecv, 0);
					SQ_PopFront(m_hQueueRecv, ForceCast<LPDWORD>(&pRecv));
					PostRecv(m_pInfo, pRecv);
					break;
				default:
					IOCP_Close(pRecv->pInfo);
					SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
					break;
			}
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我来给你简要介绍一下如何使用 GDScript 来键鼠控制的第三人称相机。 首先,我们要创建一个脚本,然后在脚本中声明一个变量来存储相机的速度。然后在脚本的 _input() 函数中,使用 is_action_pressed() 函数来检测是否按下了 W、A、S、D 或者标右键。如果按下了,就调用 translate() 函数来移动相机。 下面是一个简单的示例代码: ``` extends Camera var speed = 10 func _input(event): if event.is_action_pressed("ui_up"): translate(Vector3(0, speed, 0)) if event.is_action_pressed("ui_down"): translate(Vector3(0, -speed, 0)) if event.is_action_pressed("ui_left"): translate(Vector3(-speed, 0, 0)) if event.is_action_pressed("ui_right"): translate(Vector3(speed, 0, 0)) func _process(delta): if Input.is_mouse_button_pressed(BUTTON_RIGHT): rotate_y(Input.get_mouse_position().x - get_viewport().get_visible_rect().size.x / 2) rotate_x(Input.get_mouse_position().y - get_viewport().get_visible_rect().size.y / 2) ``` 这段代码实现了键鼠控制第三人称相机的基本功能,你可以根据自己的需要进一步完善它。 ### 回答2: 使用GDScript编键鼠控制的第三人称相机可以通过以下步骤实现: 首先,创建一个相机节点和一个目标节点作为场景的子节点。相机节点是用来渲染场景视图的,目标节点是用来控制相机位置和旋转的。 在代码中,我们需要创建变量来存储相机和目标节点的引用。我们可以使用`var`关键字声明这些变量,并在`_ready()`函数内获取引用。 接下来,我们可以设置相机的初始位置和朝向。通过将相机的位置和旋转设置为目标节点的子节点,我们可以实现第三人称的效果。 接下来,我们需要监测玩家的输入,并根据输入控制相机的位置和旋转。在GDScript中,我们可以使用`_input(event)`函数来获取用户输入。 通过检查输入事件的类型和按键代码,我们可以确定玩家是在移动相机还是旋转相机。例如,当玩家按下标左键并且移动标时,我们可以根据标的移动来旋转相机。当玩家按下WASD键时,我们可以根据按键来平移相机。 根据不同的输入事件,我们可以分别对相机进行平移和旋转操作。通过修改目标节点的位置和旋转,相机会相应地跟随目标节点移动和旋转。 最后,我们可以在主循环函数`_process(delta)`中更新相机的位置和朝向。在每一帧中,我们需要将相机的位置和旋转设置为目标节点的子节点的位置和旋转。 通过以上步骤,我们就可以使用GDScript编一个实现键鼠控制的第三人称相机。这样玩家就可以通过操作键盘和标来控制相机的位置和旋转,实现第三人称视角的游戏体验。 ### 回答3: 使用GDScript编键鼠控制的第三人称相机可以通过以下步骤完成: 1. 创建一个类来实现相机的逻辑。我们可以命名为ThirdPersonCamera.gd。 2. 在类中定义变量来存储相机的位置、旋转和其他相关信息。例如: ``` var cameraPosition = Vector3(0, 2, -5) var cameraRotation = Vector3(10, 0, 0) ``` 3. 在_ready()函数中初始化相机并设置其初始位置和旋转。例如: ``` func _ready(): $Camera.transform.origin = cameraPosition $Camera.transform.basis = Basis().rotated(Vector3(0, 1, 0), deg2rad(cameraRotation.y)) ``` 4. 在_process(delta)函数中处理键盘和标输入来控制相机的移动和旋转。例如: ``` func _process(delta): # 检测键盘输入来移动相机 if Input.is_key_pressed(KEY_W): cameraPosition += $Camera.transform.basis.z * delta if Input.is_key_pressed(KEY_S): cameraPosition -= $Camera.transform.basis.z * delta if Input.is_key_pressed(KEY_A): cameraPosition -= $Camera.transform.basis.x * delta if Input.is_key_pressed(KEY_D): cameraPosition += $Camera.transform.basis.x * delta # 检测标输入来旋转相机 cameraRotation.y += Input.get_mouse_speed().x * delta cameraRotation.x -= Input.get_mouse_speed().y * delta ``` 5. 在_physics_process(delta)函数中将相机的位置和旋转应用到实际的相机节点上。例如: ``` func _physics_process(delta): $Camera.transform.origin = cameraPosition $Camera.transform.basis = Basis().rotated(Vector3(0, 1, 0), deg2rad(cameraRotation.y)) $Camera.transform.basis = $Camera.transform.basis.rotated(Vector3(1, 0, 0), deg2rad(cameraRotation.x)) ``` 通过以上步骤,我们就可以使用GDScript编键鼠控制的第三人称相机。在游戏中,玩家可以使用标来旋转相机,并使用W、A、S、D键来在水平方向上移动相机。这样可以模拟出第三人称视角的相机效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值