zoukankan      html  css  js  c++  java
  • Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣

    今天这套主题,仅仅是通过改进让游戏更加有趣,游戏中的细节永远是耐人寻味,有的游戏团队为此付诸努力甚至成为整个项目的成功关键。

    我们将在本次完成加血、背景、更加完美的碰撞,让游戏变得更加有趣。

    首先改进碰撞范围,对于主角来说,并不需要完全的碰撞,而只有身体的部分,所以将Rect设置的小一点,例如Width = 32, Height = 36

    我们再加上一个食物类,让游戏中有加血的方法,具体效果如下:

    食物类的代码如下:

    代码
    public class ClassFood : Canvas
    {
    private Rectangle _rectangle = new Rectangle()
    { Width = 32, Height = 32, Stroke = new SolidColorBrush(Colors.Green) };
    Image Food;
    ImageSource[] FoodFrames
    = new ImageSource[4];
    public ClassFood()
    {
    Food
    = new Image();
    BitmapImage bitmap
    = new BitmapImage(new Uri(@"Src/food.png", UriKind.Relative));
    bitmap.ImageOpened
    += new EventHandler<RoutedEventArgs>(bitmap_ImageOpened);
    Food.Source
    = bitmap;
    this.Children.Add(Food);

    this.Children.Add(_rectangle);
    }
    private static int _framecont = 0;
    void bitmap_ImageOpened(object sender, RoutedEventArgs e)
    {
    Food.Source
    = sender as BitmapImage;
    for (int i = 0; i < 4; i++)
    {
    WriteableBitmap wb
    = new WriteableBitmap(32, 32);
    wb.Render(Food,
    new TranslateTransform() { X = -32 * i, Y = 0 });
    wb.Invalidate();
    FoodFrames[i]
    = (ImageSource)wb;
    }
    Food.Source
    = FoodFrames[_framecont];
    _framecont
    ++;
    if (_framecont >= 4)
    _framecont
    = 0;
    }
    /// <summary>
    /// 移动速度
    /// </summary>
    public double Speed = 1;

    public double X
    {
    get { return Canvas.GetLeft(this); }
    set { Canvas.SetLeft(this, value); }
    }
    public double Y
    {
    get { return Canvas.GetTop(this); }
    set { Canvas.SetTop(this, value); }
    }
    public Rect MyRect
    {
    get
    {
    return new Rect(X, Y, _rectangle.Width, _rectangle.Height);
    }
    }
    }

    可以看出,这个部分的代码和固体类有很接近的地方,所以我们也同样的写一个组,来管理和创建整个食物动画

    代码
    public class ClassFoodGroup :Canvas
    {
    Random _random
    = new Random((int)DateTime.Now.Ticks);
    public ClassFoodGroup(int max)
    {
    int segment = (int)(MainPage.ScreenWidth - 64) / max * 2;
    for (int i = 0; i < max; i++)
    {
    ClassFood food
    = new ClassFood();
    this.Children.Add(food);
    food.X
    = _random.Next(segment * i, segment * (i + 1));
    food.Y
    = _random.Next((int)MainPage.ScreenHeight - 64) + MainPage.ScreenHeight;
    }
    DispatcherTimer dispatcherTimer
    = new DispatcherTimer();
    dispatcherTimer.Tick
    += new EventHandler(TickGameFrameLoop);
    dispatcherTimer.Interval
    = TimeSpan.FromMilliseconds(10); //重复间隔
    dispatcherTimer.Start();
    }
    private void TickGameFrameLoop(object sender, EventArgs e)
    {
    foreach (UIElement s in this.Children)
    {
    if (s is ClassFood)
    {
    ClassFood cloud
    = (s as ClassFood);
    if (cloud.Y >= -32)
    cloud.Y
    -= cloud.Speed;
    else
    cloud.Y
    = _random.Next(400 - 64) + 400;
    }
    }
    }
    }

    然后加入到游戏的主循环当中,进行检测判定:

    foreach (ClassFood food in foodgroup.Children)
    {
    Rect rt
    = food.MyRect;
    rt.Intersect(herorect);
    if (!double.IsInfinity(rt.Height) && !double.IsInfinity(rt.Width))
    {
    flyerlife.Add(
    10);
    food.Y
    = -32;
    break;
    }
    }

    好了,F5运行一下,看看效果,相信你会觉得有点意思了,当然了,其他部分的代码需要工程支持,还是先下载代码直接看吧:)

    还有一些小细节需要增加,比如背景,背景天空的加入可以让游戏更加丰满,但是背景是有一定的要求的,它肯定不可能一直在上升,于是我们搞了一个背景类来处理内部逻辑。

    代码
    public class ClassBackGroup:Canvas
    {
    //天空的高度,在这里顺便了解一下在Silverlight里取得图片的宽高
    private int skyHeight = 1000;
    public ClassBackGroup()
    {
    Image _Image
    = new Image();
    BitmapImage bitmap
    = new BitmapImage(new Uri(@"Src/sky.jpg", UriKind.Relative)) ;
    bitmap.ImageOpened
    += new EventHandler<RoutedEventArgs>(bitmap_ImageOpened);
    _Image.Source
    = bitmap;
    this.Children.Add(_Image);
    DispatcherTimer dispatcherTimer
    = new DispatcherTimer();
    dispatcherTimer.Tick
    += new EventHandler(TickBackGroupLogic);
    dispatcherTimer.Interval
    = TimeSpan.FromMilliseconds(40); //重复间隔
    dispatcherTimer.Start();
    }
    //在这个完成事件中可以取得bitmap的高度,同样宽度也可以用类似的方式
    void bitmap_ImageOpened(object sender, RoutedEventArgs e)
    {
    skyHeight
    = (sender as BitmapSource).PixelHeight;
    }
    public void TickBackGroupLogic(object sender, EventArgs e)
    {
    //如果移动大于屏幕减去天空的高度,那么就不能再动了
    if (Y< 400 - skyHeight)
    Y
    -= Speed;
    }
    public double Speed = 0.5;

    public double Y
    {
    get { return Canvas.GetTop(this); }
    set { Canvas.SetTop(this, value); }
    }
    }

    最后做一点点的修改,将辅助的线条全部隐蔽,运行效果就是如下了:

    基本上已经出来一个游戏的大概形状,在这个基础上,可以做一些修改就变成了更加丰富的游戏,预计在Flyer07就结束这套纯用代码实现的Silverlight小游戏。

    本Flyer06的源代码在这里下载。

  • 相关阅读:
    k近邻算法
    密码技术小总结
    编码的简单总结
    icmp dos和arp dos 攻击模拟实验
    WPA简单抓包分析
    Iptables实验
    Rabin简单加解密
    response响应数据
    浮动——小米手机案例
    ServletRequest请求详解
  • 原文地址:https://www.cnblogs.com/nowpaper/p/1676754.html
Copyright © 2011-2022 走看看