ERLEDIGT
JA
JA
ANTWORTEN
17
17
ZUGRIFFE
2630
2630
EMPFEHLEN
-
hallo
ich habe versucht eine beschleunigte Bewegung zu erstellen.
in Physik habe ich imemr gut aufgepasst und in Flash mit ActionScript hat das auch ganz gut funktioniert.
Nun habe ich e sin XNA Gamestudio versucht.
Mein Problem: mit konstanter Geschwindigkeit klappt alles, aber sobald ich eine konstante Beschleunigung mit reinrechne, bewegt sich das Objekt sehr alngsam und Geschwindigkeit ist trotzdem noch konstant.
Wenn mir jemand erklären könnte, wo mein Fehler liegt, wäre ich froh.
PHP-Code:public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D strand;
Texture2D ball;
Vector2 ballposition = Vector2.Zero;
Vector2 ballgeschw = new Vector2(50.0f, 250.0f);
Vector2 ballbeschl = new Vector2(0, 20f);
}
void UpdateSprite(GameTime gameTime)
{
float t = (float)gameTime.ElapsedGameTime.TotalSeconds;
ballgeschw += ballbeschl * t;
ballposition += ballgeschw * t; ;
int MaxX = graphics.GraphicsDevice.Viewport.Width - ball.Width;
int MinX = 0;
int MaxY = graphics.GraphicsDevice.Viewport.Height - ball.Height;
int MinY = 0;
// Kollisionsabfrage
if (ballposition.X > MaxX)
{
ballgeschw.X *= -1;
ballposition.X = MaxX;
}
else if (ballposition.X < MinX)
{
ballgeschw.X *= -1;
ballposition.X = MinX;
}
if (ballposition.Y > MaxY)
{
ballgeschw.Y *= -1;
ballposition.Y = MaxY;
}
else if (ballposition.Y < MinY)
{
ballgeschw.Y *= -1;
ballposition.Y = MinY;
}
}
-
Ok soweit ich das sehe, liegt der Fehler hier:
ballgeschw += ballbeschl * t;
ballposition += ballgeschw * t; ;
weil wenn du ballposition += ballgeschw * t; rechnest, würdest du ja so tun also ob der Ball von Anfang der Zeit t (t=0) schon mit ballgeschw + ballbeschl fliegt, was ja falsch ist, denn der Ball hat erst zu dem Zeitpunkt t auch wirklich ballgeschw + ballbeschl.
ich würde das ganze so machen
s = 1/2 * a * t² (Formel für beschleunigte Bewegung)
also:
ballpostion.X += 1/2 * ballbeschl.X * t * t + ballgeschw.X * t;
ballgeschw.X += ballbeschl.X * t; //Erst jetzt der Geschwindigkeit zuweisen!!
das gleich dann auch noch für y
ICH BIN MIR DA JETZT ABER NICHT SICHER, müsste aber glaube ich stimmen...
-
hallo
danke für die antwort.
ich habe es ausprobiert:
einmalund einmal habe ich das t hinter ballgeschwindigkeit weggelassen:PHP-Code:ballpostion.X += 1/2 * ballbeschl.X * t * t + ballgeschw.X * t;
ballgeschw.X += ballbeschl.X * t;
normalerweise müsste 1/2*a*t² + v*t stimmen....PHP-Code:ballpostion.X += 1/2 * ballbeschl.X * t * t + ballgeschw.X;
ballgeschw.X += ballbeschl.X * t;
in der ersten Version passiert genau das, was ich am anfang auch hatte. Der Ball bewegt sich mit konstanter Geschwindigkeit und sehr langsam.
in Version zwei bewegt sich der Ball auch mit konstanter Geschindikeit, aber viel schneller.
Eine beschleunigte Bewegung hab ich leider immer noch nicht.
Ich vermute so langsam, dass mit t etwas nicht stimmt.Geändert von 3dsmaxer (19.04.08 um 11:35 Uhr)
-
Du muss schreiben:
ballpostion.X += 0.5f * ballbeschl.X * t * t + ballgeschw.X * t;
ballgeschw.X += ballbeschl.X * t;
so geht's, ich hab's mal bei mir getestet, allerdings jezt nicht xna sondern nur geschwind mit gdi+
wenn du 1 / 2 rechnest erhält der PC 0, weil er es als eine int Rechnung durchfüht, und so kann es auch niemals beschleunigt werden. Oder halt einfach 1f / 2f
-
Es erscheint mir alles logisch, was du schreibst.
Ich habe es nun auf beide Arten versucht, mit 0.5f und mit 1f/2f.
Der Ball bewegt sich nun nicht mehr so extrem langsam, aber leider ist die Beschleunigung immernoch nicht vorhanden, der Ball hat immer noch eine konstante Geschwindigkeit.
-

Du kannst mal alle Teilberechnungen der Formel in einzelne Variablen speichern und dann mit dem Debugger schauen ob er noch etwas falsch rechnet. Wenn du willst kann ich dir auch mein kurzes Testprojekt schicken. Aber der Fehler kann eigentlich niht mehr in der Formel liegen, weil bei mir hat es ja auch funktioniertGeändert von Hiiims (20.04.08 um 19:21 Uhr)
-
ich hab jetzt alle Teilrechnungen in Variablen gespeichert.
Der Fehler ist immernoch der selbe.
Ich hab nun den Debugger gestartet, und unter jede Variablegeschrieben.PHP-Code:Console.Write(varibalennamen);
Aber in der Console wird leider nichts ausgegeben.
Langsam glaube ich, dass XNA nicht ganz richtig läuft...
-
Auf die Konsole kannst du so nichts schreiben, das geht nur bei einer Konsolenanwendung, so weit ich weiß. Müsste man mal googeln ob oder wie man die so öffnen könnte.
Aber was ich meinte war, dass du im Debugger die Werte der Variablen anschaust. Wenn du im Debugg-Modus mit der Maus über eine Variable fährst, wird deren Wert angezeigt. So sparst du dir dann auch die Konsole.
-
20.04.08 22:16 #9
- Registriert seit
- Sep 2007
- Beiträge
- 473
Vielleicht ist zum Ausgeben das hier möglich:
Debug.Write("Huhu")
Dann sollte "Huhu" im Ausgabe-Fenster in Visual Studio landen...
-
funktioniert leider nicht....
Wenn ichschreibe, kommt: "Der Name Debug ist im aktuellen Kontext nicht vorhanden."PHP-Code:Debug.Write("irgendwas");
Komisch, da ich weiß, dass es die Klasse Debug in Visual Studio geben sollte.
-
Du must erst using System.Diagnostics; einbinden, damit der Debug findet.
Außerdem das Fenster unter Ansicht->Ausgabe öffnen oder Strg+W,O
-
immerhin die Ausgabe funktioniert nun.
ich lasse mir zuerst die halbe Ballbeschleunigung ausgeben, dann die Ballgeschwindigkeit*t und dann t².
Komischerweise wechslen sich nur immer 2 zaheln ab, obwohl ich ja 3 Variablen ausgeben lasse. Die Zaheln sind auf jeden Fall imerm gleich.
8333350,000277778900,8333350,000277778900,8333350,000277778900,.....
ich bin immer mehr verwirrt...
-----------edit---------------
ich hab jetzt nen ansatz. ich hab mir einfach nru mal meine variable t ausgeben lassen, die die Zeit mitzählt. aber t ist konstant....
PHP-Code:float t = (float)gameTime.ElapsedGameTime.TotalSeconds;
Geändert von 3dsmaxer (22.04.08 um 10:21 Uhr)
-
Poste doch noch mal deinen neuen Code hier, vielleicht kann jemand den Fehler finden.
Ob t konstant ist oder nicht ist eigentlich egal, bzw. muss egal sein, denn t wird ja übergeben, damit unabhänging von der Geschwindigkeit des PCs das Spiel ausgeführt werden kann. Also jetzt grad wie in deinem Fall, dass der Ball auf einem Pentium 2, 3, 4 ... PC die gleiche Geschwindigkeit hat. Denn die Methoden Update() bzw. Draw() werden nicht immer in selben Zeitabständen aufgerufen (auch wenn es jetzt bei dir so aussah), sondern sofort nach dem alle Update()-Methoden bzw. Draw()-Methoden durchlaufen sind. (also: alle Update() -> alle Draw() -> alle Update() -> alle Draw()...). Auch kann die Ausführungsgeschwindigkeit von der Anzahl von Prozessen abhängen, die nebenher auf dem PC laufen.Geändert von Hiiims (22.04.08 um 21:30 Uhr)
-
es ist klar, das alle prozessoren unterscheidlich lange brauchen, um einen befehl zu verarbeiten.
aber t müsste doch trotzdem jede sekunde verändert werden....
hier mal der ganze quellcode, wenn der fehler nicht gefunden wird, werde ich es aufgeben mit visual studio bzw c# noch etwas zu machen...
aber trotzdem danke für eure hilfe, ich hab jetzt dadurch schon einiges gelernt.
PHP-Code:using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Diagnostics;
namespace WindowsGame2
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D strand;
Texture2D ball;
Vector2 ballposition = Vector2.Zero;
Vector2 ballgeschw = new Vector2(50.0f, 250.0f);
float ballbeschl = 20f;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
strand = Content.Load<Texture2D>("strands");
ball = Content.Load<Texture2D>("ball");
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
UpdateSprite(gameTime);
base.Update(gameTime);
}
void UpdateSprite(GameTime gameTime)
{
//Ball bewegen
float t = (float)gameTime.ElapsedGameTime.TotalSeconds;
Debug.Write(t);
float ballbeschlhalb = 0.5f * ballbeschl;
Debug.Write(ballbeschlhalb);
float ballgeschwmalt = ballgeschw.X * t;
Debug.Write(ballgeschwmalt);
float tquadr = t * t;
Debug.Write(tquadr);
ballposition.X += ballbeschlhalb * tquadr + ballgeschwmalt ;
int MaxX = graphics.GraphicsDevice.Viewport.Width - ball.Width;
int MinX = 0;
int MaxY = graphics.GraphicsDevice.Viewport.Height - ball.Height;
int MinY = 0;
//Kollisionsabfrage
if (ballposition.X > MaxX)
{
ballgeschw.X *= -1;
ballposition.X = MaxX;
}
else if (ballposition.X < MinX)
{
ballgeschw.X *= -1;
ballposition.X = MinX;
}
if (ballposition.Y > MaxY)
{
ballgeschw.Y *= -1;
ballposition.Y = MaxY;
}
else if (ballposition.Y < MinY)
{
ballgeschw.Y *= -1;
ballposition.Y = MinY;
}
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(strand, Vector2.Zero, Color.White);
spriteBatch.Draw(ball, ballposition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
-
Setzt mal das
für deine Geschwindigkeitsberechnung ein, also statt:Code :1 2 3
float t = (float)gameTime.ElapsedGameTime.TotalSeconds; ballposition.X += 0.5f * ballbeschl * t * t + ballgeschw.X * t; ballgeschw.X += ballbeschl * t;
Code :1 2 3 4 5 6 7 8 9
float t = (float)gameTime.ElapsedGameTime.TotalSeconds; Debug.Write(t); float ballbeschlhalb = 0.5f * ballbeschl; Debug.Write(ballbeschlhalb); float ballgeschwmalt = ballgeschw.X * t; Debug.Write(ballgeschwmalt); float tquadr = t * t; Debug.Write(tquadr); ballposition.X += ballbeschlhalb * tquadr + ballgeschwmalt ;
Bei mir hat's so einwanfrei funktioniert.
Wiso sollte t jeder Sekunde verändert werden? Wenn das auszuführende immer gleich bleibt wie in deimem Fall muss das nicht unbedingt sein.Geändert von Hiiims (24.04.08 um 17:16 Uhr)
Ähnliche Themen
-
Bewegung...
Von Mailyn im Forum Visual Basic 6.0Antworten: 2Letzter Beitrag: 05.09.05, 22:46 -
beschleunigte bewegung an schiefer linie
Von Lloyd im Forum Flash PlattformAntworten: 2Letzter Beitrag: 10.08.05, 18:47 -
Bewegung...
Von Mailyn im Forum Visual Basic 6.0Antworten: 12Letzter Beitrag: 14.07.05, 15:19 -
HELP bewegung programmieren!
Von mama-karl im Forum Flash PlattformAntworten: 2Letzter Beitrag: 21.04.05, 10:49 -
[mx] stop bewegung
Von Rip van Winkle im Forum Flash PlattformAntworten: 7Letzter Beitrag: 04.11.02, 09:36





Zitieren
Login





