public static MediaElement gameMusic, gameAudio;
GameCursor.Stretch = Stretch.Fill;
GameCursor.Source = Super.GetImage("/Image/Cursor/0.png");
滑鼠移動事件中即時更新游標位置:
private void Game_MouseMove(object sender, MouseEventArgs e) {
Point p = e.GetPosition(Root);
GameCursor.SetValue(Canvas.LeftProperty, p.X);
GameCursor.SetValue(Canvas.TopProperty, p.Y);
}
此法雖能實現游標跟隨,但明顯增加 CPU 消耗,歡迎更好方案。
滑鼠左鍵點擊非物件區域時,於該位置顯示水滴動畫。單一水滴複用版:
QXDecoration hitCursor;
private void LoadHitCursor() {
hitCursor = new QXDecoration() { Code = 1, EndFrame = 9, CenterX = 32, CenterY = 32 };
hitCursor.Visibility = Visibility.Collapsed;
Add(hitCursor);
}
private void Game_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
hitCursor.Visibility = Visibility.Visible;
hitCursor.FrameCounter = 0;
hitCursor.Timer.Start();
hitCursor.Coordinate = p;
}
追求更炫效果可每次點擊新建水滴:
private void Game_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
QXDecoration hitCursor = new QXDecoration() { Code = 1, EndFrame = 9, CenterX = 32, CenterY = 32 };
Add(hitCursor);
hitCursor.Coordinate = p;
}
Demo 中的極光魔法:動畫化、360 度旋轉、不規則矩形傷害範圍,素材僅一張圖片。製作流程:
透過 QXMagic 建立實例。右鍵點擊時取得座標,延長至攻擊距離,計算旋轉角度:
public static double GetAngle(double y, double x) {
return Math.Atan2(y, x) / Math.PI * 180;
}
對魔法物件套用旋轉變換:
magic.RenderTransform = new RotateTransform() {
CenterX = 0,
CenterY = (double)magicData.Attribute("CenterY"),
Angle = magic.Angle
}
技巧:製作圖片時,刻意在激光頭部與左邊緣留白,使旋轉中心對準手部而非身體中心,免額外代碼修正發射位置。
將 360 度劃分為斜四象限(45°~135°、-135°~-45° 為一區,其餘為另一區),簡化不規則矩形四頂點計算:
public static Point[] GetRectRange(double angle, Point start, Point end, int radius) {
if ((angle >= 45 && angle <= 135) || (angle >= -135 && angle <= -45)) {
return new Point[]{
new Point(start.X - radius, start.Y),
new Point(start.X + radius, start.Y),
new Point(end.X + radius, end.Y),
new Point(end.X - radius, end.Y)
};
} else {
return new Point[]{
new Point(start.X, start.Y - radius),
new Point(start.X, start.Y + radius),
new Point(end.X, end.Y + radius),
new Point(end.X, end.Y - radius)
};
}
}
再以射線法判斷敵對精靈座標是否在多邊形內:
public static bool InPolygon(Point target, Point[] range) {
int n = 0, count = 0;
for (int i = 0; i < range.Length; i++) {
n = (i == range.Length - 1) ? 0 : n + 1;
if ((range[i].Y != range[n].Y) &&
(((target.Y >= range[i].Y) && (target.Y < range[n].Y)) || ((target.Y >= range[n].Y) && (target.Y < range[i].Y))) &&
(target.X < (range[n].X - range[i].X) * (target.Y - range[i].Y) / (range[n].Y - range[i].Y) + range[i].X)) {
count++;
}
}
return (count % 2 > 0);
}
兩節完成 WPF 到 Silverlight 移植關鍵點講解,後續教程將基於此 Silverlight 引擎全新演繹,下一節講解小地圖製作。