How to avoid mixing different sprite animation speed? - xna

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.

Related

How to implement ViewPagers with Dot Sliders in Xamarin.Android?

I am learning Xamarin.Android recently, I was trying to implement pageviewers with dot sliders for my practice from the last few days but failed to implement it, I had refereed many solutions from popular hubs like stackoverflow and github but failed to do so.
Can any one please explain me how to implement the viewpagers with dot sliders in xamarin.android.
I am attaching a photo to this for your reference, which would give you a clear view on my requirement.
as you can see he is sliding the pages using the dot sliders i was trying to do so.
Please explain me how to do it in Xamarin.Android (Native)
First define your own custom circle page-indicator let it be CirclePageIndicator.cs add this to your project (not activity file)
using Android.Content;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Graphics;
using Android.Support.V4.View;
using Android.Util;
using Java.Lang;
using Java.Interop;
namespace MyApplication.Droid.Library
{
public class CirclePageIndicator : View,PageIndicator
{
const int HORIZONTAL = 0;
const int VERTICAL = 1;
private float mRadius;
private Paint mPaintPageFill;
private Paint mPaintStroke;
private Paint mPaintFill;
private ViewPager mViewPager;
private ViewPager.IOnPageChangeListener mListener;
private int mCurrentPage;
private int mSnapPage;
private int mCurrentOffset;
private int mScrollState;
private int mPageSize;
private int mOrientation;
private bool mCentered;
private bool mSnap;
private const int INVALID_POINTER = -1;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private bool mIsDragging;
public CirclePageIndicator(Context context) : this(context, null)
{
}
public CirclePageIndicator(Context context, IAttributeSet attrs) : this(context, attrs, Resource.Attribute.vpiCirclePageIndicatorStyle)
{
}
public CirclePageIndicator(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
//Load defaults from resources
var res = Resources;
int defaultPageColor = res.GetColor(Resource.Color.default_circle_indicator_page_color);
int defaultFillColor = res.GetColor(Resource.Color.default_circle_indicator_fill_color);
int defaultOrientation = res.GetInteger(Resource.Integer.default_circle_indicator_orientation);
int defaultStrokeColor = res.GetColor(Resource.Color.default_circle_indicator_stroke_color);
float defaultStrokeWidth = res.GetDimension(Resource.Dimension.default_circle_indicator_stroke_width);
float defaultRadius = res.GetDimension(Resource.Dimension.default_circle_indicator_radius);
bool defaultCentered = res.GetBoolean(Resource.Boolean.default_circle_indicator_centered);
bool defaultSnap = res.GetBoolean(Resource.Boolean.default_circle_indicator_snap);
//Retrieve styles attributes
var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.CirclePageIndicator, defStyle, Resource.Style.Widget_CirclePageIndicator);
mCentered = a.GetBoolean(Resource.Styleable.CirclePageIndicator_centered, defaultCentered);
mOrientation = a.GetInt(Resource.Styleable.CirclePageIndicator_orientation, defaultOrientation);
mPaintPageFill = new Paint(PaintFlags.AntiAlias);
mPaintPageFill.SetStyle(Paint.Style.Fill);
mPaintPageFill.Color = a.GetColor(Resource.Styleable.CirclePageIndicator_pageColor, defaultPageColor);
mPaintStroke = new Paint(PaintFlags.AntiAlias);
mPaintStroke.SetStyle(Paint.Style.Stroke);
mPaintStroke.Color = a.GetColor(Resource.Styleable.CirclePageIndicator_strokeColor, defaultStrokeColor);
mPaintStroke.StrokeWidth = a.GetDimension(Resource.Styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth);
mPaintFill = new Paint(PaintFlags.AntiAlias);
mPaintFill.SetStyle(Paint.Style.Fill);
mPaintFill.Color = a.GetColor(Resource.Styleable.CirclePageIndicator_fillColor, defaultFillColor);
mRadius = a.GetDimension(Resource.Styleable.CirclePageIndicator_radius, defaultRadius);
mSnap = a.GetBoolean(Resource.Styleable.CirclePageIndicator_snap, defaultSnap);
a.Recycle();
var configuration = ViewConfiguration.Get(context);
mTouchSlop = ViewConfigurationCompat.GetScaledPagingTouchSlop(configuration);
}
public void SetCentered(bool centered)
{
mCentered = centered;
Invalidate();
}
public bool IsCentered()
{
return mCentered;
}
public void SetPageColor(Color pageColor)
{
mPaintPageFill.Color = pageColor;
Invalidate();
}
public int GetPageColor()
{
return mPaintPageFill.Color;
}
public void SetFillColor(Color fillColor)
{
mPaintFill.Color = fillColor;
Invalidate();
}
public int GetFillColor()
{
return mPaintFill.Color;
}
public void setOrientation(int orientation)
{
switch (orientation)
{
case HORIZONTAL:
case VERTICAL:
mOrientation = orientation;
UpdatePageSize();
RequestLayout();
break;
default:
throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL.");
}
}
public int GetOrientation()
{
return mOrientation;
}
public void SetStrokeColor(Color strokeColor)
{
mPaintStroke.Color = strokeColor;
Invalidate();
}
public int GetStrokeColor()
{
return mPaintStroke.Color;
}
public void SetStrokeWidth(float strokeWidth)
{
mPaintStroke.StrokeWidth = strokeWidth;
Invalidate();
}
public float GetStrokeWidth()
{
return mPaintStroke.StrokeWidth;
}
public void SetRadius(float radius)
{
mRadius = radius;
Invalidate();
}
public float GetRadius()
{
return mRadius;
}
public void SetSnap(bool snap)
{
mSnap = snap;
Invalidate();
}
public bool IsSnap()
{
return mSnap;
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
if (mViewPager == null)
{
return;
}
int count = mViewPager.Adapter.Count;
if (count == 0)
{
return;
}
if (mCurrentPage >= count)
{
SetCurrentItem(count - 1);
return;
}
int longSize;
int longPaddingBefore;
int longPaddingAfter;
int shortPaddingBefore;
if (mOrientation == HORIZONTAL)
{
longSize = Width;
longPaddingBefore = PaddingLeft;
longPaddingAfter = PaddingRight;
shortPaddingBefore = PaddingTop;
}
else
{
longSize = Height;
longPaddingBefore = PaddingTop;
longPaddingAfter = PaddingBottom;
shortPaddingBefore = PaddingLeft;
}
float threeRadius = mRadius * 3;
float shortOffset = shortPaddingBefore + mRadius;
float longOffset = longPaddingBefore + mRadius;
if (mCentered)
{
longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0f) - ((count * threeRadius) / 2.0f);
}
float dX;
float dY;
float pageFillRadius = mRadius;
if (mPaintStroke.StrokeWidth > 0)
{
pageFillRadius -= mPaintStroke.StrokeWidth / 2.0f;
}
//Draw stroked circles
for (int iLoop = 0; iLoop < count; iLoop++)
{
float drawLong = longOffset + (iLoop * threeRadius);
if (mOrientation == HORIZONTAL)
{
dX = drawLong;
dY = shortOffset;
}
else
{
dX = shortOffset;
dY = drawLong;
}
// Only paint fill if not completely transparent
if (mPaintPageFill.Alpha > 0)
{
canvas.DrawCircle(dX, dY, pageFillRadius, mPaintPageFill);
}
// Only paint stroke if a stroke width was non-zero
if (pageFillRadius != mRadius)
{
canvas.DrawCircle(dX, dY, mRadius, mPaintStroke);
}
}
//Draw the filled circle according to the current scroll
float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
if (!mSnap && (mPageSize != 0))
{
cx += (mCurrentOffset * 1.0f / mPageSize) * threeRadius;
}
if (mOrientation == HORIZONTAL)
{
dX = longOffset + cx;
dY = shortOffset;
}
else
{
dX = shortOffset;
dY = longOffset + cx;
}
canvas.DrawCircle(dX, dY, mRadius, mPaintFill);
}
public override bool OnTouchEvent(MotionEvent ev)
{
if (base.OnTouchEvent(ev))
{
return true;
}
if ((mViewPager == null) || (mViewPager.Adapter.Count == 0))
{
return false;
}
var action = ev.Action;
switch ((int)action & MotionEventCompat.ActionMask)
{
case (int)MotionEventActions.Down:
mActivePointerId = MotionEventCompat.GetPointerId(ev, 0);
mLastMotionX = ev.GetX();
break;
case (int)MotionEventActions.Move:
{
int activePointerIndex = MotionEventCompat.FindPointerIndex(ev, mActivePointerId);
float x = MotionEventCompat.GetX(ev, activePointerIndex);
float deltaX = x - mLastMotionX;
if (!mIsDragging)
{
if (Java.Lang.Math.Abs(deltaX) > mTouchSlop)
{
mIsDragging = true;
}
}
if (mIsDragging)
{
if (!mViewPager.IsFakeDragging)
{
mViewPager.BeginFakeDrag();
}
mLastMotionX = x;
mViewPager.FakeDragBy(deltaX);
}
break;
}
case (int)MotionEventActions.Cancel:
case (int)MotionEventActions.Up:
if (!mIsDragging)
{
int count = mViewPager.Adapter.Count;
int width = Width;
float halfWidth = width / 2f;
float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.GetX() < halfWidth - sixthWidth))
{
mViewPager.CurrentItem = mCurrentPage - 1;
return true;
}
else if ((mCurrentPage < count - 1) && (ev.GetX() > halfWidth + sixthWidth))
{
mViewPager.CurrentItem = mCurrentPage + 1;
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.IsFakeDragging)
mViewPager.EndFakeDrag();
break;
case MotionEventCompat.ActionPointerDown:
{
int index = MotionEventCompat.GetActionIndex(ev);
float x = MotionEventCompat.GetX(ev, index);
mLastMotionX = x;
mActivePointerId = MotionEventCompat.GetPointerId(ev, index);
break;
}
case MotionEventCompat.ActionPointerUp:
int pointerIndex = MotionEventCompat.GetActionIndex(ev);
int pointerId = MotionEventCompat.GetPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId)
{
int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.GetPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.GetX(ev, MotionEventCompat.FindPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
public void SetViewPager(ViewPager view)
{
if (view.Adapter == null)
{
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.SetOnPageChangeListener(this);
UpdatePageSize();
Invalidate();
}
private void UpdatePageSize()
{
if (mViewPager != null)
{
mPageSize = (mOrientation == HORIZONTAL) ? mViewPager.Width : mViewPager.Height;
}
}
public void SetViewPager(ViewPager view, int initialPosition)
{
SetViewPager(view);
SetCurrentItem(initialPosition);
}
public void SetCurrentItem(int item)
{
if (mViewPager == null)
{
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.CurrentItem = item;
mCurrentPage = item;
Invalidate();
}
public void NotifyDataSetChanged()
{
Invalidate();
}
public void OnPageScrollStateChanged(int state)
{
mScrollState = state;
if (mListener != null)
{
mListener.OnPageScrollStateChanged(state);
}
}
public void OnPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
mCurrentPage = position;
mCurrentOffset = positionOffsetPixels;
UpdatePageSize();
Invalidate();
if (mListener != null)
{
mListener.OnPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
public void OnPageSelected(int position)
{
if (mSnap || mScrollState == ViewPager.ScrollStateIdle)
{
mCurrentPage = position;
mSnapPage = position;
Invalidate();
}
if (mListener != null)
{
mListener.OnPageSelected(position);
}
}
public void SetOnPageChangeListener(ViewPager.IOnPageChangeListener listener)
{
mListener = listener;
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (mOrientation == HORIZONTAL)
{
SetMeasuredDimension(MeasureLong(widthMeasureSpec), MeasureShort(heightMeasureSpec));
}
else
{
SetMeasuredDimension(MeasureShort(widthMeasureSpec), MeasureLong(heightMeasureSpec));
}
}
/**
* Determines the width of this view
*
* #param measureSpec
* A measureSpec packed into an int
* #return The width of the view, honoring constraints from measureSpec
*/
private int MeasureLong(int measureSpec)
{
int result = 0;
var specMode = MeasureSpec.GetMode(measureSpec);
var specSize = MeasureSpec.GetSize(measureSpec);
if ((specMode == MeasureSpecMode.Exactly) || (mViewPager == null))
{
//We were told how big to be
result = specSize;
}
else
{
//Calculate the width according the views count
int count = mViewPager.Adapter.Count;
result = (int)(PaddingLeft + PaddingRight
+ (count * 2 * mRadius) + (count - 1) * mRadius + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpecMode.AtMost)
{
result = Java.Lang.Math.Min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
*
* #param measureSpec
* A measureSpec packed into an int
* #return The height of the view, honoring constraints from measureSpec
*/
private int MeasureShort(int measureSpec)
{
int result = 0;
var specMode = MeasureSpec.GetMode(measureSpec);
var specSize = MeasureSpec.GetSize(measureSpec);
if (specMode == MeasureSpecMode.Exactly)
{
//We were told how big to be
result = specSize;
}
else
{
//Measure the height
result = (int)(2 * mRadius + PaddingTop + PaddingBottom + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpecMode.AtMost)
{
result = Java.Lang.Math.Min(result, specSize);
}
}
return result;
}
protected override void OnRestoreInstanceState(IParcelable state)
{
try
{
SavedState savedState = (SavedState)state;
base.OnRestoreInstanceState(savedState.SuperState);
mCurrentPage = savedState.CurrentPage;
mSnapPage = savedState.CurrentPage;
}
catch
{
base.OnRestoreInstanceState(state);
// Ignore, this needs to support IParcelable...
}
RequestLayout();
}
protected override IParcelable OnSaveInstanceState()
{
var superState = base.OnSaveInstanceState();
var savedState = new SavedState(superState);
savedState.CurrentPage = mCurrentPage;
return savedState;
}
public class SavedState : BaseSavedState
{
public int CurrentPage { get; set; }
public SavedState(IParcelable superState) : base(superState)
{
}
private SavedState(Parcel parcel) : base(parcel)
{
CurrentPage = parcel.ReadInt();
}
public override void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
{
base.WriteToParcel(dest, flags);
dest.WriteInt(CurrentPage);
}
[ExportField("CREATOR")]
static SavedStateCreator InitializeCreator()
{
return new SavedStateCreator();
}
class SavedStateCreator : Java.Lang.Object, IParcelableCreator
{
public Java.Lang.Object CreateFromParcel(Parcel source)
{
return new SavedState(source);
}
public Java.Lang.Object[] NewArray(int size)
{
return new SavedState[size];
}
}
}
}
}
Now add PageIndicator.cs file to your project (not activity file)
using Android.Support.V4.View;
namespace MyApplication.Droid.Library
{
public interface PageIndicator : ViewPager.IOnPageChangeListener
{
/**
* Bind the indicator to a ViewPager.
*
* #param view
*/
void SetViewPager(ViewPager view);
/**
* Bind the indicator to a ViewPager.
*
* #param view
* #param initialPosition
*/
void SetViewPager(ViewPager view, int initialPosition);
/**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* #param item
*/
void SetCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* #param listener
*/
void SetOnPageChangeListener(ViewPager.IOnPageChangeListener listener);
/**
* Notify the indicator that the fragment list has changed.
*/
void NotifyDataSetChanged();
}
}
Now add the following files to your values file:
vpi__styles.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="Widget"></style>
<style name="Widget.CirclePageIndicator" parent="Widget">
<item name="centered">#bool/default_circle_indicator_centered</item>
<item name="fillColor">#color/default_circle_indicator_fill_color</item>
<item name="pageColor">#color/default_circle_indicator_page_color</item>
<item name="orientation">#integer/default_circle_indicator_orientation</item>
<item name="radius">#dimen/default_circle_indicator_radius</item>
<item name="snap">#bool/default_circle_indicator_snap</item>
<item name="strokeColor">#color/default_circle_indicator_stroke_color</item>
<item name="strokeWidth">#dimen/default_circle_indicator_stroke_width</item>
</style>
</resources>
vpi__defaults.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<bool name="default_circle_indicator_centered">true</bool>
<color name="default_circle_indicator_fill_color">#FFFFFFFF</color>
<color name="default_circle_indicator_page_color">#00000000</color>
<integer name="default_circle_indicator_orientation">0</integer>
<dimen name="default_circle_indicator_radius">3dp</dimen>
<bool name="default_circle_indicator_snap">false</bool>
<color name="default_circle_indicator_stroke_color">#FFDDDDDD</color>
<dimen name="default_circle_indicator_stroke_width">1dp</dimen>
</resources>
vpi__colors.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<color name="vpi__background_holo_dark">#ff000000</color>
<color name="vpi__background_holo_light">#fff3f3f3</color>
<color name="vpi__bright_foreground_disabled_holo_dark">#ff4c4c4c</color>
<color name="vpi__bright_foreground_disabled_holo_light">#ffb2b2b2</color>
</resources>
vpi__attrs.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="ViewPagerIndicator">
<!-- Style of the circle indicator. -->
<attr name="vpiCirclePageIndicatorStyle" format="reference"/>
</declare-styleable>
<declare-styleable name="CirclePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" format="boolean" />
<!-- Color of the filled circle that represents the current page. -->
<attr name="fillColor" format="color" />
<!-- Color of the filled circles that represents pages. -->
<attr name="pageColor" format="color" />
<!-- Orientation of the indicator. -->
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
<!-- Radius of the circles. This is also the spacing between circles. -->
<attr name="radius" format="dimension" />
<!-- Whether or not the selected indicator snaps to the circles. -->
<attr name="snap" format="boolean" />
<!-- Color of the open circles. -->
<attr name="strokeColor" format="color" />
<!-- Width of the stroke used to draw the circles. -->
<attr name="strokeWidth" format="dimension" />
</declare-styleable>
</resources>
Now add this code to design file.
Here you have to notice that MyApplication.Droid.Library is my name space and CirclePageIndicator is my page indicator file name so replace it with your's
<MyApplication.Droid.Library.CirclePageIndicator
android:id="#+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
now add the following in the activity file.
using Android.Support.V4.App;
using MyApplication.Droid.Library;
//global
public ViewPager mPager;
public PageIndicator mIndicator;
//in on create
var indicator = FindViewById<CirclePageIndicator>(Resource.Id.indicator);
mIndicator = indicator;
indicator.SetViewPager(mPager);
indicator.SetSnap(true);
I had solved this from the github
Look at this the sample project 'Android-ViewPagerIndicator to Xamarin.Android'. You need to include the library, where there are multiple implementation to display the indicators on viewpager.
https://github.com/Cheesebaron/ViewPagerIndicator
I got it working just like iOS PageControl.
Create the custom class as such:
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Runtime;
using Android.Util;
using Android.Widget;
using System;
using System.Collections.Generic;
namespace myProject.CustomWidgets
{
public class PageControl : LinearLayout
{
#region Properties
private int _currentPage = 0;
public int CurrentPage
{
get
{
return _currentPage;
}
set
{
_currentPage = value;
SetCurrentPageIndicator();
}
}
public int Pages = 0;
public Color PageIndicatorTintColor = ColorHelper.Clear;
public Color CurrentPageIndicatorTintColor = ColorHelper.Clear;
private readonly Context context;
private List<ImageView> ivList = new List<ImageView>();
private List<Drawable> drawableList = new List<Drawable>();
private readonly int circleSize = 7;
#endregion Properties
#region Constructor
protected PageControl(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public PageControl(Context context) : base(context)
{
this.context = context;
InitConfig();
}
public PageControl(Context context, IAttributeSet attrs) : base(context, attrs)
{
this.context = context;
InitConfig();
}
public PageControl(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
this.context = context;
InitConfig();
}
public PageControl(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
this.context = context;
InitConfig();
}
#endregion Constructor
#region Methods
private void InitConfig()
{
Orientation = Orientation.Horizontal;
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
Render();
}
private void Render()
{
// Start with a clean slate
RemoveAllViews();
ivList = new List<ImageView>();
drawableList = new List<Drawable>();
if (Pages <= 0)
{
return;
}
for (int i = 0; i < Pages; i++)
{
var iv = new ImageView(context);
var size = ConvertionHelper.DensityToPixels(context, circleSize);
var margin = (int)(size / 2.5);
var lp = new LayoutParams(size, size);
lp.SetMargins(margin, 0, margin, 0);
iv.LayoutParameters = lp;
/* By default, all drawables instances loaded from the same resource share a common state.
* If you modify the state of one instance, all the other instances will receive the same modification.
* Calling this method on a mutable Drawable will have no effect */
var drawable = ResourcesHelper.GetDrawable(context, Resource.Drawable.ic_circle_separator).Mutate();
drawable.SetColorFilter(PageIndicatorTintColor, PorterDuff.Mode.SrcAtop);
iv.SetImageDrawable(drawable);
drawableList.Add(drawable);
ivList.Add(iv);
AddView(iv);
}
// Initial current page indicator set-up
SetCurrentPageIndicator();
}
private void SetCurrentPageIndicator()
{
if (ivList.Count == 0 || drawableList.Count == 0 || ivList.Count != drawableList.Count ||
CurrentPage < 0 || CurrentPage >= ivList.Count)
{
return;
}
// Reset all colors
for (int i = 0; i < ivList.Count; i++)
{
drawableList[i].SetColorFilter(PageIndicatorTintColor, PorterDuff.Mode.SrcIn);
ivList[i].SetImageDrawable(drawableList[i]);
}
// Change color of current page indicator
drawableList[CurrentPage].SetColorFilter(CurrentPageIndicatorTintColor, PorterDuff.Mode.SrcIn);
ivList[CurrentPage].SetImageDrawable(drawableList[CurrentPage]);
}
#endregion Methods
}
}
Then use on your xml file such as:
<myProject.PageControl
android:id="#+id/pagecontrol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
Then on your activity you would have:
var pagecontrol = FindViewById<PageControl>(Resource.Id.pagecontrol);
pagecontrol.PageIndicatorTintColor = ColorHelper.PositiveBlue;
pagecontrol.CurrentPageIndicatorTintColor = ColorHelper.Orange;
pagecontrol.CurrentPage = 0;
pagecontrol.Pages = 3;

how to animate diff images in xna game?

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.

Xna (MonoGame) DynamicSoundEffectInstance Buffer already Full exception

I'm making this game in MonoGame (basically Xna) that uses DynamicSoundEffectInstance class. MonoGame does not have an implementation of DynamicSoundEffectInstance yet, so I made my own:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#if MONOMAC
using MonoMac.OpenAL;
#else
using OpenTK.Audio.OpenAL;
#endif
using System.Threading;
namespace Microsoft.Xna.Framework.Audio
{
public sealed class DynamicSoundEffectInstance : IDisposable
{
private const int BUFFERCOUNT = 2;
private SoundState soundState = SoundState.Stopped;
private AudioChannels channels;
private int sampleRate;
private ALFormat format;
private bool looped = false;
private float volume = 1.0f;
private float pan = 0;
private float pitch = 0f;
private int sourceId;
private int[] bufferIds;
private int[] bufferIdsToFill;
private int currentBufferToFill;
private bool isDisposed = false;
private bool hasSourceId = false;
private Thread bufferFillerThread = null;
// Events
public event EventHandler<EventArgs> BufferNeeded;
internal void OnBufferNeeded(EventArgs args)
{
if (BufferNeeded != null)
{
BufferNeeded(this, args);
}
}
public DynamicSoundEffectInstance(int sampleRate, AudioChannels channels)
{
this.sampleRate = sampleRate;
this.channels = channels;
switch (channels)
{
case AudioChannels.Mono:
this.format = ALFormat.Mono16;
break;
case AudioChannels.Stereo:
this.format = ALFormat.Stereo16;
break;
default:
break;
}
}
public bool IsDisposed
{
get
{
return isDisposed;
}
}
public float Pan
{
get
{
return pan;
}
set
{
pan = value;
if (hasSourceId)
{
// Listener
// Pan
AL.Source(sourceId, ALSource3f.Position, pan, 0.0f, 0.1f);
}
}
}
public float Pitch
{
get
{
return pitch;
}
set
{
pitch = value;
if (hasSourceId)
{
// Pitch
AL.Source(sourceId, ALSourcef.Pitch, XnaPitchToAlPitch(pitch));
}
}
}
public float Volume
{
get
{
return volume;
}
set
{
volume = value;
if (hasSourceId)
{
// Volume
AL.Source(sourceId, ALSourcef.Gain, volume * SoundEffect.MasterVolume);
}
}
}
public SoundState State
{
get
{
return soundState;
}
}
private float XnaPitchToAlPitch(float pitch)
{
// pitch is different in XNA and OpenAL. XNA has a pitch between -1 and 1 for one octave down/up.
// openAL uses 0.5 to 2 for one octave down/up, while 1 is the default. The default value of 0 would make it completely silent.
return (float)Math.Exp(0.69314718 * pitch);
}
public void Play()
{
if (!hasSourceId)
{
bufferIds = AL.GenBuffers(BUFFERCOUNT);
sourceId = AL.GenSource();
hasSourceId = true;
}
soundState = SoundState.Playing;
if (bufferFillerThread == null)
{
bufferIdsToFill = bufferIds;
currentBufferToFill = 0;
OnBufferNeeded(EventArgs.Empty);
bufferFillerThread = new Thread(new ThreadStart(BufferFiller));
bufferFillerThread.Start();
}
AL.SourcePlay(sourceId);
}
public void Apply3D(AudioListener listener, AudioEmitter emitter)
{
Apply3D(new AudioListener[] { listener }, emitter);
}
public void Pause()
{
if (hasSourceId)
{
AL.SourcePause(sourceId);
soundState = SoundState.Paused;
}
}
public void Apply3D(AudioListener[] listeners, AudioEmitter emitter)
{
// get AL's listener position
float x, y, z;
AL.GetListener(ALListener3f.Position, out x, out y, out z);
for (int i = 0; i < listeners.Length; i++)
{
AudioListener listener = listeners[i];
// get the emitter offset from origin
Vector3 posOffset = emitter.Position - listener.Position;
// set up orientation matrix
Matrix orientation = Matrix.CreateWorld(Vector3.Zero, listener.Forward, listener.Up);
// set up our final position and velocity according to orientation of listener
Vector3 finalPos = new Vector3(x + posOffset.X, y + posOffset.Y, z + posOffset.Z);
finalPos = Vector3.Transform(finalPos, orientation);
Vector3 finalVel = emitter.Velocity;
finalVel = Vector3.Transform(finalVel, orientation);
// set the position based on relative positon
AL.Source(sourceId, ALSource3f.Position, finalPos.X, finalPos.Y, finalPos.Z);
AL.Source(sourceId, ALSource3f.Velocity, finalVel.X, finalVel.Y, finalVel.Z);
}
}
public void Dispose()
{
if (!isDisposed)
{
Stop(true);
AL.DeleteBuffers(bufferIds);
AL.DeleteSource(sourceId);
bufferIdsToFill = null;
hasSourceId = false;
isDisposed = true;
}
}
public void Stop()
{
if (hasSourceId)
{
AL.SourceStop(sourceId);
int pendingBuffers = PendingBufferCount;
if(pendingBuffers > 0)
AL.SourceUnqueueBuffers(sourceId, PendingBufferCount);
if (bufferFillerThread != null)
bufferFillerThread.Abort();
bufferFillerThread = null;
}
soundState = SoundState.Stopped;
}
public void Stop(bool immediate)
{
Stop();
}
public TimeSpan GetSampleDuration(int sizeInBytes)
{
throw new NotImplementedException();
}
public int GetSampleSizeInBytes(TimeSpan duration)
{
int size = (int)(duration.TotalMilliseconds * ((float)sampleRate / 1000.0f));
return (size + (size & 1)) * 16;
}
public void SubmitBuffer(byte[] buffer)
{
this.SubmitBuffer(buffer, 0, buffer.Length);
}
public void SubmitBuffer(byte[] buffer, int offset, int count)
{
if (bufferIdsToFill != null) {
AL.BufferData (bufferIdsToFill [currentBufferToFill], format, buffer, count, sampleRate);
AL.SourceQueueBuffer (sourceId, bufferIdsToFill [currentBufferToFill]);
currentBufferToFill++;
if (currentBufferToFill >= bufferIdsToFill.Length)
bufferIdsToFill = null;
else
OnBufferNeeded (EventArgs.Empty);
} else {
throw new Exception ("Buffer already full.");
}
}
private void BufferFiller()
{
bool done = false;
while (!done)
{
var state = AL.GetSourceState(sourceId);
if (state == ALSourceState.Stopped || state == ALSourceState.Initial)
AL.SourcePlay(sourceId);
if (bufferIdsToFill != null)
continue;
int buffersProcessed;
AL.GetSource(sourceId, ALGetSourcei.BuffersProcessed, out buffersProcessed);
if (buffersProcessed == 0)
continue;
bufferIdsToFill = AL.SourceUnqueueBuffers(sourceId, buffersProcessed);
currentBufferToFill = 0;
OnBufferNeeded(EventArgs.Empty);
}
}
public bool IsLooped
{
get
{
return looped;
}
set
{
looped = value;
}
}
public int PendingBufferCount
{
get
{
if (hasSourceId)
{
int buffersQueued;
AL.GetSource(sourceId, ALGetSourcei.BuffersQueued, out buffersQueued);
return buffersQueued;
}
return 0;
}
}
}
}
Now, I followed this tutorial on making dynamic sounds in Xna, which worked with my custom MonoGame class. However, when I run the project (Xamarin Studio 4, Mac OS X 10.8, with MonoGame 3.0.1), it throws this exception:
Buffer already full
Pointing at the code in my custom class:
public void SubmitBuffer(byte[] buffer, int offset, int count)
{
if (bufferIdsToFill != null) {
AL.BufferData (bufferIdsToFill [currentBufferToFill], format, buffer, count, sampleRate);
AL.SourceQueueBuffer (sourceId, bufferIdsToFill [currentBufferToFill]);
currentBufferToFill++;
if (currentBufferToFill >= bufferIdsToFill.Length)
bufferIdsToFill = null;
else
OnBufferNeeded (EventArgs.Empty);
} else {
throw new Exception ("Buffer already full."); //RIGHT HERE IS THE EXCEPTION
}
}
I commented out the exception, and ran it again. It played the sound, with pops in it, but it still played it. How can I clear the buffer, so it is not full? I followed this tutorial EXACTLY, so all the code I added to my project is in there.
Oh! Figured it out myself; I changed the pending buffer count from 3 to 2. My final submit buffer code was:
while(_instance.PendingBufferCount < 2)
SubmitBuffer();
Where the 2 is, used to be a 3. Now it no longer throws the exception.

Making an object appear to move across the screen randomly

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.

Changing the colour of UIPageControl dots in MonoTouch

I was wondering if MonoTouch allows the developer to change the colour of UIPageControl dots to suit a light background - they seem to be fixed white, which makes them very hard to see on a light textured background.
I am aware there is no public API available for this but I was wondering if anything was internally implemented in MonoTouch to improve on this.
Otherwise, what's the recommended approach to using a UIPageControl on a light background?
I took a stab at translating this. I'm not sure it will work, but it does compile. Note that the page linked to contains comments indicating that Apple frowns upon this code and may reject it:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Whatever
{
public class StyledPageControl : UIPageControl
{
public StyledPageControl () : base()
{
}
public override int CurrentPage {
get {
return base.CurrentPage;
}
set {
base.CurrentPage = value;
string imgActive = NSBundle.MainBundle.PathForResource("activeImage", "png");
string imgInactive = NSBundle.MainBundle.PathForResource("inactiveImage", "png");
for (int subviewIndex = 0; subviewIndex < this.Subviews.Length; subviewIndex++)
{
UIImageView subview = this.Subviews[subviewIndex] as UIImageView;
if (subviewIndex == value)
subview.Image = UIImage.FromFile(imgActive);
else
subview.Image = UIImage.FromFile(imgInactive);
}
}
}
public override int Pages {
get {
return base.Pages;
}
set {
base.Pages = value;
string img = NSBundle.MainBundle.PathForResource("inactiveImage", "png");
for (int subviewIndex = 0; subviewIndex < this.Subviews.Length; subviewIndex++)
{
UIImageView subview = this.Subviews[subviewIndex] as UIImageView;
subview.Image = UIImage.FromFile(img);
}
}
}
}
}
Convert the following code to C#: http://apptech.next-munich.com/2010/04/customizing-uipagecontrols-looks.html
I combined this and this for monotouch. I hope this helps.
The usage is like this:
_pager.Change += delegate(object sender, EventArgs e) {
var pc = sender as PageControl;
Console.WriteLine ("Change Delegate== " + pc.currentPage);
var toPage = pc.currentPage;
var pageOffset = _scroll.Frame.Width*toPage;
PointF p = new PointF(pageOffset, 0);
Console.WriteLine (pageOffset);
_scroll.SetContentOffset(p,true);
};
And the class like this.
public class PageControl:UIView
{
#region ctor
public PageControl (RectangleF rect) :base(rect)
{
this.BackgroundColor = UIColor.Red;
this.CurrenColor=new CGColor(.2f,15f,10F);
this.OtherColor =new CGColor(.77F,.71F,.60F);
}
#endregion
#region Fields
float kDotDiameter= 7.0f;
float kDotSpacer = 7.0f;
int _currentPage;
int _numberOfPages;
CGColor CurrenColor{get;set;}
CGColor OtherColor{get;set;}
public int currentPage
{
set
{
_currentPage = Math.Min(Math.Max(0, value),_numberOfPages-1);
this.SetNeedsDisplay();
}
get{return _currentPage;}
}
public int numberOfPages
{
set
{
_numberOfPages = Math.Max(0,value);
_currentPage = Math.Min(Math.Max(0, _currentPage), _numberOfPages-1);
this.SetNeedsDisplay();
}
get{return _numberOfPages;}
}
#endregion
#region Overrides
public override void Draw (RectangleF rect)
{
base.Draw (rect);
CGContext context = UIGraphics.GetCurrentContext();
context.SetAllowsAntialiasing(true);
RectangleF currentBounds = this.Bounds;
float dotsWidth = this.numberOfPages*kDotDiameter + Math.Max(0,this.numberOfPages-1)*kDotSpacer;
float x = currentBounds.GetMidX() - dotsWidth/2;
float y = currentBounds.GetMidY() - kDotDiameter/2;
for (int i = 0; i < _numberOfPages; i++) {
RectangleF circleRect = new RectangleF(x,y,kDotDiameter,kDotDiameter);
if (i==_currentPage) {
context.SetFillColor(this.CurrenColor);
}
else {
context.SetFillColor(this.OtherColor);
}
context.FillEllipseInRect(circleRect);
x += kDotDiameter + kDotSpacer;
}
}
public override void TouchesBegan (MonoTouch.Foundation.NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
PointF touchpoint = (touches.AnyObject as MonoTouch.UIKit.UITouch).LocationInView(this);
RectangleF currentbounds = this.Bounds;
float x = touchpoint.X- currentbounds.GetMidX();
if (x<0 && this.currentPage>=0) {
this.currentPage--;
Change(this,EventArgs.Empty);
}
else if (x>0 && this.currentPage<this.numberOfPages-1) {
this.currentPage++;
Change(this,EventArgs.Empty);
}
}
#endregion
#region delegate
public event EventHandler Change;
#endregion
}

Resources