抛物线之winform与android的实现

    近来玩小鸟比较爽,感觉所以有种冲动想做小鸟的念头,这段时间有点闲暇所以信手写了写,忽然发现原来自已以前学过的物理都丢给了老师了,在互联网上找了一大圈也没有发现一个好的程序,在这里特别感谢我的好朋友老李友情提供了所有的物理公式与C#原理程序,之后我就顺利的改写完成了android的实现。

    希望对大家有帮助,后续还会继续解决动量的问题

    这个重点推荐一下老李的博客:http://www.cnblogs.com/DragonInSea

以下抛物线的物理公式:

 

以下是windows版的主要代码

代码
using System.Drawing;

namespace ObjectMotion
{
public class MovingObject
{
//重力加速度
public const double G = 9.8;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="V0">物体的初速度</param>
/// <param name="Sita">物体初速度与水平方向的夹角</param>
/// <param name="Color">颜色</param>
public MovingObject(double V0, double Sita, Color Color)
{
this.V0 = V0;
this.Sita = Sita;
this.Color = Color;
}

/// <summary>
/// 物体的初速度
/// </summary>
public double V0 { private set; get; }

/// <summary>
/// 物体初速度与水平方向的夹角
/// </summary>
public double Sita { private set; get; }

/// <summary>
/// 物体的横坐标
/// </summary>
public double X { set; get; }

/// <summary>
/// 物体的纵坐标
/// </summary>
public double Y { set; get; }

// 物体的颜色
public Color Color{ private set; get;}

// 要绘制的物体的矩形
public Rectangle GetObjectRectangle()
{
return new Rectangle((int)X - 3, (int)Y - 3, 6, 6);
}


/// <summary>
/// 最大射程
/// </summary>
public double Smax { set; get; }

/// <summary>
/// 最大高度
/// </summary>
public double H { set; get; }

/// <summary>
/// 运行时间
/// </summary>
public double T { set; get; }
}
}

 

 

 

代码
1 using System;
2  using System.Collections.Generic;
3  using System.ComponentModel;
4  using System.Data;
5  using System.Drawing;
6  using System.Linq;
7  using System.Text;
8  using System.Windows.Forms;
9
10  namespace ObjectMotion
11 {
12 public partial class Form1 : Form
13 {
14 public Form1()
15 {
16 InitializeComponent();
17 }
18
19 private void button1_Click(object sender, EventArgs e)
20 {
21 List<MovingObject> objects = new List<MovingObject>();
22
23 // 在此处添加多个物体
24 objects.Add(new MovingObject(30, Math.PI/4, Color.Red));
25 objects.Add(new MovingObject(30, Math.PI/3, Color.Blue));
26 objects.Add(new MovingObject(20, Math.PI/4, Color.Green));
27
28 // 计算物体的最大高度、运动时间及最大射程
29 foreach (MovingObject obj in objects)
30 {
31 // 运行时间
32 obj.T = 2*obj.V0*Math.Sin(obj.Sita)/MovingObject.G;
33
34 // 最大高度
35 obj.H = obj.V0*obj.V0*Math.Sin(obj.Sita)*Math.Sin(obj.Sita)/(2*MovingObject.G);
36
37 // 最大射程
38 obj.Smax = 2*obj.V0*obj.V0*Math.Sin(obj.Sita)*Math.Cos(obj.Sita)/MovingObject.G;
39 }
40
41 double maxS = 0;
42 double maxH = 0;
43 double maxT = 0;
44 foreach (MovingObject obj in objects)
45 {
46 if (obj.Smax > maxS)
47 {
48 maxS = obj.Smax;
49 }
50
51 if (obj.H > maxH)
52 {
53 maxH = obj.H;
54 }
55
56 if (obj.T>maxT)
57 {
58 maxT = obj.T;
59 }
60 }
61
62 double dx = (pictureBox1.Width - 20)/maxS;
63 double dy = (pictureBox1.Height - 20)/maxH;
64
65 double d = Math.Min(dx, dy);
66
67
68 Graphics g = this.pictureBox1.CreateGraphics();
69
70 for (double t = 0; t < maxT; t += 0.01)
71 {
72 if (checkBox1.Checked == false)
73 {
74 // 不显示轨迹
75 g.Clear(SystemColors.Control);
76 }
77
78 foreach (MovingObject obj in objects)
79 {
80 // 水平坐标
81 double x = obj.V0*Math.Cos(obj.Sita)*t;
82
83 // 竖直坐标
84 double y = obj.V0*Math.Sin(obj.Sita)*t - MovingObject.G*t*t/2;
85
86 if (y < 0)
87 {
88 continue;
89 }
90
91 // 坐标转换
92 obj.X = 10 + d*x;
93 obj.Y = this.pictureBox1.Height - 10 - d*y;
94
95 g.FillEllipse(new SolidBrush(obj.Color), obj.GetObjectRectangle());
96
97 System.Threading.Thread.Sleep(10);
98 }
99 }
100 }
101 }
102 }
103

 

 

以下是android版的主要代码

 

代码
package com.yarin.android.Examples_05_04;

import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class GameView extends View implements Runnable
{
/* 声明Paint对象 */
private Paint mPaint = null;

double maxS = 0;
double maxH = 0;
double maxT = 0;
double dx;
double dy;
double d;
MovingObject obj;
boolean isDraw
=false;
public GameView(Context context)
{
super(context);
/* 构建对象 */
mPaint
= new Paint();

// 计算物体的最大高度、运动时间及最大射程

obj
= new MovingObject(30, Math.PI / 4, Color.RED);
// 运行时间
obj.T = 2 * obj.V0 * Math.sin(obj.Sita) / 9.8;

// 最大高度
obj.H = obj.V0 * obj.V0 * Math.sin(obj.Sita) * Math.sin(obj.Sita)
/ (2 * 9.8);

// 最大射程
obj.Smax = 2 * obj.V0 * obj.V0 * Math.sin(obj.Sita)
* Math.cos(obj.Sita) / 9.8;

if (obj.Smax > maxS)
{
maxS
= obj.Smax;
}

if (obj.H > maxH)
{
maxH
= obj.H;
}

if (obj.T > maxT)
{
maxT
= obj.T;
}

dx
= (800 - 20) / maxS;
dy
= (480 - 20) / maxH;

d
= Math.min(dx, dy);
//最大运行时间
Log.v("TAG", String.valueOf(maxT));
//最大高度
Log.v("TAG", String.valueOf(maxH));
//最大射程
Log.v("TAG", String.valueOf(maxS));

}

public void onDraw(Canvas canvas)
{
super.onDraw(canvas);

/* 设置画布的颜色 */
canvas.drawColor(Color.BLACK);

/* 设置取消锯齿效果 */
mPaint.setAntiAlias(
true);
canvas.drawColor(Color.GREEN);
if(isDraw)
{
canvas.drawCircle((
float)obj.X, (float)obj.Y, 10, mPaint);
}


}

// 触笔事件
public boolean onTouchEvent(MotionEvent event)
{

switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
new Thread(this).start();
break;
}
return true;
}


public void run()
{
for (double t = 0; t < maxT; t += 0.01)
{
Log.v(
"TAG", String.valueOf(t));
isDraw
=true;
// 水平坐标
double x = obj.V0 * Math.cos(obj.Sita) * t;

// 竖直坐标
double y = obj.V0 * Math.sin(obj.Sita) * t - 9.8 * t * t / 2;

if (y < 0)
{
continue;
}

// 坐标转换
obj.X = 10 + d * x;
obj.Y
= 480 - 10 - d * y;
try
{
Thread.sleep(
10);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
// 使用postInvalidate可以直接在线程中更新界面
postInvalidate();

}

}
}

class MovingObject
{
// 重力加速度
public final double G = 9.8;

// / <summary>
// / 构造函数
// / </summary>
// / V0物体的初速度
// / Sita物体初速度与水平方向的夹角
// / Color颜色
public MovingObject(double V0, double Sita, int red)
{
this.V0 = V0;
this.Sita = Sita;
this.Color = red;
}

// / <summary>
// / 物体的初速度
// / </summary>
public double V0;

// / <summary>
// / 物体初速度与水平方向的夹角
// / </summary>
public double Sita;

// / <summary>
// / 物体的横坐标
// / </summary>
public double X;

// / <summary>
// / 物体的纵坐标
// / </summary>
public double Y;

// 物体的颜色
public int Color;

// 要绘制的物体的矩形
public Rect GetObjectRectangle()
{
return new Rect((int) X - 3, (int) Y - 3, 6, 6);
}

// / <summary>
// / 最大射程
// / </summary>
public double Smax;

// / <summary>
// / 最大高度
// / </summary>
public double H;

// / <summary>
// / 运行时间
// / </summary>
public double T;

}

 

posted on 2011-01-13 16:36 楚广明 阅读(2587) 评论(14) 编辑 收藏

评论

#1楼  回复 引用 查看   

呃,这个,拿sliverlight/wpf/flash/js做貌似更方便吧
2011-01-13 16:39 | 菩提树下的杨过      

#2楼  回复 引用 查看   

不知你玩通关了吗?
2011-01-13 16:48 | chenkai      

#3楼  回复 引用 查看   

昨晚玩到15关
2011-01-13 16:52 | 天行健 自强不息      

#4楼  回复 引用 查看   

用 Rx 你可以忘记一切公式,让Timer自己来做。。。

#5楼  回复 引用 查看   

很多没写过游戏的人 往往以为,游戏都是算好了以后把结果播放出来的。

但是愤怒小鸟那种飞行过程中根据操作转向的道具怎么可能事先算出来呢?

所以很多情况下 这种公式意义不大 呵呵。
话说,如果有预测弹道功能 或者外挂需求,意义就。。

#6楼  回复 引用 查看   

还得考虑空气阻力。
2011-01-13 17:14 | 麦舒      

#7楼  回复 引用 查看   

老赵太牛叉了!
2011-01-13 17:27 | 根号贰      

#8楼  回复 引用 查看   

http://files.cnblogs.com/waynebaby/Hockey.zip

这边是一个 wpf4 + Rx的例子,对于重力干脆speed=speed+g算了

#9楼  回复 引用 查看   

疯狂的小鸟,还可以发出3只鸟,楼主考虑了没?
2011-01-13 19:25 | IT鸟      

#10楼  回复 引用 查看   

我儿子把那个可加速的鸟叫快鸡
把那个分成三个鸟的叫分身鸡,霰弹鸡
把那个可以爆炸的,叫炸弹鸡,黑鸡
把那个最大的,叫胖鸡
把那个大长嘴的叫,回旋鸡
把那个可以扔炸弹的叫下蛋鸡.

通关不难,难得是得到全部金蛋.
2011-01-13 20:18 | YaoTong      

#11楼  回复 引用 查看   

引用韦恩卑鄙 v-zhewg @waynebaby:
很多没写过游戏的人 往往以为,游戏都是算好了以后把结果播放出来的。

但是愤怒小鸟那种飞行过程中根据操作转向的道具怎么可能事先算出来呢?

所以很多情况下 这种公式意义不大 呵呵。
话说,如果有预测弹道功能 或者外挂需求,意义就。。

实时运算也是要公式的吧?
按当前状态计算预订落点位置其实也是有用的
2011-01-14 09:59 | 徐少侠      

#12楼  回复 引用 查看   

除了感慨还是感慨,我现在还是上学,初中物理知识忘得都差不多了,理科生在这方面的记忆还是强啊,之前在点评狂也曾经看到过这个很多理科生的作品,只能让我们这些文科生自愧不如。
2011-02-23 21:00 | 智能手机测评      

#13楼  回复 引用 查看   

初中物理课天天睡觉,印象中就没学过物理
2011-03-23 09:08 | 默^_^默      

#14楼  回复 引用 查看   

请问下,那个求球和水平线夹角的公式怎么算啊,这个夹角应该是动态变化的
2012-01-30 15:35 | kaj      

导航

<2011年1月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

公告

公告

个人简介

  • 本名:楚广明
  • 网名:chu888chu888
昵称:楚广明
园龄:5年2个月
荣誉:推荐博客
粉丝:118
关注:3

搜索

 
 

最新随笔

随笔分类(557)

随笔档案(629)

文章分类(5)

积分与排名

  • 积分 - 258162
  • 排名 - 290

阅读排行榜