Making basic attack animation depending on keypress XNA C# - c#

I've got a 2D rpg-ish thing going on, where I want my character to swing a sword when I press a certain key, the sword swing is made out of 3 sprites.
This is the code I got going on so far:
EDIT: Upon request I've copypasted the entire class in where my attack-animation-code is in.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Media;
namespace RPGJensLomanderV2
{
class Player : Characters
{
KeyboardState ks;
Camera camera;
KeyboardState oldKs;
int attackTime;
Vector2 origin = Vector2.Zero;
bool isAnimationRunning = false;
public Player(GameScreen gameScreen, Camera camera)
: base(gameScreen)
{
health = 10;
this.camera = camera;
direction = Vector2.Zero;
movementSpeed = 1;
currentSprite = new Rectangle(229, 30, 14, 16);
}
public override void Load(ContentManager content)
{
spawnPoint = gameScreen.destSourceRecISE.Where(t => t.Value.X == 78 && t.Value.Y == 26).First().Key;
position = spawnPoint;
gameScreen.destSourceRecISE.Remove(spawnPoint);
base.Load(content);
}
public override void Update(GameTime gameTime)
{
ks = Keyboard.GetState();
timeSprite += gameTime.ElapsedGameTime.Milliseconds;
Attack(gameTime);
attackTime = 0;
Movement(gameTime);
camera.Position = position;
oldKs = ks;
}
private void Movement(GameTime gameTime)
{
if (ks.IsKeyDown(Keys.Right) && ks.IsKeyDown(Keys.Up))
{
direction = new Vector2(1, -1);
directionPointer = 1;
if (currentSprite.X != 140 && currentSprite.X != 154)
currentSprite = new Rectangle(140, 30, 14, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 140)
currentSprite = new Rectangle(154, 30, 14, 16);
else if (currentSprite.X == 154)
currentSprite = new Rectangle(140, 30, 14, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Right) && ks.IsKeyDown(Keys.Down))
{
direction = new Vector2(1, 1);
directionPointer = 2;
if (currentSprite.X != 229 && currentSprite.X != 245)
currentSprite = new Rectangle(229, 30, 16, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 229)
currentSprite = new Rectangle(245, 30, 16, 16);
else if (currentSprite.X == 245)
currentSprite = new Rectangle(229, 30, 16, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Left) && ks.IsKeyDown(Keys.Up))
{
direction = new Vector2(-1, -1);
directionPointer = 1;
if (currentSprite.X != 140 && currentSprite.X != 154)
currentSprite = new Rectangle(140, 30, 14, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 140)
currentSprite = new Rectangle(154, 30, 14, 16);
else if (currentSprite.X == 154)
currentSprite = new Rectangle(140, 30, 14, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Left) && ks.IsKeyDown(Keys.Down))
{
direction = new Vector2(-1, 1);
directionPointer = 2;
if (currentSprite.X != 229 && currentSprite.X != 245)
currentSprite = new Rectangle(229, 30, 16, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 229)
currentSprite = new Rectangle(245, 30, 16, 16);
else if (currentSprite.X == 245)
currentSprite = new Rectangle(229, 30, 16, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Left))
{
direction = new Vector2(-1, 0);
directionPointer = 3;
if (currentSprite.X != 198 && currentSprite.X != 214)
currentSprite = new Rectangle(198, 30, 16, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 198)
currentSprite = new Rectangle(214, 30, 15, 16);
else if (currentSprite.X == 214)
currentSprite = new Rectangle(198, 30, 16, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Right))
{
direction = new Vector2(1, 0);
directionPointer = 4;
if (currentSprite.X != 168 && currentSprite.X != 184)
currentSprite = new Rectangle(168, 30, 16, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 168)
currentSprite = new Rectangle(184, 30, 16, 16);
else if (currentSprite.X == 184)
currentSprite = new Rectangle(168, 30, 16, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Up))
{
direction = new Vector2(0, -1);
directionPointer = 1;
if (currentSprite.X != 140 && currentSprite.X != 154)
currentSprite = new Rectangle(140, 30, 14, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 140)
currentSprite = new Rectangle(154, 30, 14, 16);
else if (currentSprite.X == 154)
currentSprite = new Rectangle(140, 30, 14, 16);
timeSprite = 0;
}
}
else if (ks.IsKeyDown(Keys.Down))
{
direction = new Vector2(0, 1);
directionPointer = 2;
if (currentSprite.X != 229 && currentSprite.X != 245)
currentSprite = new Rectangle(229, 30, 16, 16);
if (timeSprite >= 100)
{
if (currentSprite.X == 229)
currentSprite = new Rectangle(245, 30, 16, 16);
else if (currentSprite.X == 245)
currentSprite = new Rectangle(229, 30, 16, 16);
timeSprite = 0;
}
}
else
{
direction = Vector2.Zero;
timeSprite = 0;
}
position += movementSpeed * direction;
}
private void Attack(GameTime gameTime)
{
if (ks.IsKeyDown(Keys.A) /*&& oldKs.IsKeyUp(Keys.A)*/)
{
isAnimationRunning = true;
}
while (isAnimationRunning && directionPointer == 1)
{
attackTime += gameTime.ElapsedGameTime.Milliseconds;
if (attackTime > 1 && attackTime < 100)
{
currentSprite = new Rectangle(3, 46, 32, 16);
}
if (attackTime < 200 && attackTime > 100)
{
currentSprite = new Rectangle(33, 61, 32, 32);
}
if (attackTime > 200 && attackTime < 300)
{
currentSprite = new Rectangle(61, 65, 16, 32);
}
if (attackTime > 300)
{
attackTime = 0;
currentSprite = new Rectangle(140, 30, 14, 16);
isAnimationRunning = false;
}
}
if (directionPointer == 2 && isAnimationRunning)
{
attackTime += gameTime.ElapsedGameTime.Milliseconds;
if (attackTime < 100)
{
currentSprite = new Rectangle(4, 67, 32, 16);
}
else if (attackTime < 200 && attackTime > 100)
{
currentSprite = new Rectangle(35, 66, 32, 32);
}
else if (attackTime > 200 && attackTime < 300)
{
currentSprite = new Rectangle(69, 66, 16, 32);
}
else if (attackTime > 300)
{
attackTime = 0;
isAnimationRunning = false;
currentSprite = new Rectangle(229, 30, 16, 16);
}
}
if (directionPointer == 3 && isAnimationRunning)
{
attackTime += gameTime.ElapsedGameTime.Milliseconds;
if (attackTime < 100)
{
currentSprite = new Rectangle(5, 138, 16, 32);
}
else if (attackTime < 200 && attackTime > 100)
{
currentSprite = new Rectangle(20, 138, 32, 32);
}
else if (attackTime > 200 && attackTime < 300)
{
currentSprite = new Rectangle(53, 154, 32, 16);
}
else if (attackTime > 300)
{
attackTime = 0;
isAnimationRunning = false;
currentSprite = new Rectangle(198, 30, 16, 16);
}
}
if (directionPointer == 4 && isAnimationRunning)
{
attackTime += gameTime.ElapsedGameTime.Milliseconds;
if (attackTime < 100)
{
currentSprite = new Rectangle(5, 102, 16, 32);
}
else if (attackTime < 200 && attackTime > 100)
{
currentSprite = new Rectangle(20, 102, 32, 32);
}
else if (attackTime > 200 && attackTime < 300)
{
currentSprite = new Rectangle(51, 118, 32, 16);
}
else if (attackTime > 300)
{
attackTime = 0;
currentSprite = new Rectangle(168, 30, 16, 16);
isAnimationRunning = false;
}
}
}
public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, currentSprite, Color.White, 0f, origin, 1f, SpriteEffects.None, 0f);
}
}
}
Right now, it does not go past the first sprite of the attack when I swing, and I am not totally sure how to make it happen. I'd be grateful if someone could give me a tip or the like of how I could make it go through the entire code so that a full swing will be done on the press of a button? Thanks on beforehand!

Define a global variable
bool isAnimationRunning = false;
and then change your code like this:
if (ks.IsKeyDown(Keys.A) && directionPointer == 1 && oldKs.IsKeyUp(Keys.A))
{
isAnimationRunning = true;
}
if(isAnimationRunning)
{
attackTime += gameTime.ElapsedGameTime.Milliseconds;
if (attackTime > 1 && attackTime < 100)
{
currentSprite = new Rectangle(3, 46, 32, 16);
}
else if (attackTime < 200 && attackTime > 100)
{
currentSprite = new Rectangle(33, 61, 32, 32);
}
else if (attackTime > 200 && attackTime < 300)
{
currentSprite = new Rectangle(61, 65, 16, 32);
}
else if (attackTime > 300)
{
attackTime = 0;
isAnimationRunning = false;
}
}

Related

C# snake game problem with body extension monogame

So I have this problem where my sprites draw to close to the head of my snake and therefore only takes very long time to complete the map. I have tried to increase the speed and lower the frame rate but it is very laggy.
//Comments are in Swedish
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
SpriteFont xcord;
SpriteFont ycord;
//Map settings
int mapX;
int mapY;
//Movement Variabels
//Snake Movement
bool snakemoveup;
bool snakemovedown;
bool snakemoveright;
bool snakemoveleft;
int speedx;
int speedy;
int score;
int timer;
int i;
List<Rectangle> snakelength = new List<Rectangle>();
List<int> positiony = new List<int>() { 300, 300 };
bool snakemoveup2;
bool snakemovedown2;
bool snakemoveright2;
bool snakemoveleft2;
bool snakemoveupMemory;
bool snakemovedownMemory;
bool snakemoverightMemory;
bool snakemoveleftMemory;
//Sprite Variables
//Textures
Texture2D snakehead;
Texture2D gamemap;
Texture2D gamemapborder;
Texture2D Leader_Right;
Texture2D Leader_Left;
Texture2D Leader_Up;
Texture2D Leader_Down;
Texture2D Follower;
Texture2D Candy;
//Sprite Rectangles
Rectangle snakerec;
Rectangle followerrec;
Rectangle candyrec;
//Position Variables
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}enter code here
protected override void Initialize()
{
// TODO: Add your initialization logic here
//MapSize
mapX = 900 + 100;
mapY = 800 + 100;
_graphics.PreferredBackBufferWidth = mapX;
_graphics.PreferredBackBufferHeight = mapY;
_graphics.ApplyChanges();
//Movement
speedx = 0;
speedy = 0;
base.Initialize();
}
protected override void LoadContent()
{
//läger till en svans i listan
snakelength.Add(new Rectangle(snakerec.X, snakerec.Y, 50, 50));
//sänker fps:n (nämnaren = önskade fps:n)
IsFixedTimeStep = true;
TargetElapsedTime = System.TimeSpan.FromSeconds(1d / 60);
xcord = Content.Load<SpriteFont>("File");
ycord = Content.Load<SpriteFont>("File");
_spriteBatch = new SpriteBatch(GraphicsDevice);
Leader_Right = Content.Load<Texture2D>("Leader_Right");
Leader_Left = Content.Load<Texture2D>("Leader_Left");
Leader_Up = Content.Load<Texture2D>("Leader_Up");
Leader_Down = Content.Load<Texture2D>("Leader_Down");
Candy = Content.Load<Texture2D>("Candy");
Follower = Content.Load<Texture2D>("Follower");
gamemap = Content.Load<Texture2D>("Snake_map");
gamemapborder = Content.Load<Texture2D>("Snakemapborder");
snakerec = new Rectangle(500, 450, Leader_Right.Width, Leader_Right.Height);
candyrec = new Rectangle(200,150, Candy.Width, Candy.Height);
// TODO: use this.Content to load your game content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
//gameTime.ElapsedGameTime.Milliseconds
//sätt en if innan ditt ökande
snakerec.X += speedx;
snakerec.Y += speedy;
if (Keyboard.GetState().IsKeyDown(Keys.W) && snakemovedown == false)
{
snakemoveup2 = true;
snakemoveupMemory = true;
}
if (Keyboard.GetState().IsKeyDown(Keys.D) && snakemoveleft == false)
{
snakemoveright2 = true;
snakemoverightMemory = true;
}
if (Keyboard.GetState().IsKeyDown(Keys.A) && snakemoveright == false)
{
snakemoveleft2 = true;
snakemoveleftMemory = true;
}
if (Keyboard.GetState().IsKeyDown(Keys.S) && snakemoveup == false)
{
snakemovedown2 = true;
snakemovedownMemory = true;
}
if (snakerec.X % 50 == 0 && snakemoveupMemory == true)
{
speedy = -5;
speedx = 0;
snakemoveup = true;
snakemovedown = false;
snakemoveright = false;
snakemoveleft = false;
snakemoveupMemory = false;
}
if (snakerec.Y % 50 == 0 && snakemoveleftMemory == true)
{
speedy = 0;
speedx = -5;
snakemoveleft = true;
snakemovedown = false;
snakemoveright = false;
snakemoveup = false;
snakemoveleftMemory = false;
}
if (snakerec.X % 50 == 0 && snakemovedownMemory == true )
{
speedy = 5;
speedx = 0;
snakemovedown = true;
snakemoveup = false;
snakemoveright = false;
snakemoveleft = false;
snakemovedownMemory = false;
}
if (snakerec.Y % 50 == 0 && snakemoverightMemory == true)
{
speedy = 0;
speedx = 5;
snakemoveright = true;
snakemovedown = false;
snakemoveup = false;
snakemoveleft = false;
snakemoverightMemory = false;
}
if (Keyboard.GetState().IsKeyUp(Keys.W))
{
snakemoveup2 = false;
}
if (Keyboard.GetState().IsKeyUp(Keys.S))
{
snakemovedown2 = false;
}
if (Keyboard.GetState().IsKeyUp(Keys.A))
{
snakemoveleft2 = false;
}
if (Keyboard.GetState().IsKeyUp(Keys.D))
{
snakemoveright2 = false;
}
//Godis
Random randomx = new Random();
Random randomy = new Random();
List<int> godtalx = new List<int>() { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900 };
List<int> godtaly = new List<int>() { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800 };
if (snakerec.Intersects(candyrec))
{
candyrec.X = godtalx[randomx.Next(1, 18)];
candyrec.Y = godtaly[randomx.Next(1, 16)];
score++;
snakelength.Add(new Rectangle(snakerec.X, snakerec.Y, 50, 50));
}
//Follower
if (snakelength.Count != score)
{
for (int i = snakelength.Count - 1; i > 0; i--)
{
snakelength[i] = new Rectangle(snakelength[i - 1].X, snakelength[i - 1].Y, 50, 50);
}
}
snakelength[0] = new Rectangle(snakerec.X, snakerec.Y, 50, 50);
//Infite borders
//X
if (snakerec.X <= 50 || snakerec.X >= 900)
{
if (snakerec.X <= 0)
{
snakerec.X = 995;
}
if (snakerec.X >= 1000)
{
snakerec.X = 5;
}
}
//Y
if (snakerec.Y <= 50 || snakerec.Y >= 800)
{
if (snakerec.Y <= 0)
{
snakerec.Y = 895;
}
if (snakerec.Y >= 900)
{
snakerec.Y = 5;
}
}
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
_spriteBatch.Begin();
_spriteBatch.Draw(gamemap, new Vector2(0, 0), Color.White);
for (int i = 0; i < snakelength.Count; i++)
{
_spriteBatch.Draw(Follower, new Rectangle(snakelength[i].X, snakelength[i].Y, 50, 50), Color.White);
}
//Vilket håll huvudet kollar mot
if (true)
{
if (snakemoveup == true)
{
_spriteBatch.Draw(Leader_Up, snakerec, Color.White);
}
if (snakemoveright == true)
{
_spriteBatch.Draw(Leader_Right, snakerec, Color.White);
}
if (snakemoveleft == true)
{
_spriteBatch.Draw(Leader_Left, snakerec, Color.White);
}
if (snakemovedown == true)
{
_spriteBatch.Draw(Leader_Down, snakerec, Color.White);
}
}
_spriteBatch.Draw(Candy, candyrec, Color.White);
_spriteBatch.Draw(gamemapborder, new Vector2(0, 0), Color.White);
_spriteBatch.DrawString(xcord, (snakelength.Count).ToString(), new Vector2(0, 60), Color.Black);
_spriteBatch.DrawString(xcord, (snakerec.X).ToString(), new Vector2(0, 0), Color.Black);
_spriteBatch.DrawString(ycord, (snakerec.Y).ToString(), new Vector2(0, 30), Color.Black);
_spriteBatch.End();
}
}
}

Saving a 2D array as JSON

I Have problem to save my simulation into JSON File.
the basics I make a moving ship. in the world space there will be a probe button that will provide information about the ship. I want to save that information into JSON.
Anyone know how to do that. I am new in Unity.
In button () I want to save the ship information (eg. position, depthsea, windspeed, temperature,flow
public class test : MonoBehaviour
{
// Start is called before the first frame update
public GameObject Ship;
public GameObject hole;
public GameObject turtle;
public GameObject panelhole;
public GameObject panelturtle;
public RectTransform shipvalue;
//public RectTransform flowvalue;
//public RectTransform windspeedvalue;
//public RectTransform temperaturevalue;
//public RectTransform depthvalue;
public Vector3 offset;
public RectTransform Basicobject; //parent
//public static bool captureAllKeyboardInput = false;
private bool paneloff = false;
public float duration = 1;
public int[,] grid = new int[10, 16];
public float[,] depth = new float[4, 3]
{{1.6f, 2.3f, 3.5f },
{4, 5, 6.5f},
{7, 8, 6.5f},
{7, 8, 6.5f}};
public float[,] temperaturedata = new float[10, 16]
{{0, 0, 0, 0, 0, 0, 0, 22.5f, 22.7f, 23, 23.9f, 24, 26.3f, 26.4f, 26.4f, 26.3f},
{0, 0, 0, 0, 0, 0, 22.8f, 23.2f, 23.8f, 24.4f, 25, 24.3f, 26.5f, 26.5f, 26.5f, 26.6f},
{0, 0, 0, 0, 0, 22.5f, 23.1f, 24.8f, 25.3f, 25.7f, 0, 0, 26.7f, 26.3f, 26.2f, 26.6f},
{0, 0, 0, 0, 23.2f, 23.8f, 25.1f, 25.4f, 25.9f, 0, 0, 26.8f, 26.9f, 26.5f, 26.3f, 26.3f},
{0, 0, 24.5f, 23.3f, 23.9f, 24.5f, 25.7f, 25.6f, 26.8f, 0, 0, 26.9f, 27.1f, 26.6f, 26.4f, 26.4f},
{0, 24.1f, 23.9f, 24.9f, 25.4f, 25.5f, 25.9f, 27.4f, 27.2f, 0, 0, 27, 27.2f, 26.8f, 26.4f, 26 },
{27.4f, 27.7f, 27.3f, 26.2f, 26.2f, 25.9f, 27.5f, 27.7f, 27.3f, 0, 26.8f, 27.2f, 27.2f, 26.9f, 26.4f, 26.2f},
{28.5f, 29, 27.5f, 27.3f, 27.3f, 27.5f, 27.7f, 27.7f, 27.5f, 27.2f, 27.2f, 27.4f, 27.4f, 26.9f, 26.3f, 26.7f},
{28.5f, 27.6f, 27.1f, 27, 26.5f, 27.6f, 27.6f, 27.6f, 27.7f, 27.4f, 27.8f, 27.7f, 27.7f, 27, 27, 26.6f},
{28.5f, 27.6f, 25, 27.3f, 26.8f, 27.8f, 27.3f, 27.5f, 28.1f, 27.9f, 28, 27.6f, 27.7f, 26.9f, 27.1f, 26.8f}};
public float[,] flowdata = new float[10, 16]
{{0, 0, 0, 0, 0, 0, 0, 0.4f, 0.4f, 0.6f, 0.8f, 0.6f, 0.7f, 0.4f, 0.4f, 0.4f},
{0, 0, 0, 0, 0, 0, 0.3f, 0.5f, 0.5f, 0.8f, 0.8f, 0.8f, 0.6f, 0.6f, 0.5f, 0.5f},
{0, 0, 0, 0, 0, 0.4f, 0.7f, 0.7f, 0.7f, 0.7f, 0, 0, 0.9f, 0.6f, 0.4f, 0.4f},
{0, 0, 0, 0, 0.5f, 0.5f, 0.6f, 0.7f, 0.6f, 0, 0, 0.8f, 0.8f, 0.4f, 0.3f, 0.3f},
{0, 0, 000, 0.7f, 0.6f, 0.5f, 0.7f, 1, 0.8f, 0, 0, 0.9f, 0.5f, 0.3f, 0.1f, 0.3f},
{0, 0.5f, 0.7f, 0.6f, 0.8f, 0.8f, 1.3f, 0.9f, 0.5f, 0, 0, 0.8f, 0.3f, 0.1f, 0.2f, 0.2f},
{0.6f, 0.6f, 0.6f, 0.7f, 1.1f, 0.9f, 0.8f, 0.4f, 0.3f, 0, 0.9f, 0.6f, 0.2f, 0.2f, 0.2f, 0.2f},
{0.4f, 0.4f, 0.5f, 0.5f, 0.3f, 0.4f, 0.3f, 0.2f, 0.4f, 0.2f, 0.8f, 0.3f, 0.2f, 0.2f, 0.2f, 0.1f},
{000, 0.3f, 0.5f, 0.2f, 0.2f, 0.2f, 0.2f, 0.1f, 0.2f, 0.6f, 0.6f, 0.3f, 0.3f, 0.2f, 0.2f, 0.2f},
{000, 000, 0.1f, 0.4f, 0.3f, 0.3f, 0.2f, 0.2f, 0.1f, 0.2f, 0.3f, 0.1f, 0.2f, 0.2f, 0.2f, 0.2f}};
public float[,] windspeeddata = new float[10, 12]
{{0,0,0,0,0,0,0,4,4,4,3,3},
{0,0,0,0,0,0,4,5,4,3,3,3},
{0,0,0,0,0,5,5,5,5,3,0,0},
{0,0,0,0,4,4,4,4,4,0,0,3},
{0,0,3,0,4,4,4,4,4,0,0,3},
{0,4,4,4,4,4,4,4,3,0,0,3},
{4,4,4,4,4,4,4,3,3,0,3,4},
{5,4,4,4,4,4,3,3,3,3,4,4},
{4,4,4,4,4,4,3,3,3,3,4,4},
{5,4,4,4,4,4,4,4,4,3,3,3}};
int row, column, num1, num2;
int p1;
int p2;
int[] grid2 = new int[5];
public Text shiposition = null;
public Text depthtext = null;
public Text windspeedtext = null;
public Text temperaturetext = null;
public Text flowtext = null;
//direction = Ship.transform.rotation.z;
float LastMove;
float timeIn = 0.5f;
public Vector3 direction;
float zvalue;
[Serializable]
public class ShipData
{
public int grid;
public float depth;
public float windspeed;
public float temperature;
}
[SerializeField]
private ShipData JSON_ShipData = new ShipData();
public void SaveintoJson()
{
string data = JsonUtility.ToJson(JSON_ShipData);
System.IO.File.WriteAllText(Application.persistentDataPath + "/DataCenter.json", data);
Debug.Log("Saving as JSON" + JSON_ShipData);
Debug.Log(Application.persistentDataPath);
}
void Start()
{
p1 = 9;
p2 = 0;
grid[p1, p2] = 1;
panelhole.SetActive(false);
panelturtle.SetActive(false);
Debug.Log(grid[p1, p2]);
Debug.Log(shiposition.transform.position);
}
// Update is called once per frame
void Update()
{
//Debug.Log(Ship.transform.localEulerAngles.z);
zvalue = Ship.transform.localEulerAngles.z;
if (Input.GetKeyDown(KeyCode.RightArrow))
{
StartCoroutine(Forward());
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
StartCoroutine(Backward());
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
StartCoroutine(Rotate(Vector3.forward, -90, 1.0f));
Debug.Log(transform.rotation.eulerAngles.z);
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
StartCoroutine(Rotate(Vector3.forward, 90, 1.0f));
Debug.Log(transform.rotation.eulerAngles.z);
}
if (Time.time - LastMove > timeIn)
{
LastMove = Time.time;
}
if (Input.GetKeyDown(KeyCode.W))
{
StartCoroutine(Rotate(Vector3.forward, 90, 1.0f));
// position(grid);
// depthsea(depth);
}
if (Input.GetKeyDown(KeyCode.A))
{
if (p2 >= 0)
{
StartCoroutine(Backward());
grid[p1, p2] = 0;
grid[p1, --p2] = 1;
//position(grid);
//depthsea(depth);
}
else
{
Debug.Log("You can't move left!!");
}
}
if (Input.GetKeyDown(KeyCode.D))
{
// z = 0
if (p2 <= 12 && zvalue == 0)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[p1, ++p2] = 1;
//position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
// z = 270
else if (p2 <= 12 && zvalue == 270)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[++p1, p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
//// z = 180
else if (p2 <= 12 && zvalue == 180)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[p1, --p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
//// z = 90
else if (p2 <= 12 && zvalue == 90)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[--p1, p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
else
{
Debug.Log("You can't move right any further!!");
Debug.Log(Ship.transform.localEulerAngles.z);
}
}
if (Input.GetKeyDown(KeyCode.S))
{
StartCoroutine(Rotate(Vector3.forward, -90, 1.0f));
//position(grid);
//depthsea(depth);
}
//WebGLInput.captureAllKeyboardInput = false;
}
private void position(int[,] grid)
{
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
if (grid[i, j] == 1)
{
// Debug.Log("x: " + i + " y: " + j + " Grid: " + grid[i, j]);
shiposition.text = "X : " + i + " " + "Y : " + j;
shiposition.text.ToString();
PlayerPrefs.SetString("position", shiposition.text);
PlayerPrefs.Save();
Debug.Log(shiposition.text);
}
}
}
}
public void windspeed(float[,] windspeeddata)
{
for (int x = 0; x < windspeeddata.GetLength(0); x++)
{
for (int y = 0; y < windspeeddata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
windspeedtext.text = "Windspeed Level :" + windspeeddata[x, y];
}
}
}
}
public void temperature(float[,] temperaturedata)
{
for (int x = 0; x < temperaturedata.GetLength(0); x++)
{
for (int y = 0; y < temperaturedata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
//Debug.Log(temperaturedata[x, y]);
temperaturetext.text = "Temperature :" + temperaturedata[x, y] + "C";
}
}
}
}
public void flow(float[,] flowdata)
{
for (int x = 0; x < flowdata.GetLength(0); x++)
{
for (int y = 0; y < flowdata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
flowtext.text = "Flow :" + flowdata[x, y];
}
}
}
}
public void depthsea(float[,] depth)
{
for (int x = 0; x < depth.GetLength(0); x++)
{
for (int y = 0; y < depth.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
depthtext.text = "Depth :" + depth[x, y];
Debug.Log(depth[x, y]);
}
}
}
}
public void moveobject()
{
shipvalue.transform.position = Ship.transform.position;
//shipvalue.transform.position.y + 0.5f;
//flowvalue.transform.position = Ship.transform.position;
//windspeedvalue.transform.position = Ship.transform.position;
//temperaturevalue.transform.position = Ship.transform.position;
//depthvalue.transform.position = Ship.transform.position;
}
public void button()
{
position(grid);
depthsea(depth);
windspeed(windspeeddata);
temperature(temperaturedata);
flow(flowdata);
moveobject();
//value.transform.position = Ship.transform.position;
//string newposition = JsonUtility.ToJson(shiposition.text);
//System.IO.File.WriteAllText(Application.persistentDataPath + "PositionData.json", newposition);
//Debug.Log(shiposition.text);
}
The JSON export itself should work that way
However, never use + "/" for system file paths. Rather use Path.Combine which inserts the correct path separator automatically
System.IO.File.WriteAllText(Path.Combine(Application.persistentDataPath, "DataCenter.json", data);
Main Problem
You are never assigning any values into the JSON_ShipData so you will always export a JSON with default values!
So first what you want is to store a Vector2Int for the position
[Serializable]
public class ShipData
{
public Vector2Int position;
public float depth;
public float windspeed;
public float temperature;
}
Then you probably would want to update the content at certain places like e.g.
private bool TryGetPosition(int[,] grid, out Vector2Int position)
{
position = default;
for (int x = 0; x < grid.GetLength(0); i++)
{
for (int y = 0; y < grid.GetLength(1); j++)
{
if (grid[x, y] == 1)
{
// store into the returned out value
position = new Vector2Int(x, y);
shiposition.text = $"X : {x} Y : {y}";
shiposition.text.ToString();
PlayerPrefs.SetInt("positionX", position.x);
PlayerPrefs.SetInt("positionY", position.y);
PlayerPrefs.Save();
Debug.Log(shiposition.text);
return true;
}
}
}
return false;
}
Note that this is also more efficient since it doesn't iterate through the rest of your grid if it already has found the position
Repeat the same for your other methods and then use them like e.g.
public void button()
{
// Check if a position is found and if yes update the json data
if(TryGetPosition(grid, out var position)
{
JSON_ShipData.position = position;
}
// Repeat the same for your other values
SaveintoJson();
}
General notes:
Before doing stuff like
grid[p1, --p2] = 1;
You should always check if your are maybe getting out of bounds e.g. like
private bool TryGoToPosition(int[,] grid, Vector2Int from, Vector2Int to)
{
if(to.x >= 0 && to.x < grid.GetLength(0) - 1 && to.y >= 0 && to.y < grid.GetLength(1) - 1)
{
grid[from.x, from.y] = 0;
grid[to.x, to.x] = 1;
}
else
{
Debug.LogWarning("Reached grid border! -> Ignored");
}
}
Then I would simply work with a Vector2Int in general instead of setting some value in a grid to 0 or 1 like
Vector2Int gridDimensions = new Vector2Int(10, 16);
public ShipData currentShipData;
public ShipData JSON_ShipData;
private bool CanGoToPosition(Vector2Int to)
{
return to.x >= 0 && to.x < gridDimensions.x - 1 && to.y >= 0 && to.y < gridDimensions.y - 1;
}
void Start()
{
currentShipData.position = new Vector2Int(9, 0);
panelhole.SetActive(false);
panelturtle.SetActive(false);
Debug.Log(JSON_ShipData.position);
Debug.Log(shiposition.transform.position);
}
void Update()
{
......
if (Input.GetKeyDown(KeyCode.A))
{
if (CanGoToPosition(JSON_ShipData.position + Vector2Int.down))
{
currentShipData.position += Vector2Int.down;
}
else
{
Debug.Log("You can't move left!!");
}
}
...
// Then after you handled user input for movement update the other data
currentShipData.windspeed = windspeedData[JSON_ShipData.position.x, JSON_ShipData.position.y];
currentShipData.flow = flowData[JSON_ShipData.position.x, JSON_ShipData.position.y];
...
}
Then for the button press you simply only copy over the current values
public void button()
{
JSON_ShipData.position = currentShipData.position;
...
SaveintoJson();
}

add multiple pages in C#

I'm writing a program in C# which takes information of items from Listview and print it based on the quantity of these items. My problem is that I would like to print a document in multiple pages in c#.
Here is my code:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
//frame
e.Graphics.DrawRectangle(Pens.Black, 30, 30, 757, 1080);
//rows
e.Graphics.DrawLine(Pens.Black, 30, 184, 787, 184);
e.Graphics.DrawLine(Pens.Black, 30, 338, 787, 338);
e.Graphics.DrawLine(Pens.Black, 30, 492, 787, 492);
e.Graphics.DrawLine(Pens.Black, 30, 646, 787, 646);
e.Graphics.DrawLine(Pens.Black, 30, 800, 787, 800);
e.Graphics.DrawLine(Pens.Black, 30, 955, 787, 955);
//columns
e.Graphics.DrawLine(Pens.Black, 282, 30, 282, 1110);
e.Graphics.DrawLine(Pens.Black, 534, 30, 534, 1110);
int rows_loc = 35;
int cols_loc = 70;
int lable_index = 0;
foreach (ListViewItem item in listView1.Items)
{
for (int quantity = 1; quantity < (Convert.ToInt32(item.SubItems[1].Text) + 1); quantity++)
{
Font font = new System.Drawing.Font("Arial", 16);
SolidBrush black = new SolidBrush(Color.Black);
Zen.Barcode.Code128BarcodeDraw barcode1 = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
Image barcode_image = barcode1.Draw(item.SubItems[2].Text, 20);
e.Graphics.DrawImage(barcode_image, 40f + cols_loc, 29f + rows_loc);
e.Graphics.DrawString(item.Text, font, black, 60f + cols_loc, 0f + rows_loc);
lable_index++;
row_index = (int)(lable_index / 3);
col_index = lable_index % 3;
rows_loc = 35 + ((row_index) * 155);
cols_loc = 70 + (250 * col_index);
if (rows_loc >= e.PageSettings.PrintableArea.Height)
{
e.HasMorePages = true;
rows_loc = 35;
return;
}
else
{
e.HasMorePages = false;
}
}
}
}
But got the page looks like the figure below with infinite number of pages! I would be very appreciated if someone can help.
Thanks

Use HSV instead of RGB in WPF

I'm using the Color.FromArgb to for determining the brush color. Using this for examplePen p= new Pen(new SolidColorBrush(Color.FromArgb(95, 255, 0, 0)), 6); the problem with this is that I want to use 4 colors of the brushes (red, orange, yellow and green). And I have a condition where depending on the value in this condition the color is chosen with a certain transparency. The problem with this is the transition between the two different colors, for example from green to yellow or from orange to red, the color changes suddenly and I don't want this. I want to transition to be smooth between different colors so for example from orange to red I want it to take the different degrees of oranges till it becomes reddish till it becomes red.
The below is a snapshot of my code trying to clarify what I did, so if anyone could please advise, and please let me know if any more clarification needed. So as shown below depending of the value of X the color is determined with a certain intensity, but the problem is in if the last value of X was 10 which means Green and the current is 11 which means the color is Yellow, this makes the view not smooth because the color changed from Green to Yellow without any degrees of smoothness. And I thought that may be using HSV can solve this problem. So if anyone could please advise.
for(X=0; X<=40; X++)
//this is green phase
if (X == 0)
P = new Pen(new SolidColorBrush(Color.FromArgb(75, 0, 255, 0)), 6);
else if (X == 1)
P = new Pen(new SolidColorBrush(Color.FromArgb(77, 0, 255, 0)), 6);
else if (X == 2)
P = new Pen(new SolidColorBrush(Color.FromArgb(79, 0, 255, 0)), 6);
else if (X == 3)
P = new Pen(new SolidColorBrush(Color.FromArgb(81, 0, 255, 0)), 6);
else if (X == 4)
P = new Pen(new SolidColorBrush(Color.FromArgb(83, 0, 255, 0)), 6);
else if (X == 5)
P = new Pen(new SolidColorBrush(Color.FromArgb(85, 0, 255, 0)), 6);
else if (X == 6)
P = new Pen(new SolidColorBrush(Color.FromArgb(87, 0, 255, 0)), 6);
else if (X == 7)
P = new Pen(new SolidColorBrush(Color.FromArgb(89, 0, 255, 0)), 6);
else if (X == 8)
P = new Pen(new SolidColorBrush(Color.FromArgb(91, 0, 255, 0)), 6);
else if (X == 9)
P = new Pen(new SolidColorBrush(Color.FromArgb(93, 0, 255, 0)), 6);
else if (X == 10)
P = new Pen(new SolidColorBrush(Color.FromArgb(95, 0, 255, 0)), 6);
// this is yellow phase
else if (X == 11)
P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 255, 0)), 6);
else if (X == 12)
P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 255, 0)), 6);
else if (X == 13)
P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 255, 0)), 6);
else if (X == 14)
P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 255, 0)), 6);
else if (X == 15)
P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 255, 0)), 6);
else if (X == 16)
P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 255, 0)), 6);
else if (X == 17)
P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 255, 0)), 6);
else if (X == 18)
P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 255, 0)), 6);
else if (X == 19)
P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 255, 0)), 6);
else if (X == 20)
P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 255, 0)), 6);
// this is orange phase
else if (X == 21)
P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 127, 0)), 6);
else if (X == 22)
P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 127, 0)), 6);
else if (X == 23)
P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 127, 0)), 6);
else if (X == 24)
P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 127, 0)), 6);
else if (X == 25)
P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 127, 0)), 6);
else if (X == 26)
P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 127, 0)), 6);
else if (X == 27)
P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 127, 0)), 6);
else if (X == 28)
P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 127, 0)), 6);
else if (X == 29)
P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 127, 0)), 6);
else if (X == 30)
P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 127, 0)), 6);
//this is red phase
else if (X == 31)
P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 0, 0)), 6);
else if (X == 32)
P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 0, 0)), 6);
else if (X == 33)
P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 0, 0)), 6);
else if (X == 34)
P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 0, 0)), 6);
else if (X == 35)
P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 0, 0)), 6);
else if (X == 36)
P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 0, 0)), 6);
else if (X == 37)
P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 0, 0)), 6);
else if (X == 38)
P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 0, 0)), 6);
else if (X == 39)
P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 0, 0)), 6);
else if (X == 40)
P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 0, 0)), 6);
Maybe you should take a look into this answer. It helps you to use the methods GetHue(), GetSaturation() and GetBrightness() from the color class and create a new color from these parameters.
By using this you can simply get out the hue of your start and end color and depending on your step size get as much intermediate colors as needed.
Wouldn't it be great to have a method:
int numberOfIntermediateColors = 8;
IEnumerable<Colors> colorPalette = Color.Red.Range(Color.Green, numberOfIntermediateColors);
And here it is:
public static IEnumerable<Color> Range(this Color firstColor, Color lastColor, int count)
{
float stepHueClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.Clockwise);
float stepHueCounterClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.CounterClockwise);
if (Math.Abs(stepHueClockwise) >= Math.Abs(stepHueCounterClockwise))
return Range(firstColor, lastColor, count, Direction.Clockwise);
else
return Range(firstColor, lastColor, count, Direction.CounterClockwise);
}
public static IEnumerable<Color> Range(this Color firstColor, Color lastColor, int count, Direction hueDirection)
{
var color = firstColor;
if (count <= 0)
yield break;
if (count == 1)
yield return firstColor;
float startingHue = color.GetHue();
float stepHue = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count - 1, hueDirection);
var stepSaturation = (lastColor.GetSaturation() - firstColor.GetSaturation()) / (count - 1);
var stepBrightness = (lastColor.GetBrightness() - firstColor.GetBrightness()) / (count - 1);
var stepAlpha = (lastColor.A - firstColor.A) / (count - 1.0);
for (int i = 1; i < count; i++)
{
yield return color;
var hueValue = startingHue + stepHue * i;
if (hueValue > 360)
hueValue -= 360;
if (hueValue < 0)
hueValue = 360 + hueValue;
color = FromAhsb(
Clamp((int)(color.A + stepAlpha), 0, 255),
hueValue,
Clamp(color.GetSaturation() + stepSaturation, 0, 1),
Clamp(color.GetBrightness() + stepBrightness, 0, 1));
}
yield return lastColor;
}
public enum Direction
{
Clockwise = 0,
CounterClockwise = 1
}
private static float GetStepping(float start, float end, int count, Direction direction)
{
var hueDiff = end - start;
switch (direction)
{
case Direction.CounterClockwise:
if (hueDiff >= 0)
hueDiff = (360 - hueDiff) * -1;
break;
default:
if (hueDiff <= 0)
hueDiff = 360 + hueDiff;
break;
}
return hueDiff / count;
}
private static int Clamp(int value, int min, int max)
{
if (value < min)
return min;
if (value > max)
return max;
return value;
}
private static float Clamp(float value, float min, float max)
{
if (value < min)
return min;
if (value > max)
return max;
return value;
}
To get your list of pens without any transparency you can take this simple approach:
var startColor = Color.Green;
var endColor = Color.Red;
var penWidth = 6;
var rainbow = startColor.Range(endColor, 40, bla.Direction.CounterClockwise);
var pens = rainbow.Select(color => new Pen(color, penWidth))
.ToList();
// Somewhere else...
int x = RetrieveDesiredCondition();
var neededPen = pens[x];
As far as i can see in your example you like to let the transparency iterate from 75 - 95 for each block of ten colors and a total of four blocks. In that case maybe this algorithm may help:
var startColor = Color.Green;
var endColor = Color.Red;
var penWidth = 6;
var lowerTransparency = 75;
var higherTransparency = 95;
var stepsPerSection = 10;
var sections = 4;
var stepsNeeded = stepsPerSection * sections;
var transparencyRange = higherTransparency - lowerTransparency;
var stepSize = transparencyRange / stepsPerSection;
var rainbow = startColor.Range(endColor, stepsNeeded, Direction.CounterClockwise);
var rainbowWithTransparency = rainbow.Select((color, index) =>
{
var step = (index % stepsPerSection) * stepSize;
var neededTransparency = lowerTransparency + step;
return Color.FromArgb(neededTransparency, color);
});
var pens = rainbowWithTransparency.Select(color => new Pen(color, penWidth))
.ToList();
// Somewhere else...
int x = RetrieveDesiredCondition();
var neededPen = pens[x];

How can I get my collision to be more solid?

I'm working on a game in C# with XNA and I've been learning program in C# thanks to Nick Gravelyn's tutorials, but I've hit a snag. While I'm using Nick's collision system, I'm not using his player code. I'm using one that's based on a tutorial by Fatso784 that I've modified. So, as a result, I'm having trouble making my modified version of the collision system work properly. I've got it to the point that it pushes the player out of certain tiles, but I need it to be more solid because the player is still able walk through walls occasionally. I'm pretty sure I'm handling the collision wrong, but it could be that the collision is a little mushy. So here's the relevant code from my player class, the move code:
public void Move()
{
pos.X = bounds.X;
pos.Y = bounds.Y;
offsetPos.X = bounds.Width;
offsetPos.Y = bounds.Height;
if (frameCount % delay == 0)
{
switch (direction)
{
case "stand":
if (sideCollide == "none")
{
Equalize(2);
}
else if (sideCollide == "left")
{
speed += 1f;
}
else if (sideCollide == "right")
{
speed -= 1f;
}
bounds.X += (int)speed;
if (frameCount / delay >= 8)
frameCount = 0;
srcBounds = new Rectangle(frameCount / delay * 64, 0, 64, 64);
break;
case "left":
if (sideCollide != "left")
{
if (speed > -maxspeed)
{
speed -= acceleration;
}
else if (speed < -maxspeed)
{
speed -= acceleration;
speed += drag;
Equalize(2);
}
speed += friction;
}
bounds.X += (int)speed;
if (frameCount / delay >= 4)
frameCount = 0;
srcBounds = new Rectangle(frameCount / delay * 64, 64, 64, 64);
break;
case "right":
if (sideCollide != "right")
{
if (speed < maxspeed)
{
speed += acceleration;
}
else if (speed > maxspeed)
{
speed += acceleration;
speed -= drag;
Equalize(2);
}
speed -= friction;
}
bounds.X += (int)speed;
if (frameCount / delay >= 4)
frameCount = 0;
srcBounds = new Rectangle(frameCount / delay * 64, 64, 64, 64);
break;
case "up":
if (speed > -4 && speed < 4)
srcBounds.Y = 128;
else
srcBounds.Y = 64;
if (srcBounds.Y == 0 || srcBounds.Y == 128)
{
if (jumpCount < 2)
{
if (frameCount / delay >= 9)
frameCount = 0;
}
else if (jumpCount > 2 && jumpCount <= 10)
{
if (frameCount / delay > 3)
frameCount = 2 * delay;
}
else if (jumpCount > 10 && jumpCount <= 18)
{
if (frameCount / delay > 5)
frameCount = 4 * delay;
}
else if (jumpCount > 18)
{
if (frameCount / delay >= 9)
frameCount = 0;
}
srcBounds = new Rectangle(frameCount / delay * 64, 128, 64, 64);
}
else if (srcBounds.Y == 64)
{
if (frameCount / delay >= 4)
frameCount = 0;
if (jumpCount <= 10)
srcBounds = new Rectangle((frameCount / delay) / 2 * 64, 64, 64, 64);
else
srcBounds = new Rectangle(frameCount / delay * 64, 64, 64, 64);
}
if (jumpCount == 0)
startY = bounds.Y;
bounds = new Rectangle(bounds.X + (int)speed,
(jumpCount - 10) * (jumpCount - 10) - 100 + startY, 64, 64);
jumpCount++;
if (bounds.Y > startY)
{
bounds.Y = startY;
direction = "stand";
jumpCount = 0;
}
break;
}
}
frameCount++;
}
And the collision code:
public void CollideOutside(TileMap tilemap)
{
Point cell = Engine.PointCell(PlayerCenter);
Point? upLeft = null, Up = null, upRight = null, Right = null, downRight = null, Down = null, downLeft = null, Left = null;
if (cell.Y > 0)
{
Up = new Point(cell.X, cell.Y - 1);
}
if (cell.Y < tilemap.collisionMap.HeightinPixels)
{
Down = new Point(cell.X, cell.Y + 1);
}
if (cell.X > 0)
{
Left = new Point(cell.X - 1, cell.Y);
}
if (cell.X < tilemap.collisionMap.WidthinPixels)
{
Right = new Point(cell.X + 1, cell.Y);
}
if (cell.X > 0 && cell.Y > 0)
{
upLeft = new Point(cell.X - 1, cell.Y - 1);
}
if (cell.X < tilemap.collisionMap.WidthinPixels - 1 && cell.Y > 0)
{
upRight = new Point(cell.X + 1, cell.Y - 1);
}
if (cell.X > 0 && cell.Y < tilemap.collisionMap.HeightinPixels - 1)
{
downLeft = new Point(cell.X - 1, cell.Y + 1);
}
if (cell.X < tilemap.collisionMap.WidthinPixels - 1 && cell.Y < tilemap.collisionMap.Height - 1)
{
downRight = new Point(cell.X + 1, cell.Y + 1);
}
if (Up != null && tilemap.collisionMap.GetCellIndex(Up.Value) == 1)
{
Rectangle rect = Engine.CreateCell(Up.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
}
}
if (Down != null && tilemap.collisionMap.GetCellIndex(Down.Value) == 1)
{
Rectangle rect = Engine.CreateCell(Down.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
}
}
if (Right != null && tilemap.collisionMap.GetCellIndex(Right.Value) == 1)
{
Rectangle rect = Engine.CreateCell(Right.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
speed = -1f;
sideCollide = "right";
}
else
{
sideCollide = "none";
}
}
if (Left != null && tilemap.collisionMap.GetCellIndex(Left.Value) == 1)
{
Rectangle rect = Engine.CreateCell(Left.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
speed = 1f;
sideCollide = "left";
}
else
{
sideCollide = "none";
}
}
if (upLeft != null && tilemap.collisionMap.GetCellIndex(upLeft.Value) == 1)
{
Rectangle rect = Engine.CreateCell(upLeft.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
}
}
if (upRight != null && tilemap.collisionMap.GetCellIndex(upRight.Value) == 1)
{
Rectangle rect = Engine.CreateCell(upRight.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
}
}
if (downLeft != null && Left != null && tilemap.collisionMap.GetCellIndex(downLeft.Value) == 1)
{
Rectangle rect = Engine.CreateCell(downLeft.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
speed = 1f;
sideCollide = "left";
}
}
if (downRight != null && Right != null && tilemap.collisionMap.GetCellIndex(downRight.Value) == 1)
{
Rectangle rect = Engine.CreateCell(downRight.Value);
Rectangle playerCell = Boundary;
if (rect.Intersects(playerCell))
{
speed = -1f;
sideCollide = "right";
}
}
if (Right == null && Left == null)
{
sideCollide = "none";
}
}
public Rectangle Boundary
{
get
{
Rectangle rect = bounds;
rect.X = (int)pos.X;
rect.Y = (int)pos.Y;
return rect;
}
}
So how can I improve the collision?
This answer is mostly in response to Tim's answer - because he's given very much the wrong approach. (Your question is a very large code dump, I can't really play spot-the-error with that much code.)
The trick with collision detection - the way the "real" physics engines do it - is to always treat your objects as solids. You always - each frame - check objects for interpenetration, and then separate them if they interpenetrate.
If you only test for moving across the boundary of an object you are going to miss collisions. This includes any approach where you attempt to predict and avoid a collision by snapping onto the surface. If you do this, you are just asking for floating-point precision errors to let you slip inside objects.
EDIT: of course, your code all seems to be integer-based (Point and Rectangle). So at least floating-point precision should not be an issue. But maybe you have a < where you should have a <= or something to that effect?
(Also you're using strings in a lot of places where you very much should be using enumerations.)

Categories

Resources