Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Switch statement not working?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
22 replies to this topic

#1 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 06:29 AM

so in my game engine that im making there is a part in the program that makes an object of the Player class render and animate depending on what the Movement state is (i.e standing, running, jumping, crouching). However when i use a switch statement to check which state is active it basically skips over everything and goes to "running"...making a continuous running sprite animation. I really dont see why it would do that.

Here are the 3 main files used in this problem:

//Entity.h

#include "Engine.h"

namespace DarkMatter
{
	class Entity
	{

	protected:

		LPDIRECT3DTEXTURE9 texture;
		D3DXVECTOR3 pos;

		int health;
		int frame;
		int starttime;
		int width;
		int height;

	public:

		Entity();
		~Entity();

		void LoadTexture(string filename, D3DCOLOR trans);

		void DrawFrame(int width, int height, int columns);
		void Animate(int startframe, int endframe, int direction, int delay);

		void SetPos(float x, float y);
		void SetDimensions(string filename);

		virtual void Move() = 0;
		virtual void Update() = 0;

	};

	class Player : public Entity
	{

	private:

		int health;
		int frame;
		int starttime;
		int width;
		int height;

		enum Movement {standing, running, jumping, crouching};
		Movement state;

	public:

		Player();
		~Player();

		void Move();
		void Update();

	};
};

//Entity.cpp

#include "Entity.h"

namespace DarkMatter
{
	Entity::Entity()
	{
		this -> texture = NULL;
		this -> pos.x = 0; this -> pos.y = 0;

		this -> health = 0;
		this -> frame = 0;
		this -> starttime = 0;
		this -> width = 0;
		this -> height = 0;

	}

	Entity::~Entity()
	{

	}

	void Entity::LoadTexture(string filename, D3DCOLOR trans)
	{
		D3DXIMAGE_INFO info;
		D3DXGetImageInfoFromFile(filename.c_str(), &info);

		D3DXCreateTextureFromFileEx(
			engine -> GetDevice(),
			filename.c_str(),
			info.Width, info.Height,
			1,
			D3DPOOL_DEFAULT,
			D3DFMT_UNKNOWN,
			D3DPOOL_DEFAULT,
			D3DX_DEFAULT,
			D3DX_DEFAULT,
			trans,
			&info,
			NULL,
			&this -> texture);
	}

	void Entity::DrawFrame(int width, int height, int columns)
	{
		D3DXVECTOR3 pos(this -> pos.x, this -> pos.y, 0);
		D3DCOLOR white = D3DCOLOR_XRGB(255, 255, 255);

		RECT rect;
		rect.left = (this -> frame % columns) * width;
		rect.top = (this -> frame / columns) * height;
		rect.right = rect.left + width;
		rect.bottom = rect.top + height;

		engine -> GetSprite() -> Draw(this -> texture, &rect, NULL, &pos, white);
	}

	void Entity::Animate(int startframe, int endframe, int direction, int delay)
	{
		if ((int)GetTickCount() > this -> starttime + delay)
		{
			this -> starttime = GetTickCount();

		this -> frame += direction;
		
		if (this -> frame > endframe) this -> frame = startframe;
		if (this -> frame < startframe) this -> frame = endframe;
		
		}
	}

	void Entity::SetPos(float x, float y)
	{
		this -> pos.x = x;
		this -> pos.y = y;
	}

	void Entity::SetDimensions(string filename)
	{
		D3DXIMAGE_INFO info;
		D3DXGetImageInfoFromFile(filename.c_str(), &info);

		this -> width = info.Width;
		this -> height = info.Height;
	}};

//Player.cpp

#include "Entity.h"

namespace DarkMatter
{
	Player::Player()
	{
		this -> health = 0;
		this -> frame = 0;
		this -> starttime = 0;
		this -> width = 37;
		this -> height = 44;
	}

	Player::~Player()
	{

	}

	void Player::Move()
	{
		engine -> GetKeyboard() -> Acquire();
		engine -> GetKeyboard() -> GetDeviceState(sizeof(engine -> keys), (LPVOID)&engine -> keys);

		if (engine -> keys[DIK_LEFT] & 0x80)
		{
			this -> pos.x -= 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_RIGHT] & 0x80)
		{
			this -> pos.x += 3.0f;
			this -> state = running;
		}

		else 
		{
			this -> state = standing;
			this -> frame = 0;
		}

		if (engine -> keys[DIK_UP] & 0x80)
		{
			this -> pos.y -= 3.0f;
			this -> state = standing;
		}

		else if (engine -> keys[DIK_DOWN] & 0x80)
		{
			this -> pos.y += 3.0f;
			this -> state = standing;
		}

		else 
		{
			this -> state = standing;
			this -> frame = 0;
		}

		if (engine -> keys[DIK_ESCAPE] & 0x80)
		{
			gameover = true;
		}
	}

	void Player::Update()
	{
		this -> Move();

		switch (this -> state)
		{
		case running:
			{
				this -> DrawFrame(37, 44, 6);
				this -> Animate(0, 5, 1, 60);
				break;
			}

		case standing:
			{
				this -> DrawFrame(37, 44, 6);
				break;
			}

		case jumping:
			{
				break;
			}
			
		case crouching:
			{
				break;
			}

		default:
			{

			}
		}
	}};


As you can see i made an Enum in the Player class that holds all the possible movement types. Then when the player presses the keys to make the sprite move the state changes from standing to running. In the Update() function it uses a switch statement to check which state the character is in to make the corrisponding animation. However it jumps straight to "case running" and makes a continuous running animation. If you could help me out then thanks :)














Sponsor:

#2 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 06:33 AM

You need to use the 'break' keyword.

http://tigcc.ticalc.org/doc/keywords.html#break

#3 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 06:35 AM

everyone keeps telling me that and i know what they are....i used them in here before but they arent doing anything...it just makes the sprite get stuck in the "standing" state and move around without being animated :P

#4 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 06:39 AM

everyone keeps telling me that and i know what they are....i used them in here before but they arent doing anything...it just makes the sprite get stuck in the "standing" state and move around without being animated :P


Your Player::Move function is the reason it stays standing. Look at the if...else blocks.



#5 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 06:42 AM

i dont see the problem? the state changes to "running" when the left and right arrow keys are pressed....and if not then it goes back to "standing"...the up and down arrow keys are "standing" because i didnt get a jumping animation ready yet

#6 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 06:45 AM

i dont see the problem? the state changes to "running" when the left and right arrow keys are pressed....and if not then it goes back to "standing"...the up and down arrow keys are "standing" because i didnt get a jumping animation ready yet


Follow the logic of that function. If the up key or down key is pressed then the animation is standing, otherwise the animation is... standing.

#7 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 06:47 AM

ok well i did this and it still doesnt do anything....only animates when i press up but it doesnt revert back to the standing position...just gets stuck in what ever frame you released the up key in:



		if (engine -> keys[DIK_LEFT] & 0x80)
		{
			this -> pos.x -= 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_RIGHT] & 0x80)
		{
			this -> pos.x += 3.0f;
			this -> state = running;
		}

		else 
		{
			this -> state = standing;
			this -> frame = 0;
		}

		if (engine -> keys[DIK_UP] & 0x80)
		{
			this -> pos.y -= 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_DOWN] & 0x80)
		{
			this -> pos.y += 3.0f;
			this -> state = running;
		}

		else 
		{
			this -> state = standing;
			this -> frame = 0;
		}


#8 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 06:54 AM

OK... i'll spell it out for you.

if (key left)
run
else if (key right)
run
else
stand

if (key up)
run
else if (key down)
run
else
stand

If i hold left state is set to run in first if...else block. Then state is set to stand in second if...else block as I am not holding up or down keys.

#9 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 07:02 AM

if (engine -> keys[DIK_LEFT] & 0x80)
		{
			this -> pos.x -= 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_RIGHT] & 0x80)
		{
			this -> pos.x += 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_UP] & 0x80)
		{
			this -> pos.y -= 3.0f;
			this -> state = running;
		}

		else if (engine -> keys[DIK_DOWN] & 0x80)
		{
			this -> pos.y += 3.0f;
			this -> state = running;
		}

		else 
		{
			this -> state = standing;
			this -> frame = 0;		}


sorry man...i just got alot on my mind right now so im not thinking right :P but anyways i did this and the animation starts at the right time now....however when i let go of the key it just stops at whatever frame of the animation it was on...i need it to go back to frame #0 so that he'll be back in his starting position

#10 kauna   Members   -  Reputation: 1139

Like
0Likes
Like

Posted 02 August 2011 - 07:13 AM

You should keep better track of key events. Just handling "key pressed" won't give you enough information about the keyboard state.

You'll need to find out also if key that was pressed earlier was released. In the simplest form, when you receive the key release event, you can reset your pose and animation frame.

Of course, you'll need to handle cases such as if several move related keys are pressed and released in the same time.

Cheers!

#11 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 07:16 AM

Sorry, it's not obvious why that would happen. Why do you use 'columns' in the rect.top calculation? Surely that should be rows...

#12 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 07:18 AM

You should keep better track of key events. Just handling "key pressed" won't give you enough information about the keyboard state.

You'll need to find out also if key that was pressed earlier was released. In the simplest form, when you receive the key release event, you can reset your pose and animation frame.

Of course, you'll need to handle cases such as if several move related keys are pressed and released in the same time.

Cheers!


He's not dealing with pressed/released events. He's getting the device state and testing which keys are currently down.

#13 kauna   Members   -  Reputation: 1139

Like
0Likes
Like

Posted 02 August 2011 - 07:22 AM


You should keep better track of key events. Just handling "key pressed" won't give you enough information about the keyboard state.

You'll need to find out also if key that was pressed earlier was released. In the simplest form, when you receive the key release event, you can reset your pose and animation frame.

Of course, you'll need to handle cases such as if several move related keys are pressed and released in the same time.

Cheers!


He's not dealing with pressed/released events. He's getting the device state and testing which keys are currently down.



exactly my point.



#14 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 07:22 AM

Why do you use 'columns' in the rect.top calculation? Surely that should be rows..



Its just how i was taught to do animation...it works though...the sprite comes out fine and animates right...its just these darn states that i cant get for some reason...just gets stuck

#15 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 07:28 AM

'columns' is always greater than 'this->frame', so 'this->frame / columns' is always zero.

The statement "rect.top = 0;" is equivalent.

I don't mean to be overly critical but doing things the way you were taught instead of understanding the maths involved is not a good way to do things...

EDIT: If you have rows in the sprite map then you need to pass the number of rows and use 'rect.top = (this->frame % rows) * height;'

#16 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 07:33 AM

i only have one row in my "sprite sheet" so i cant really use rows lol its one long row with 6 columns

#17 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 07:34 AM

Actually, at frame zero we have:

rect.left = (0 % 6) * width = 6 * width

it should be

rect.left = frame * width = 0 * width;

#18 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 07:36 AM

lol well it works fine for right now...i dont really wanna mess with anything else unless it proves to be a problem. First i just wanna clear up this whole states mess :P

#19 triangles   Members   -  Reputation: 106

Like
0Likes
Like

Posted 02 August 2011 - 07:40 AM

Sorry, I was wrong about the modulo (The % button in windows calculator is not modulo) and the code would work.

Although the code I gave (frame * width) is exactly equivalent and makes more sense.

#20 Cryptiik   Members   -  Reputation: 242

Like
0Likes
Like

Posted 02 August 2011 - 07:43 AM

yeah lol anyways i really wish i could figure out what the problem with this state thing is...its the first time its happened to me....i used this in another program i made and i worked fine. Dont know why its doing this now




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS