編輯:Android開發實例
近來玩小鳥比較爽,感覺所以有種沖動想做小鳥的念頭,這段時間有點閒暇所以信手寫了寫,忽然發現原來自已以前學過的物理都丟給了老師了,在互聯網上找了一大圈也沒有發現一個好的程序,在這裡特別感謝我的好朋友老李友情提供了所有的物理公式與C#原理程序,之後我就順利的改寫完成了android的實現。
希望對大家有幫助,後續還會繼續解決動量的問題
以下拋物線的物理公式:
以下是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;
}
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
這篇文章寫的非常好,深入淺出,關鍵還是一位大三學生自己剖析的心得。這是我喜歡此文的原因。下面請看正文: 作為一個大三的預備程序員,我學習android的一大樂趣是
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
本文首先解釋一下handler是用來干嘛的,然後通過例子介紹其在多線程中的應用。 什麼是Handler handler通俗一點講就是用來在各個進程之間發送數據的處