C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②
第二种方法,CompositionTarget动画,官方描述为:CompositionTarget对象可以根据每个帧回调来创建自定义动画。其实直接点,CompositionTarget创建的动画是基于每次界面刷新后触发的,与窗体刷新率保持一致,所以频率是固定的,很难人工介入控制。
那么如何使用它?xaml的界面代码还是和上一篇中描述的一样,这里不累述了。那么接下来就是创建对象并注册事件,全部代码如下:
Rectangle rect; //创建一个方块作为演示对象
double speed = 1; //设置移动速度
Point moveTo; //设置移动目标
public Window1() {
InitializeComponent();
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Width = 50;
rect.Height = 50;
rect.RadiusX = 5;
rect.RadiusY = 5;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, 0);
Canvas.SetTop(rect, 0);
//注册界面刷新事件
CompositionTarget.Rendering += new EventHandler(Timer_Tick);
}
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
moveTo = e.GetPosition(Carrier);
}
CompositionTarget的注册事件方法为:
CompositionTarget.Rendering += new EventHandler(Timer_Tick);
因为我们要实现的是鼠标点哪方块就移动到哪,所以我用一个变量moveTo保存鼠标点击点的Point。并在鼠标左键事件中赋值:moveTo = e.GetPosition(Carrier);同时设置方块X,Y方向的速度均为speed。
接下来就是实现Timer_Tick了,它是基于窗体的时时刷新事件。我们这样写:
private void Timer_Tick(object sender, EventArgs e) {
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed : -speed));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed : -speed));
}
首先获取方块的X,Y位置,接下让方块的X,Y与moveTo的X,Y进行比较而判断是+speed还是-speed,这里的逻辑需要朋友们自行领会了。
好了Ctrl+F5测试一下,呵呵,是不是同样也动起来了呢?
可是大家会发现一个很大的问题:这方块移动得也太勉强了吧,抖来抖去的而且移动得也不平滑,是不是CompositionTarget有问题?其实不然,因为之前的Storyboard动画它不存在X,Y轴的速度,只需要设定起点和终点以及过程经历的时间就可以平滑的移动了,而CompositionTarget需要分别设定X,Y轴的速度,而我们这为了简单演示,X,Y轴的速度speed均设置成了5,这在现实使用中是绝对不合理的。因此,如果要模拟实际效果,必须计算终点和起点的正切值Tan,然后再根据直线速度speed通过Tan值计算出speed_X,speed_Y,最后改写成:
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y));
这样才能实现真实的移动(具体算法就不讨论了)。
这一节讲解了如何使用CompositionTarget主界面刷新线程实现基于帧的动画,下一节我将讲解第三种动态创建动画的方法,并会对这三种方法进行一个归纳比较。
作者:深蓝色右手
出处:http://alamiye010.cnblogs.com/
教程目录及源码下载:点击进入(欢迎加入WPF/Silverlight小组 WPF/Silverlight博客团队)
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。
Tag标签: WPF/Silverlight动画游戏教程
深蓝色右手
关注 - 38
粉丝 - 250
荣誉:微软社区精英,推荐博客
关注博主
1
0
0
(请您对文章做出评价)
« 上一篇:C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
» 下一篇:C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三)让物体动起来③
posted on 2009-06-17 21:04 深蓝色右手 阅读(9703) 评论(41) 编辑 收藏
2009-06-18 09:32 | 花纯春
支持博主
回复 引用 查看
#2楼
2009-06-18 12:46 | sparks345
第1节课就出师不利啊⊙﹏⊙b
为什么我的这里报错哇 Storyboard下就没有SetTarget方法
Storyboard.SetTarget
还有这里,说缺参数
storyboard.Begin();
回复 引用 查看
#3楼
2009-06-18 13:14 | W.SiMin[未注册用户]
个人感觉XNA比较缺乏GUI系统,要自己写,然后注入进去,还有其他的比如物理啊,什么的都要自己实现,比起C++那么多的开源组件,XNA显得比较蹩脚,就像当年的DIRECTX.NET
回复 引用
#4楼[楼主]
2009-06-18 15:26 | 深蓝色右手
@sparks345
注意添加引用,需要引用Media类
回复 引用 查看
#5楼
2009-06-18 21:06 | 凯锐
@sparks345
是你的.net framework沒有打sp1,這個Storyborad在sp1中有修改過的!
博主在目錄中就指出了在vs2008 sp1 +以上開發的呀!
呵呵.....
回复 引用 查看
#6楼
2009-06-22 10:39 | 丝丝[未注册用户]
能不能把示例代码放上来
回复 引用
#7楼
2009-06-22 16:40 | yuhenyunchou[未注册用户]
private void Timer_Tick(object sender, EventArgs e)
{
var rectX = Canvas.GetLeft(rectangle);
var rectY = Canvas.GetTop(rectangle);
if (moveTo.X == rectX && moveTo.Y == rectY) return;
var width = Math.Abs(rectX - moveTo.X);
var height = Math.Abs(rectY - moveTo.Y);
var speedX = width > height ? speed : Width * speed / height;
var speedY = width > height ? height * speed / width : speed;
Canvas.SetLeft(rectangle, rectX + (rectX < moveTo.X ? speedX : -speedX));
Canvas.SetTop(rectangle, rectY + (rectY < moveTo.Y ? speedY : -speedY));
}
回复 引用
#8楼
2009-06-22 16:42 | 雨恨云愁
真实的移动实现补充如上
回复 引用 查看
#9楼
2009-06-22 17:14 | 雨恨云愁
疏忽了,上面的代码
var speedX = width > height ? speed : Width * speed / height;
应该改成:
var speedX = width > height ? speed : width * speed / height;
回复 引用 查看
#10楼[楼主]
2009-06-22 18:31 | 深蓝色右手
@雨恨云愁
^()^,感谢您的支持!
回复 引用 查看
#11楼
2009-06-27 18:10 | Fencer_HAHA[未注册用户]
@雨恨云愁
你在9楼写的代码不一样吗?
而且加上后有时候还是不稳定
回复 引用
#12楼
2009-07-04 17:44 | ianc
画面抖动的原因应该不是博主讲的那样
private void Timer_Tick(object sender, EventArgs e) {
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if (Math.Abs(rect_X - moveTo.X) > 1)
{
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed : -speed));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed : -speed));
}
}
这样就可以了。
回复 引用 查看
#13楼
2009-07-05 17:34 | mienfong[未注册用户]
樓上少了Y軸,是下面的寫法才對。
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if (Math.Abs(rect_X - moveTo.X) > 1 || Math.Abs(rect_Y - moveTo.Y) > 1)
{
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed : -speed));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed : -speed));
}
回复 引用
#14楼[楼主]
2009-07-05 18:03 | 深蓝色右手
@mienfong
@ianc
呵呵,感谢大家的支持!
回复 引用 查看
#15楼
2009-07-10 16:16 | 乡村里的.NET
上面的代码也没解决抖动的问题
回复 引用 查看
#16楼
2009-07-18 09:50 | 刑ˇ天
怎么要转弯啊?不能直线吗?
回复 引用 查看
#17楼[楼主]
2009-07-18 17:16 | 深蓝色右手
@刑ˇ天
不太清楚您说的是什么
回复 引用 查看
#18楼
2009-07-23 17:03 | sdhj
Rectangle rect;
double speed = 1;
double speed_X;
double speed_Y;
Point moveTo=new Point(0,0);
public Window2()
{
InitializeComponent();
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Width = 50;
rect.Height = 50;
rect.RadiusX = 5;
rect.RadiusY = 5;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, 0);
Canvas.SetTop(rect, 0);
//注册界面刷新事件
CompositionTarget.Rendering += new EventHandler(Timer_Tick);
}
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
moveTo = e.GetPosition(Carrier);
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
double x = Math.Abs(moveTo.X - rect_X);
double y = Math.Abs(moveTo.Y - rect_Y);
double len = Math.Sqrt(x * x + y * y);
if (len != 0)
{
speed_X = (x / len) * speed;
speed_Y = (y / len) * speed;
}
else
{
speed_X = speed;
speed_Y = speed;
}
}
private void Timer_Tick(object sender, EventArgs e)
{
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y));
}
回复 引用 查看
#19楼
2009-07-30 21:18 | 为理想在路上奔跑
楼主,我把那个speed改大了点,抖的好厉害哦,这是什么原因,是应为刷新的问题么
回复 引用 查看
#20楼
2009-08-05 17:15 | wangxj[未注册用户]
DoubleAnimation doubleAnimation = new DoubleAnimation( Canvas.GetLeft(rect), p.X,new Duration(TimeSpan.FromMilliseconds(500)));
我在wpf里,这句可以通过,在silverlight里,我句报错,wpf和sl不一样吗?
回复 引用
#21楼[楼主]
2009-08-05 18:22 | 深蓝色右手
@wangxj
写法上会有区别,功能上也是有差距的,毕竟SL是子集
回复 引用 查看
#22楼
2009-08-08 16:21 | 快乐的流浪汉
刚开始学你的这个系列教程,很好!!!
好象还没有人解决speed改大抖的厉害的问题哦!
我改了一下,解决了这个问题,供参考一下,呵呵!!!!!
其他部分代码一样,主要改动如下:
private void Timer_Tick(object sender, EventArgs e)
{
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if (moveTo.X == rect_X && moveTo.Y == rect_Y)
return;
double width = Math.Abs(rect_X - moveTo.X);
double height = Math.Abs(rect_Y - moveTo.Y);
double judgeSpeed = width > height ? width : height;
if (judgeSpeed > speed)
{
double speed_X = width > height ? speed : width * speed / height;
double speed_Y = width > height ? height * speed / width : speed;
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X));
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y));
}
else
{
Canvas.SetLeft(rect, moveTo.X);
Canvas.SetTop(rect, moveTo.Y);
}
}
回复 引用 查看
#23楼
2009-08-09 21:23 | sparks345
double rectX = Canvas.GetLeft(rect);
double rectY = Canvas.GetTop(rect);
if (Double.IsNaN(rectY))
rectY = 0;
Canvas.SetLeft(rect, rectX +( rectX > moveTo.X ? -speed : speed));
double lx = Math.Abs(moveTo.X - rectX);
double ly = Math.Abs(moveTo.Y - rectY);
double speedY = ly * speed / lx;
Canvas.SetTop(rect, rectY + (rectY > moveTo.Y ? -speedY : speedY));
------------------
不知道为什么 Canvas.GetTop(rect) 会返回 NaN~~
好郁闷~~
回复 引用 查看
#24楼[楼主]
2009-08-09 21:43 | 深蓝色右手
不行你先设置一下Canvas.SetTop(rect)调试一下
回复 引用 查看
#25楼
2009-08-18 14:39 | peerless
呵呵呵 这是很不错的教程啊。。。。
谢谢楼主
我这样做了一使矩形不抖
Rectangle rect; //创建一个方块作为演示对象
double actionTime = 400; //设置动作时间(相对于屏幕刷新次数的时间,如400即为屏幕刷新400次需要的时间)
double speedX = 0;
double speedY = 0;
Point moveTo; //设置移动目标
public MainPage()
{
InitializeComponent();
rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Red);
rect.Width = 50;
rect.Height = 50;
rect.RadiusX = 5;
rect.RadiusY = 5;
Carrier.Children.Add(rect);
Canvas.SetLeft(rect, 0);
Canvas.SetTop(rect, 0);
//注册界面刷新事件
CompositionTarget.Rendering += new EventHandler(Timer_Tick);
}
private void Carrier_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
moveTo = e.GetPosition(Carrier);
speedX = (moveTo.X - Canvas.GetLeft(rect))/actionTime;
speedY = (moveTo.Y - Canvas.GetTop(rect))/actionTime;
}
private void Timer_Tick(object sender, EventArgs e)
{
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if ((moveTo.X - Canvas.GetLeft(rect) < 1) && (moveTo.X - Canvas.GetLeft(rect) > -1))
speedX = 0;
if ((moveTo.Y - Canvas.GetTop(rect) <1) && (moveTo.Y - Canvas.GetTop(rect) > -1))
speedY = 0;
Canvas.SetLeft(rect, rect_X + speedX);
Canvas.SetTop(rect, rect_Y + speedY);
}
回复 引用 查看
#26楼
2009-08-20 09:49 | 卷毛[未注册用户]
产生闪烁的主要原因如下:
speed代表了方块每次移动的距离,当最后一次移动时,会超过moveTo所指定值,所以,要比较每次移动的预期位置与moveTo,当预期位置小于moveTo时,移动到预期的位置,否则移动到moveTo。
具体代码如下,请各位指正:
private void Timer_Tick(object sender, EventArgs e)
{
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if (rect_X == moveTo.X && rect_Y == moveTo.Y)
return;
double width = Math.Abs(rect_X - moveTo.X);
double height = Math.Abs(rect_Y - moveTo.Y);
double len = Math.Sqrt(width * width + height * height);
double speed_X = speed * width / len;
double speed_Y = speed * height / len;
double offset_X = rect_X < moveTo.X ? speed_X : -speed_X;
double offset_Y = rect_Y < moveTo.Y ? speed_Y : -speed_Y;
if(Math.Abs(rect_X - moveTo.X) > offset_X)
Canvas.SetLeft(rect, rect_X + offset_X);
else
Canvas.SetLeft(rect, moveTo.X);
if (Math.Abs(rect_Y - moveTo.Y) > offset_Y)
Canvas.SetTop(rect, rect_Y + offset_Y);
else
Canvas.SetTop(rect, moveTo.Y);
}
回复 引用
#27楼
2009-12-16 14:59 | 哈哈哈由于[未注册用户]
引用卷毛:
private void Timer_Tick(object sender, EventArgs e)
{
double rect_X = Canvas.GetLeft(rect);
double rect_Y = Canvas.GetTop(rect);
if (rect_X == moveTo.X && rect_Y == moveTo.Y)
return;
double width = Math.Abs(rect_X - moveTo.X);
double height = Math.Abs(rect_Y - moveTo.Y);
double len = Math.Sqrt(width * width + height * height);
double speed_X = speed * width / len;
double speed_Y = speed * height / len;
double offset_X = rect_X < moveTo.X ? speed_X : -speed_X;
double offset_Y = rect_Y < moveTo.Y ? speed_Y : -speed_Y;
if(Math.Abs(rect_X - moveTo.X) > offset_X)
Canvas.SetLeft(rect, rect_X + offset_X);
else
Canvas.SetLeft(rect, moveTo.X);
if (Math.Abs(rect_Y - moveTo.Y) > offset_Y)
Canvas.SetTop(rect, rect_Y + offset_Y);
else
Canvas.SetTop(rect, moveTo.Y);
} quote]
可以讲讲吗都是什么意思吗?
回复 引用
#28楼
2010-01-12 00:36 | 采云摘月
按照楼主提出的解决方案,果然能够防止抖动!谢谢,楼主提醒啊!!
代码如下:
view source
print?
01
double
rect_X = Canvas.GetLeft(rect);
02
double
rect_Y = Canvas.GetTop(rect);
03
double
x = Math.Abs(moveTo.X - rect_X);
04
double
y = Math.Abs(moveTo.Y - rect_Y);
05
double
tanR;
06
if
(x == 0)
07
{
08
tanR = 0;
09
speed_Y = 0;
//
10
speed_X = 0;
11
}
12
else
13
{
14
tanR = y / x;
15
speed_Y = speed * Math.Sin(Math.Atan(tanR));
//
16
speed_X = speed * Math.Cos(Math.Atan(tanR));
17
}
18
Canvas.SetLeft(rect, rect_X + (rect_X < moveTo.X ? speed_X : -speed_X));
19
Canvas.SetTop(rect, rect_Y + (rect_Y < moveTo.Y ? speed_Y : -speed_Y));
回复 引用 查看
#29楼
2010-01-27 10:11 | 包建强
CompositionTarget的Rending事件上挂的方法,不用的时候最好Remove掉,不然会降低性能。
回复 引用 查看
#30楼[楼主]
2010-01-27 15:13 | 深蓝色右手
@包建强
是的,类似传统游戏中的游戏主循环。
回复 引用 查看
#31楼
2010-03-23 22:39 | Coki
角度只在左键点击时才会改变,应该把计算speed_x和speed_y的过程放在鼠标点击事件里,帧更新的方法里只需要加减这个固定的速度就好了,抖动是因为某帧结束后方块从目标点一边移动到了另一边,下一帧时他又会移回来,如此往复。所以防止抖动还要加上一个判断,假如某方向当前距离小于或等于该方向的速度,直接把方块移动到目标点上即可。
view source
print?
01
private
void
Timer_Tick(
object
sender, EventArgs e)
02
{
03
double
rect_x = Canvas.GetLeft(rect);
04
double
rect_y = Canvas.GetTop(rect);
05
if
(Math.Abs(rect_x - moveTo.X) <= speed_x || Math.Abs(rect_y - moveTo.Y) <= speed_y)
06
{
07
Canvas.SetLeft(rect, moveTo.X);
08
Canvas.SetTop(rect, moveTo.Y);
09
}
10
else
11
{
12
Canvas.SetLeft(rect, rect_x + ((rect_x > moveTo.X) ? -speed_x : speed_x));
13
Canvas.SetTop(rect, rect_y + ((rect_y > moveTo.Y) ? -speed_y : speed_y));
14
}
15
}
16
17
private
void
Canvas_MouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
18
{
19
moveTo = e.GetPosition(carrier);
20
x = Math.Abs(Canvas.GetLeft(rect) - moveTo.X);
21
y = Math.Abs(Canvas.GetTop(rect) - moveTo.Y);
22
if
(x != 0 && y != 0)
23
{
24
double
tan = y / x;
25
speed_y = Math.Sin(Math.Atan(tan)) * speed;
26
speed_x = (1 / tan) * speed_y;
27
}
28
else
if
(x == 0 && y != 0)
29
{
30
speed_x = 0;
31
speed_y = speed;
32
}
33
else
if
(x != 0 && y == 0)
34
{
35
speed_x = speed;
36
speed_y = 0;
37
}
38
else
if
(x == 0 && y == 0)
39
{
40
speed_x = 0;
41
speed_y = 0;
42
}
43
}
C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②相关推荐
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):目录
本系列教程的示例代码下载(感谢 银光中国 提供资源分流): 第一部分源码:WPFGameTutorial_PartI(1-20节) 第二部分源码:WPFGameTutorial_PartII(21-2 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①
序:自从QXGame(WPF GAME ENGINE)游戏引擎公布以来,受到很多朋友的热切关注,于是乎有了写教程的想法.那么从今天开始,我将带领大家一步一步的学会如何使用纯C#开发WPF/Silver ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十八) 完美精灵之八面玲珑(WPF Only)②...
紧接着上一节,首先得解释一下为什么需要将这272张图片合成为一张大图.因为如果游戏中还有装备.坐骑等其他设置,那么我们就需要对图片源进行时时的合成:同时对272张甚至更多的图片进行合成效率高还是对2张 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十五)完美捕捉精灵之神器 -- HitTest...
怪物们都出现了,如何选中自己心仪的怪是主角目前首要做的事. 为了进行鼠标状态区别,我首先对鼠标变化规则进行约束:当鼠标在屏幕上空旷地图区域移动时,鼠标光标形态表现为默认光标 (0号光标图片),当鼠标经 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四)实现2D人物动画①
通过前面的学习,我们掌握了如何动态创建物体移动动画,那么接下来我将介绍WPF中如何将物体换成2D游戏角色,并通过使用前面所讲的DispatcherTimer计时器来实现2D人物角色的各种动作动画. 动 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十九) 落雷!治疗!陷阱!连锁闪电!多段群伤!魔法之终极五重奏②...
本节,我将完成本教程示例游戏的最终两个魔法:传说中的连锁闪电与暴风雪.如此经典与华丽的家伙无论在哪款好游戏中都少不了它们的踪影. 首先是连锁闪电,在<英雄无敌>中体现得尤为出色,击中一个怪 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十六)通用型角色头像面板...
目前游戏的开发进度已经基本实现了精灵对象之间的普通交互,接下来我们需要朝着实现战斗系统的目标前行.而实现它的前提是必须完善精灵控件的基本属性,如添加生命值.魔法值.活力值.经验值等基本属性并通过窗体界 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十七)远距离单体攻击与单体魔法...
到目前为止,主角能使用的魔法均为群攻型魔法,群攻魔法的原理相对简单,常见如圆形范围,矩形范围,扇形范围等等,当魔法释放后可以按照本教程的做法对所有坐标处于相应范围内的怪物进行伤害处理,这是直观的处理方 ...
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十)斜度α地图的构造及算法...
在当前的网络游戏中,地图基本都是采取一定斜度的拼装地图,这其中存在两种斜度地图的构造方式: 第一种我称之为伪斜度地图:该类型地图表现层图片为斜度的,但地图基底障碍物等的构造则实为正方形,如下图: 其实 ...
最新文章
- socket编程缓冲区大小对send()的影响
- 【转】C# 中文URL编码
- C语言——反弹球游戏(第二阶段
- 压控元器件和流控元器件
- WebBrowser中html元素如何触发winform事件
- 专家点评Science | 朱冰/许瑞明合作团队报道CpG岛结合蛋白BEND3作用机制
- 如何实现单链表交换任意两个元素(不包括头结点)
- vue element隐藏组件滚动条scrollbar使用
- C语言 #define
- 数学模型--预测模型、BP神经网络预测
- JAVAFX的table样式修改
- 网络编程 write 阻塞和非阻塞下的区别
- CTC算法论文阅读笔记:Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurren
- Keras中的深度学习的模型:序列模型(Sequential)和通用模型(Model)
- 学科前沿讲座课程总结与感悟
- vulnhub:Who Wants To Be King: 1
- 第14章-1~3 法兰接头预紧力密封接触分析周期对称 (介绍、局部柱坐标系建立、周期对称的设置) Beta选项打开、 cyclic region、symmetry
- rhce考试linux环境,RHCSA考试题及RHCE考试题
- 利用Word去除图片背景色
- 微信中无法直接下载棋牌游戏类app的解决办法
热门文章
- 信息学奥赛一本通 1091:求阶乘的和 / 2026:【例4.12】阶乘和 / OpenJudge NOI 1.5 34
- 信息学奥赛一本通(1163:阿克曼(Ackmann)函数)
- Cantor表(洛谷-P1014)
- 29 FI配置-财务会计-外币评估-分配到评估范围和会计核算原则
- python现在的时间是几点_Python 的日期和时间处理
- python 默认参数_避坑指南!Python里面的这九个坑,坑的就是你!
- java静默安装_jdk silent install - JDK的静默安装
- C++:利用sort()对vector中的数据自定义排序
- pytorch中Mini-batch批处理实现函数xx.unsqueeze(0)
- 默认参数,命名参数,可变参数