i am having 19 images , which are animation frames of my player
in below i have created array of texture as frog which is my player.and there are 19 images.how to animate them.
public class Texture
{
public static Texture2D mBackground;
public static Texture2D mBackgroundOne;
public static Texture2D mBackgroundTwo;
public static Texture2D grassUp;
public static Texture2D grassDown;
public static Texture2D[] frog = new Texture2D[19];
public static Texture2D[] frogdie = new Texture2D[4];
public static Vector2 position;
public static void Load()
{
mBackground = GamePage.contentManager.Load<Texture2D>("layer_11");
mBackgroundOne = GamePage.contentManager.Load<Texture2D>("layer_11");
mBackgroundTwo = GamePage.contentManager.Load<Texture2D>("layer_11");
grassUp = GamePage.contentManager.Load<Texture2D>("layer_11");
grassDown = GamePage.contentManager.Load<Texture2D>("layer_11");
frog[0] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal1");
frog[1] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal2");
frog[2] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal3");
frog[3] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal4");
frog[4] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal5");
frog[5] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal6");
frog[6] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal7");
frog[7] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal8");
frog[8] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal9");
frog[9] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal10");
frog[10] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal11");
frog[11] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal12");
frog[12] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal13");
frog[13] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal14");
frog[14] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal15");
frog[15] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal16");
frog[16] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal17");
frog[17] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal18");
frog[18] = GamePage.contentManager.Load<Texture2D>("player/maindak_normal19");
}
public static void draw(SpriteBatch sprite)
{
for (int i = 0; i <= 18; i++)
{
sprite.Draw(frog[i],position= new Vector2(100, 100), Color.White);
}
}
Keeping with your current structure, you could animate your textures in the following manner:
//timer
private const float TIME_BETWEEN_FRAME = 0.1f;
private float timer = TIME_BETWEEN_FRAME;
//frame sequence
private int currentFrame = 0;
public void Update(GameTime gametime)
{
float elapsed = (float)gametime.ElapsedGameTime.TotalSeconds;
timer -= elapsed; //subtract elapsed time from timer
if (timer <= 0) //if our timer is elapsed
{
currentFrame++; //next frame
if (currentFrame >= frog.Count)
currentFrame = 0; //If we reach last frame, reset to loop
timer = TIME_BETWEEN_FRAME; //reset timer
}
}
public void draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(frog[currentFrame], position, Color.White);
}
This will work, however, if you want to take it a step further into the right direction, you should look into SpriteSheets, which will provide you with a much easier way to manage all of your animations.
Related
I am trying to use Mouse.GetState() for my menu selection. Currently, it will only highlight if I hover over a region left and up from where the menu is. I used DrawString to display the mouses coordinates and found that the 0,0 point wasn't in the top left of my monitor or in the top left of the game window. It was somewhere about 100,100 pixels from the top left of the screen. Also, the 0,0 point moves every time I run the programme.
I looked at others people who have had the same problem but wasn't able to solve it. I tried using Mouse.WindowHandle = this.Window.Handle; in my Initialize() but it didn't nothing. I have two monitors and when I forced the game in fullscreen it would open on my second monitor so I disabled it but the problem remains.
here is a link to my code http://pastebin.com/PNaFADqp
Game1 class:
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spriteFont;
public const int WINDOW_HEIGHT = 800;
public const int WINDOW_WIDTH = 600;
public int tree;
public TitleScreen titleScreen;
public SATDemo satDemo;
public SeparatingAxisTest separatingAxisTest;
public SATWithAABB sATWithAABB;
GameState currentState;
public static Dictionary<string, Texture2D> m_textureLibrary = new Dictionary<string, Texture2D>();
public static Dictionary<string, SpriteFont> m_fontLibrary = new Dictionary<string, SpriteFont>();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = WINDOW_HEIGHT;
graphics.PreferredBackBufferWidth = WINDOW_WIDTH;
}
protected override void Initialize()
{
Mouse.WindowHandle = this.Window.Handle;
//enable the mousepointer
IsMouseVisible = true;
currentState = GameState.TitleScreen;
//sets the windows mouse handle to client bounds handle
base.Initialize();
}
public void RequestSATDemo()
{
currentState = GameState.RequestSATDemo;
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
m_textureLibrary.Add("Pixel", Content.Load<Texture2D>("White_Pixel"));
m_fontLibrary.Add("Font", Content.Load<SpriteFont>("MotorwerkOblique"));
titleScreen = new TitleScreen();
satDemo = new SATDemo();
separatingAxisTest = new SeparatingAxisTest();
sATWithAABB = new SATWithAABB();
}
public void RequestSeparatingAxisTest()
{
currentState = GameState.SeparatingAxisTest;
}
public void RequestSATWithAABB()
{
currentState = GameState.SATWithAABB;
}
protected override void Update(GameTime gameTime)
{
MouseTestState = Mouse.GetState();
switch (currentState)
{
case GameState.TitleScreen:
{
titleScreen.Update(gameTime);
break;
}
case GameState.SeparatingAxisTest:
{
separatingAxisTest.Update(gameTime);
break;
}
case GameState.SATWithAABB:
{
sATWithAABB.Update(gameTime);
break;
}
case GameState.Exit:
{
Exit();
break;
}
default:
{
titleScreen.Update(gameTime);
break;
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.DrawString(m_fontLibrary["Font"], MouseTestState.ToString(), new Vector2(0, 0), Color.White);
switch (currentState)
{
case GameState.TitleScreen:
{
titleScreen.Draw(spriteBatch, spriteFont);
break;
}
case GameState.SeparatingAxisTest:
{
separatingAxisTest.Draw(gameTime, spriteBatch);
break;
}
case GameState.SATWithAABB:
{
sATWithAABB.Draw(gameTime, spriteBatch);
break;
}
case GameState.Exit:
{
Exit();
break;
}
default:
{
titleScreen.Update(gameTime);
break;
}
}
spriteBatch.End();
base.Draw(gameTime);
}
}
TitleScreen class:
public class TitleScreen : Screen
{
List<Button> buttonList = new List<Button>();
public Menu mainMenu;
public TitleScreen()
{
mainMenu = new Menu(new Vector2(200, 100), buttonList, 0);
buttonList.Add(new PushButton("Separating Axis Test"));
buttonList.Add(new PushButton("SAT With AABB"));
buttonList.Add(new PushButton("Awesome"));
buttonList.Add(new PushButton("Awesomere"));
buttonList.Add(new PushButton("Awesomere"));
}
public override void Update(GameTime gametime)
{
mainMenu.Update(gametime);
}
public void Draw(SpriteBatch sB, SpriteFont sF)
{
mainMenu.Draw(sB, sF);
}
}
PushButton class:
public class PushButton : Button
{
string m_text;
SpriteFont m_font;
Color m_static, m_onClick, m_onHover;
Texture2D m_sprite2D, m_onClick2D;
static public int Pbuttoncount;
//click processing
bool m_clickedInside = false,
m_releasedInside = false,
m_OnClicked = false,
selected = false;
Rectangle drawRectangle;
public PushButton(string Text)
{
m_text = Text;
drawRectangle = new Rectangle((int)Menu.m_position.X, (int)Menu.m_position.Y + (15 * Pbuttoncount), 200, 15);
ButtonRegion = new Rectangle((int)Position.X, (int)Position.Y, 200, 15);
Pbuttoncount++;
}
public PushButton(Rectangle ButtonRegion, SpriteFont Font, string Text, Color Static, Color OnClick, Color OnHover)
{
m_buttonRegion = ButtonRegion;
m_font = Font;
m_text = Text;
m_static = Static;
m_onClick = OnClick;
m_onHover = OnHover;
// drawRectangle = ButtonPosition(m_buttonRegion);
}
public PushButton(Rectangle ButtonRegion, Texture2D Sprite2D, Texture2D OnClick2D)
{
m_buttonRegion = ButtonRegion;
m_sprite2D = Sprite2D;
m_onClick2D = OnClick2D;
//drawRectangle = ButtonPosition(m_buttonRegion);
}
public override void Update(GameTime gameTime)
{
MouseState currentMouse = Mouse.GetState();
selected = MouseState(drawRectangle, currentMouse);
m_clickedInside = ClickInside(currentMouse, m_lastMouseState);
ReleaseInside(currentMouse, m_lastMouseState);
if (selected && m_clickedInside && m_releasedInside)
m_OnClicked = true;
else
m_OnClicked = false;
m_lastMouseState = currentMouse;
}
public override void Draw(SpriteBatch spriteBatch, SpriteFont spriteFont, int buttonCount, Vector2 Position)
{
spriteBatch.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)Position.X + 10, (int)(Position.Y + 15 * buttonCount), 180, 15), Color.Wheat);
if (selected)
spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Orange);
else
spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Black);
}
}
Menu class:
public class Menu
{
List<Button> m_buttonList;
float m_transparency;
public int n = 0;
public Rectangle buttonRegion, m_menuRegion, m_dimensions;
static public Vector2 m_position;
int m_WINDOW_HEIGHT = Game1.WINDOW_HEIGHT;
int m_WINDOW_WIDTH = Game1.WINDOW_WIDTH;
private Game1 m_managerClass;
public Menu(Vector2 Position, List<Button> ButtonList, float Transparency)
{
m_position = Position;
m_buttonList = ButtonList;
m_transparency = Transparency;
m_managerClass = new Game1();
}
public Rectangle MenuRegion
{
get { return m_menuRegion; }
set { m_menuRegion = value; }
}
static public Vector2 Position
{
get { return m_position; }
}
public void Update(GameTime gametime)
{
for (int i = 0; i < m_buttonList.Count; i++)
{
m_buttonList[i].Update(gametime);
if (m_buttonList[0].OnClicked)
{
SeperatingAxisTest();
}
}
}
public void Draw(SpriteBatch sB, SpriteFont sF)
{
sB.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)m_position.X - 5, (int)m_position.Y - 10, (m_buttonList[0].ButtonRegion.Width + 10), (m_buttonList[0].ButtonRegion.Height * m_buttonList.Count) + 20), Color.Blue);
for (int i = 0; i < m_buttonList.Count; i++)
{
m_buttonList[i].Draw(sB, sF, i, new Vector2(Position.X, Position.Y));
}
}
private void SeperatingAxisTest()
{
m_managerClass.RequestSeparatingAxisTest();
}
}
Program class:
public static class Program
{
[STAThread]
static void Main()
{
using (var game = new Game1())
game.Run();
}
}
Let me know if you need anything else. I'm still learning and will sell my soul to you for an answer.
Your Menu class is creating a new instance of Game1. This is, most likely, not what you want, since Game1 is instantiated in the entry point for you app. The Game1 instance has an instance of TitleScreen, which in turn has an instance of the Menu class, so a Menu should have no business creating its own game.
When this (other) instance is created, it invokes platform-specific (Windows) methods, creates an additional window handle (which is never shown) and configures the Mouse.WindowHandle.
And btw, setting WindowHandle manually does absolutely nothing in Monogame, so all these sources mentioning that are talking about XNA.
So, there are several remarks:
You should probably have a "screen manager" class which contains the current screen. It is strange to have a field of type TitleScreen in your game class, it should at least be of the base type (Screen), so that the game class draws and updates each screen transparently.
If you need a reference to the game class anywhere, don't instantiate a new one, but rather pass it along through the constructor.
m_managerClass is a bad name for a field which is actually a Game. Also google for C# naming conventions. Perhaps you even might want to download an existing monogame game template, e.g. check some of the samples online; the NetRumble sample seems to implement a screen manager.
Remove the Mouse.WindowHandle line, it should be set to your one-and-only game window by default.
tl;dr add the Game1 as a parameter wherever you might need it (but only where you need it).
abstract class Screen
{
private readonly Game1 _game;
public Game1 Game
{ get { return _game; } }
public Screen(Game1 game)
{
_game = game;
}
}
class TitleScreen : Screen
{
public TitleScreen(Game1 game)
: base(game)
{ ... }
}
class Menu
{
private readonly Screen _screen;
public Menu(Screen parentScreen, Vector2 pos, List<Button> list, float alpha)
{
_screen = parentScreen;
...
// if you need the game instance, just use _screen.Game
}
}
I need to create an image slideshow in my app (i.e. the image should be changed at a regular interval of time with a fade in / fade out effect). I have tried some code, but it throws illegal exception.
Is there any option to change images in picture scroll field programatically? i.e. from a thread or something?
public class SlideTransition extends MainScreen {
final Bitmap image000 = Bitmap.getBitmapResource("img1.jpg");
final Bitmap image001 = Bitmap.getBitmapResource("img2.jpg");
final Bitmap image002 = Bitmap.getBitmapResource("img3.jpg");
final BitmapField animationField = new BitmapField(image000);
int counter = 0;
Timer animationTimer = new Timer();
TimerTask animationTask;
public SlideTransition() {
animationTask = new TimerTask() {
public void run() {
if (counter == 0) {
animationField.setBitmap(image000);
}
if (counter == 1) {
animationField.setBitmap(image001);
}
if (counter == 2) {
animationField.setBitmap(image002);
counter = -1;
}
counter++;
}
};
animationTimer.scheduleAtFixedRate(animationTask, 0, 100);
add(animationField);
}
}
The code posted will throw an IllegalStateException because it is attempting to modify a UI element directly from a background (timer) thread:
animationField.setBitmap(image000);
You need to use UiApplication.getUiApplication().invokeLater(), or something similar, to modify the UI from a background thread.
Also, you can have your timer continuously adjust the bitmap field's alpha value (opacity) to produce a fade effect.
Here's an example, starting with the code you provided:
public class SlideTransition extends MainScreen {
private final Bitmap image000 = Bitmap.getBitmapResource("img1.jpg");
private final Bitmap image001 = Bitmap.getBitmapResource("img2.jpg");
private final Bitmap image002 = Bitmap.getBitmapResource("img3.jpg");
private AlphaBitmapField animationField = new AlphaBitmapField(image000);
private Timer animationTimer = new Timer();
private TimerTask animationTask;
private final int animationPeriodMsec = 40; // 25 Hz animation timer
public SlideTransition() {
animationTask = new AnimationTask();
add(animationField);
animationTimer.scheduleAtFixedRate(animationTask, 0, animationPeriodMsec);
}
// I separated your anonymous timer task into its own class for readability
private class AnimationTask extends TimerTask {
private final int fadeDurationMsec = 500;
private final int displayDurationMsec = 1500;
private final int fadeInEndCount = fadeDurationMsec / animationPeriodMsec;
private final int fadeOutStartCount = (fadeDurationMsec + displayDurationMsec) / animationPeriodMsec;
private final int endCount = (2 * fadeDurationMsec + displayDurationMsec) / animationPeriodMsec;
private int imgCounter = 0;
private int cycleCounter = 0;
public void run() {
if (cycleCounter >= endCount) {
cycleCounter = 0;
}
Bitmap newImage = null;
if (cycleCounter == 0) {
// time to switch the images
if (imgCounter == 0) {
newImage = image000;
} else if (imgCounter == 1) {
newImage = image001;
} else if (imgCounter == 2) {
newImage = image002;
imgCounter = -1;
}
imgCounter++;
}
// assign final variables to use inside a UI thread Runnable
final Bitmap currentImage = newImage;
final int i = cycleCounter;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
if (i == 0) {
// switch images, and start with the image invisible (alpha = 0)
animationField.setAlpha(0);
animationField.setBitmap(currentImage);
} else if (i <= fadeInEndCount) {
// fade in by changing alpha
animationField.setAlpha(i * 255 / fadeInEndCount);
} else if (i >= fadeOutStartCount) {
// fade out by changing alpha
animationField.setAlpha(255 + (fadeOutStartCount - i) * 255 / (endCount - fadeOutStartCount));
}
}
});
cycleCounter++;
}
}
// this class extends BitmapField to allow alpha adjustment, and automatic repainting
private class AlphaBitmapField extends BitmapField {
private int _alpha;
public AlphaBitmapField(Bitmap img) {
super(img);
}
public void setAlpha(int alpha) {
if (alpha != _alpha) {
_alpha = alpha;
// force a repaint
invalidate();
}
}
protected void paint(Graphics graphics) {
graphics.setGlobalAlpha(_alpha);
super.paint(graphics);
}
}
}
I changed the time values from your code, but you can modify them to whatever you like. I had the animation timer run at 25 cycles per second. I find that this is a reasonable value for smartphone animations. It's fast enough to look fairly smooth, but is only about twice the rate that the human eye can process information like this ... any faster is probably wasteful.
I defined constants that you can use to control the length of time that the fade in and fade out takes (fadeDurationMsec) and the time that each image is displayed between fade in and fade out (displayDurationMsec). All values are in milliseconds.
Helpful References
BlackBerry AnimatedGIFField sample code.
BlackBerry forums thread about fade in / fade out
I dun know why each time I call Update_Animation(Point sheetSize, TimeSpan frameInterval, GameTime gameTime) function, the sprite animation speed becomes more faster. Does it causes by gameTime? How to fix it? Thanks.
class Character
{
#region Field
// Character file
System.Xml.Linq.XDocument doc;
// The texture with animation frames
Texture2D animationTexture_Stand;
Texture2D animationTexture_Run;
Texture2D animationTexture_Hit;
// The size of single frame inside the animationTexture
public Point frameSize_Stand;
public Point frameSize_Run;
public Point frameSize_Hit;
// The size and structure of whole frames sheet in animationTexture. The animationTexture could
// hold animaton sequence organized in multiple rows and multiple columns.
Point sheetSize_Stand;
Point sheetSize_Run;
Point sheetSize_Hit;
// Amount of time between frames
TimeSpan frameInterval_Stand;
TimeSpan frameInterval_Run;
TimeSpan frameInterval_Hit;
#endregion
#region Initialization
/// <summary>
/// Constructor of a character class
/// </summary>
/// <param name="characterName">the name of the xml file of the character without .xml</param>
/// <param name="content">ContentManager instance</param>
public Character(String characterName, ContentManager content)
{
doc = System.Xml.Linq.XDocument.Load("Content/" + "Player/" + characterName + ".xml");
// Get the first sprite info from the XML definition
var stand = doc.Root.Element("stand");
var run = doc.Root.Element("run");
var hit = doc.Root.Element("hit");
animationTexture_Stand = content.Load<Texture2D>(stand.Attribute("SheetName").Value);
animationTexture_Run = content.Load<Texture2D>(run.Attribute("SheetName").Value);
animationTexture_Hit = content.Load<Texture2D>(hit.Attribute("SheetName").Value);
frameSize_Stand = new Point();
frameSize_Stand.X = int.Parse(stand.Attribute("FrameWidth").Value, NumberStyles.Integer);
frameSize_Stand.Y = int.Parse(stand.Attribute("FrameHeight").Value, NumberStyles.Integer);
frameSize_Run = new Point();
frameSize_Run.X = int.Parse(run.Attribute("FrameWidth").Value, NumberStyles.Integer);
frameSize_Run.Y = int.Parse(run.Attribute("FrameHeight").Value, NumberStyles.Integer);
frameSize_Hit = new Point();
frameSize_Hit.X = int.Parse(hit.Attribute("FrameWidth").Value, NumberStyles.Integer);
frameSize_Hit.Y = int.Parse(hit.Attribute("FrameHeight").Value, NumberStyles.Integer);
sheetSize_Stand = new Point();
sheetSize_Stand.X = int.Parse(stand.Attribute("SheetColumns").Value, NumberStyles.Integer);
sheetSize_Stand.Y = int.Parse(stand.Attribute("SheetRows").Value, NumberStyles.Integer);
sheetSize_Run = new Point();
sheetSize_Run.X = int.Parse(run.Attribute("SheetColumns").Value, NumberStyles.Integer);
sheetSize_Run.Y = int.Parse(run.Attribute("SheetRows").Value, NumberStyles.Integer);
sheetSize_Hit = new Point();
sheetSize_Hit.X = int.Parse(hit.Attribute("SheetColumns").Value, NumberStyles.Integer);
sheetSize_Hit.Y = int.Parse(hit.Attribute("SheetRows").Value, NumberStyles.Integer);
frameInterval_Stand = TimeSpan.FromSeconds(1.0f / int.Parse(stand.Attribute("Speed").Value, NumberStyles.Integer));
frameInterval_Run = TimeSpan.FromSeconds(1.0f / int.Parse(run.Attribute("Speed").Value, NumberStyles.Integer));
frameInterval_Hit = TimeSpan.FromSeconds(1.0f / int.Parse(hit.Attribute("Speed").Value, NumberStyles.Integer));
}
#endregion
#region Update Animation
TimeSpan nextFrame;
Point currentFrame;
public void Update_Animation(Point sheetSize, TimeSpan frameInterval, GameTime gameTime)
{
if (nextFrame >= frameInterval)
{
currentFrame.X++;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
currentFrame.Y++;
}
if (currentFrame.Y >= sheetSize.Y)
currentFrame.Y = 0;
nextFrame = TimeSpan.Zero;
}
else
{
nextFrame += gameTime.ElapsedGameTime;
}
}
#endregion
#region Update Control
KeyboardState mPreviousKeyboardState;
String action;
SpriteEffects effect = SpriteEffects.FlipHorizontally;
Vector2 feetPosition = new Vector2(0, 450);
Vector2 mSpeed = Vector2.Zero;
Vector2 mDirection = Vector2.Zero;
Vector2 mStartingPosition = Vector2.Zero;
int CHARACTER_SPEED = 50;
int MOVE_LEFT = -5;
int MOVE_RIGHT = 5;
int MOVE_UP = -5;
int MOVE_DOWN = 5;
enum State
{
Walking,
Jumping,
Hitting,
}
State mCurrentState = State.Walking;
public void UpdateControl(GameTime gameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
feetPosition += mDirection * mSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
UpdateMovement(aCurrentKeyboardState, gameTime);
UpdateJump(aCurrentKeyboardState, gameTime);
mPreviousKeyboardState = aCurrentKeyboardState;
}
private void UpdateMovement(KeyboardState aCurrentKeyboardState, GameTime gameTime)
{
if (mCurrentState == State.Walking)
{
action = "stand";
Update_Animation(sheetSize_Stand, frameInterval_Stand, gameTime);
mSpeed = Vector2.Zero;
mDirection = Vector2.Zero;
if (aCurrentKeyboardState.IsKeyDown(Keys.Left) && !aCurrentKeyboardState.IsKeyDown(Keys.Right))
{
action = "run";
effect = SpriteEffects.None;
mSpeed.X = CHARACTER_SPEED;
mDirection.X = MOVE_LEFT;
Update_Animation(sheetSize_Run, frameInterval_Run, gameTime);
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Right) && !aCurrentKeyboardState.IsKeyDown(Keys.Left))
{
action = "run";
effect = SpriteEffects.FlipHorizontally;
mSpeed.X = CHARACTER_SPEED;
mDirection.X = MOVE_RIGHT;
Update_Animation(sheetSize_Run, frameInterval_Run, gameTime);
}
if (aCurrentKeyboardState.IsKeyDown(Keys.Z) && mPreviousKeyboardState.IsKeyUp(Keys.Z))
{
mCurrentState = State.Hitting;
}
}
if (mCurrentState == State.Hitting)
{
action = "hit";
Update_Animation(sheetSize_Hit, frameInterval_Hit, gameTime);
mCurrentState = State.Walking;
}
}
private void UpdateJump(KeyboardState aCurrentKeyboardState, GameTime gameTime)
{
if (mCurrentState == State.Walking)
{
if (aCurrentKeyboardState.IsKeyDown(Keys.Up) && mPreviousKeyboardState.IsKeyUp(Keys.Up))
Jump();
}
if (mCurrentState == State.Jumping)
{
if (mStartingPosition.Y - feetPosition.Y > 150)
mDirection.Y = MOVE_DOWN;
if (feetPosition.Y > mStartingPosition.Y)
{
feetPosition.Y = mStartingPosition.Y;
mCurrentState = State.Walking;
mDirection = Vector2.Zero;
}
}
}
private void Jump()
{
if (mCurrentState != State.Jumping)
{
mCurrentState = State.Jumping;
mStartingPosition = feetPosition;
mDirection.Y = MOVE_UP;
mSpeed = new Vector2(CHARACTER_SPEED, CHARACTER_SPEED);
}
}
#endregion
#region Draw Animation
Texture2D animationTexture;
Point frameSize;
/// <summary>
/// Rendering of the animation
/// </summary>
/// <param name="spriteBatch">SpriteBatch in which current frame will be rendered</param>
/// <param name="position">The position of the current frame</param>
/// <param name="scale">Scale factor to apply on the current frame</param>
/// <param name="spriteEffect">SpriteEffect to apply on the current frame</param>
public void Draw_Animation(SpriteBatch spriteBatch)
{
if (action == "stand")
{
Assign_Sprite(animationTexture_Stand, frameSize_Stand);
Draw_Action(spriteBatch, feetPosition, 1.0f, effect);
}
else if (action == "run")
{
Assign_Sprite(animationTexture_Run, frameSize_Run);
Draw_Action(spriteBatch, feetPosition, 1.0f, effect);
}
else if (action == "hit")
{
Assign_Sprite(animationTexture_Hit, frameSize_Hit);
Draw_Action(spriteBatch, feetPosition, 1.0f, effect);
}
}
private void Assign_Sprite(Texture2D assignAnimationTexture, Point assignFrameSize)
{
animationTexture = assignAnimationTexture;
//currentFrame = AssignCurrentFrame;
frameSize = assignFrameSize;
}
private void Draw_Action(SpriteBatch spriteBatch, Vector2 position, float scale, SpriteEffects spriteEffect)
{
spriteBatch.Draw(animationTexture, position - new Vector2(0, frameSize.Y), new Rectangle(
frameSize.X * currentFrame.X,
frameSize.Y * currentFrame.Y,
frameSize.X,
frameSize.Y),
Color.White, 0f, Vector2.Zero, scale, spriteEffect, 0);
}
#endregion
}
I'm not sure if that is the problem, but this code concerns me:
if (nextFrame >= frameInterval)
{
//Blah blah
nextFrame = TimeSpan.Zero;
}
If gameTime.ElapsedGameTime is not regular (if your game is having performance problems), this method will not be correctly timed. Instead, you should try:
while (nextFrame >= frameInterval)
{
//Blah blah
nextFrame -= frameInterval;
}
Thus there will be some time "left over" in nextFrame, so the next animation will come at the right time.
However, since your question isn't very clear, I'm not sure if this will actually fix your problem.
I'm currently doing an assignment, on which one of the requirements is for a random object to appear on screen and move across. Being new to XNA, i do not know where to even begin implementing such behaviours to the game, thus would really appreciate if someone could give me a nudge towards the right direction.
I'm only really accustomed to invoking something when a key is pressed, however with something completely random, this can't be done. as far as i am aware of.
Thank you.
You need to create and set up a sprite for the UFO first. In your protected override void Update(GameTime gameTime) code you simply need to get the current time and compare it to the rules in which you wish to apply. Then update if you wish to draw and "move" the sprite. Here is an example:
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
public class Game : Microsoft.Xna.Framework.Game {
#region Game Settings
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
GraphicsDevice device;
int screenWidth = 800;
int screenHeight = 600;
bool fullscreen = false;
string title = "MyGame";
string origionaltitle;
float frames = 0;
float framesPerSecond = 0;
int startTime;
int currentTime;
int nextTime;
#endregion
struct sprite {
public string TextureName;
public Texture2D Texture;
public Vector2 Position;
public Vector2 Speed;
public Color[] TextureData;
};
bool DrawUFO = false;
sprite ufo = new sprite();
public Game() {
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void LoadContent() {
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
device = graphics.GraphicsDevice;
// TODO: use this.Content to load your game content here
ufo.TextureName = "ufo";
ufo.Texture = Content.Load<Texture2D>(ball.TextureName);
ufo.TextureData = new Color[ufo.Texture.Width *ufo.Texture.Height];
ufo.Texture.GetData(ball.TextureData);
}
protected override void Initialize() {
// TODO: Add your initialization logic here
ufo.Position = new Vector2(10f, 10.0f);
ufo.Speed = new Vector2(0.0f, 10.0f);
//
// Set up game window
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.IsFullScreen = fullscreen;
graphics.ApplyChanges();
origionaltitle = title;
Window.Title = title;
//
// Set the initial time
startTime = DateTime.Now.Second;
//
// Set "random"/next time for ufo to be rendered
nextTime = startTime + rand.Next(2);
//
base.Initialize();
}
protected override void Update(GameTime gameTime) {
//
// Set the current time
currentTime = DateTime.Now.Second;
//
// if not drawing ufo then
if(!DrawURO) {
//
// check current time and compare it with the next time
if( currentTime == nextTime ) {
DrawURO = true;
}
} else {
//
// Update UFO position (aka move it)
ufo.Posistion += ball.Speed *(float)gameTime.ElapsedGameTime.TotalSeconds;
//
// if ufo goes of the screen then
if(ufo.Position.Y > screenHeight) {
//
// Reset ufo
DrawURO = false;
ufo.Position.X = 10.0f;
ufo.Position.Y = 10.0f;
//
// set next time to render
nextTime = currentTime + rand.Next(2);
}
}
}
protected override void Draw(GameTime gameTime) {
graphics.GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
if(DrawUFO == true) {
spriteBatch.Draw(ufo.Texture, ufo.Position, Color.White);
}
spriteBatch.End();
//
base.Draw(gameTime);
}
}
I copied this from some code i did at college a few years a ago, so apologies for any bugs.
I've been reading about Vala over the past couple of days and decided to dive into it and make some Clutter widgets along the way. I'm currently trying to draw a private actor from my custom actor subclass. Here is a simplified version of what I've got so far.
public class MyContainer : Clutter.Actor, Clutter.Container {
private Clutter.Group group;
public MyContainer() {
group = new Clutter.Group();
group.set_parent(this);
}
public void add_actor(Clutter.Actor actor) {
group.add_actor(actor);
actor.show();
set_size(group.width, group.height);
actor_added(actor);
queue_redraw();
}
public void foreach(Clutter.Callback callback) {
group.foreach(callback);
queue_redraw();
}
public override void get_preferred_height(
float for_width,
out float min_height_p,
out float natural_height_p) {
group.get_preferred_height(
for_width,
out min_height_p,
out natural_height_p);
}
public override void get_preferred_width(
float for_height,
out float min_width_p,
out float natural_width_p) {
group.get_preferred_width(
for_height,
out min_width_p,
out natural_width_p);
}
public override void paint() {
group.paint();
}
public void remove_actor(Clutter.Actor actor) {
group.remove_actor(actor);
set_size(group.width, group.height);
actor_removed(actor);
queue_redraw();
}
public void sort_depth_order() {
group.sort_depth_order();
queue_redraw();
}
}
int main(string [] args) {
// Start clutter.
var result = Clutter.init(ref args);
if (result != Clutter.InitError.SUCCESS) {
stderr.printf("Error: %s\n", result.to_string());
return 1;
}
var stage = Clutter.Stage.get_default();
// Build a MyCollection object.
var myc = new MyContainer();
myc.x = 100;
myc.y = 100;
var r1 = new Clutter.Rectangle();
r1.width = 50;
r1.height = 50;
r1.color = Clutter.Color.from_string("rgb(255, 0, 0)");
var t1 = new Clutter.Text();
t1.text = "The red square.";
t1.y = r1.height;
// Build a Group object similar to the previous.
var group = new Clutter.Group();
group.x = 300;
group.y = 100;
var r2 = new Clutter.Rectangle();
r2.width = 50;
r2.height = 50;
r2.color = Clutter.Color.from_string("rgb(255, 0, 0)");
var t2 = new Clutter.Text();
t2.text = "The red square.";
t2.y = r2.height;
// Display.
myc.add_actor(r1);
myc.add_actor(t1);
group.add_actor(r2);
group.add_actor(t2);
stage.add_actor(myc);
stage.add_actor(group);
stage.show_all();
Clutter.main();
return 0;
}
The example paints the group added directly to the stage, but not the group wrapped by the custom collection that is added to the stage. How can I get this to work and what is wrong with the above?
I've been working on ubuntu 11.10 with valac --pkg clutter-1.0 above_code_example.vala.
This answer is from buz on gnome.irc's #clutter room.
The problem is a missing override for the allocate function.