C++ How to animate graphics (POO) - c++

I'm working on a game project in c++ using programming oriented object and classes but I can't figure out a way to animate the following graphics.
What I need is while the player is holding left key or the right key, the graphics should be appearing to make the character like moving and when they stop holding the key it'll turn to idle graphic.
I can't paste the whole source code here, i have many classes, and functions.. All I need is a BASIC idea of how to implement it, an example or a function anything useful. I don't need libraries because i just have two sprites to animate so it's not necessary.
As an example be Sprites the class that creates the object and Koala the one that moves it and prints it in a certain position.
Sprites idleSprite, walkingSprite;
Koala koala;
These declarations are just for avoiding other explanations.
I would appreciate your help.
PD: Don't worry about the keyboard keys, or other classes all I need is how to animate a sprite.

Koala should have two states:
a direction state: enum Direction {Left,Right};
a movement state. enum Movement { Idle, Walk };
As you have only one picture for the walking status, moving graphically the picture around will give the impression of a floating body. I'd recomment that you'd really have at least two walking positions to show that the foots are moving:
a movement step counter
a constant for the maximum number of steps.
Then the states should be updated in your game loop according to keyboard status and elapsed time. The pseudo code would be something like:
if (!arrow_key_pressed()) {
status_movement = Idle;
lasttimer = gametimer(); // keep track of last event
}
else {
status_movement = Walk;
if (left_arrow_pressed() )
status_direction = Left;
else if (right_arrow_pressed() )
status_direction = Right;
if (gametimer() - lasttimer > 2 ms ) { // if enough time,
if (status_direction==Left)
position_x -= step_increment;
else if (status_direction==Right)
position_x += step_increment;
movement_step = (movement_step+1) % maxi_steps;
lasttimer = gametimer();
}
}
All you have then to do is to restore te background of the picture at tis old position, and draw the picture at the position. For this, youd could call a function with paramters position_x, direction, movement status and status step, to return/draw the sprite at the right place.

Related

Efficient way to detect mouseover in SFML

I recently started to work on a 2D Tower Defense game in SFML, and I intend to put in several visual gimmicks and other functionalities that occur when the mouse hovers over certain objects (menu items, enemies, etc.). To that end, I have to constantly check whether the mouse is hovering over such an object, many of which may be moving around and have varying sizes and shapes. Does anyone know of a fast and efficient way to accomplish this?
A brute force method to solve this would be to simply check for every single object in the game world whether the mouse position intersects their bounding rectangle. My game is rather simple, so normally it would be overkill to optimize it here, but I also intend to implement more complex components elsewhere, and I wish to make sure the program wastes as little resources on the graphics as possible.
Beyond that, I've read a number of various solutions that might work, such as keeping track of objects in a grid/quadtree and only checking the area where the mouse is. There was also a solution through raycasting, but as far as I know, SFML itself doesn't have it built in. Since I assume I'm not the only one who had to work this out, I'm hoping there is some kind of solution for this that I missed. Any ideas?
Thanks in advance for helping out!
I'm also writing TD game right now, i started it this month using SFML too. that was also my problem last last day, and came up with this idea. i dont know if this is the standard way to do this but this is better than my first attempt of testing the entire game objects. and hoping to came up with better solution lol
i have 3 areas of my game window, which is:
MAP - the place where map,enemy is and where you build tower
SHOP - where you buy towers
INFORMATION - if you click enemy or tower or something, the information will appear in this area
then i wrote a Boundary class which defines the boundary of an area.
Example:
Boundary shopBoundary;
Boundary mapBoundary;
Boundary infoBoundary;
i can also add another Boundary if i want to add another area ( maybe area where i can click special buffs for tower? ) then i will just do this
Boundary buffsBoundary;
so this is how i do the trick
i created an enum which defines mouse location
enum AREAS { NONE, SHOP, MAP, INFO }
Areas mLoc = NONE;
i created a struct that stores an AREAS which will be use to name that area and a boundary object for the boundary of that area.
struct _Boundary
{
Areas area;
Boundary boundary;
bool isMouseInside(const sf::Vector2i v) const
{
return boundary.isMouseInside(v);
}
}
std::vector<_Boundary> boundaries; // now put all your boundary to a container
now everytime mouse move, i will only have to check where the mouse is using only 3 iteration ( for map, shop and information )
if ( mouse moved )
{
for ( int a = 0; a < boundaries.size(); a++ )
{
if ( boundaries[a].isMouseInside(mousePos) )
{
mLoc = boundaries[a].area;
break;
}
}
}
with that loop, i will be able to track where ever the mouse go by checking mLoc, by having to know the location while the clicked is occured it will narrow the game objects you need to check, (if mouse location is in shop area and then when clicked occured,check only the game objects on that area)
if ( mouse button pressed )
{
if ( click mouse left )
{
if ( mLoc == SHOP )
{
// the click has been occured in shop
// check the game objects relative to shop
}
else if ( mLoc == MAP )
{
// the click has been occured in map
// check the game objects relative to map
}
else if ( mLoc == INFO )
{
// the click has been occured in information
// check game objects relative to that area
}
}
}

Pygame: Character Centered Movement System (Diablo II like click-to-move)

I am currently working on a new RPG game using Pygame (my aim here is really to learn how to use object oriented programming). I started a few days ago and developed a movement system where the player clicks a location and the character sprite goes to that location and stops when it get's there by checking if the sprite 'collides' with the mouse position.
I quickly found however that this greatly limited the world size (to the app window size).
I started having a look into making a movement system where the background would move with respect to the player, hence providing the illusion of movement.
I managed to achieve this by creating a variable keeping track of my background map position. The map is much bigger than the app window. And each time I want my player to move I offset the background by the speed of the player in the opposite direction.
My next problem now is that I can't get my character to stop moving... because the character sprite never actually reaches the last position clicked by the mouse, since it is the background that is moving, not the character sprite.
I was thinking of spending some time coding in a variable that would keep track of how many displacements it would take the character sprite to reach the mouse clicked position if it was to move. Since the background moves at the character sprite's speed it would take as many displacement of the background in the x and y directions to center the clicked position on the background to the character sprite at the center of the screen.
It would be something like that:
If MOUSEBUTTON clicked:
NM = set number of moves needed to reach the clicked position based on character sprite distance to click and character sprite speed.
If NM != 0:
Move background image
Else:
pass
This would mean that when my background has moved enough for the character sprite to now be just over the area of the background that was originally clicked by the player, the movement would stop since NM == 0.
I guess that my question is: Does that sound like a good idea or will it be a nightmare to handle the movement of other sprites and collisions ? And are there better tools in Pygame to achieve this movement system ?
I could also maybe use a clock and work out how many seconds the movements would take.
I guess that ultimately the whole challenge is dealing with a fixed reference point and make everything move around it, both with respect to this fixed reference, but also to their own. e.g. If two other sprites move toward one another, and the character of the player also "moves" then the movement of the other two sprites will have to depend both on the position of the other sprite and also on the offset of the background caused by the movement of the player's character.
An interesting topic which has been frying my brain for a few nights !
Thank you for your suggestions !
You actually asking for an opinion on game design. The way I look at it, nothing is impossible so go ahead and try your coding. Also it would be wise to look around at similar projects scattered around the net. You may be able to pick up a lot of tips without re inventing the wheel. Here is a good place to start.
scrolling mini map

How to add a sprite that is always on the screen in Cocos2d?

I'm doing a platformer game using cocos2d-x v3 in c++, where the maps are usually very large, the visible screen follows the object through the map.
Let's say I want to show a sprite in the top right corner of the screen and it would be in this position even when the screen is following the object.
Using the object position doesn't do it.
Is there a way to show a sprite or whatever in the screen and it would be in the screen even when the screen is moving?
Ps. I'm super noob in game development
As it's written here, you whould use convertToWorldSpace
convertToWorldSpace converts on-node coords to SCREEN coordinates.convertToWorldSpace will always return SCREEN position of our sprite, might be very useful if you want to capture taps on your sprite but need to move/scale your layer.
Generally, the parent node call this method with the child node position, return the world’s postion of child’s as a result. It seems make no sense calling this method if the caller isn’t the parent…
So, as you can read,
Point point = node1->convertToWorldSpace(node2->getPosition());
the above code will convert the node2‘s coordinates to the coordinates on the screen.
For example if the anchor position of node1 is which will be the bottom left corner of the node1, but not necessarily on the screen. This will convert the position of the node2 which is to the screen coordinate of the point relative to node1 ).
Or if you wish, you can get position relative to scenes' anchor points with function convertToWorldSpaceAR.
So there are some assumptions that will have to be made to answer this question. I am assuming that you are using a Follow action on your layer that contains your map. Check here for example. Something like:
// If your playerNode is the node you want to follow, pass it to the create function.
auto cameraFollowAction = Follow:create(playerNode);
// running the action on the layer that has the game/map on it
mapLayer->runAction(cameraFollowAction);
The code above will cause the viewport to "move" to where the player is in world position. So following the player on your map that's bigger than the current viewport. What I did for my in-game menu/hud is add the Hud onto a different layer and add it to the root of the main game scene. The scene that does not have the follow action running on it. Something like below.
// Hud inherits from layer and has all the elements you need on it.
auto inGameHud = HudLayer::create();
// Add the map/game layer to the root of main game scene
this->addChild(mapLayer, 0);
// Add the hud to the root layer
this->addChild(inGameHud, 1);
The code above assumes 'this' to be your MainGameScene. This restricts the Follow action from scrolling the element off the screen. Your element will be on the screen no matter where in World space your scene currently is.
Let me know if this is clear enough. I can help you out more if you get stuck.
I've managed to do it using a Parallax Node, and using the velocity which the sprite goes to Vec2(0,0), this way it stays always on the same spot in the screen.
You can always just put that sprite into different node / layer that everything else is. That way moving this layer / node won't move the sprite

Cocos2D: CCPhysicsNode and child sprite move with different speed

I'm following the tutorial here to mimic Flappy Bird. At the part to scroll the game scene:
- (void)update:(CCTime)delta {
_hero.position = ccp(_hero.position.x + delta * scrollSpeed, _hero.position.y);
_physicsNode.position = ccp(_physicsNode.position.x - (scrollSpeed *delta), _physicsNode.position.y);
...
}
Ideally the whole world will scroll left, and _hero (which is a child node of _physicsNode) move right with the same speed it would stay still on the screen. But when I run the code on simulator the _hero sprite just blast off to the right at the speed of light (about 10~20 times faster than the scrolling speed of _physicsNode). The _physicsNode and every other things inside it is scrolling left at normal speed as intended.
If I don't give _hero any movement it would scroll along with _physicsNode normally.
I have tried other method like using CCAction at game start:
CCAction *moveAction = [CCActionMoveBy actionWithDuration:1 position:ccp(-scrollSpeed,0)];
CCActionRepeatForever *repeatAction = [CCActionRepeatForever actionWithAction:(CCActionInterval *)moveAction];
[_physicsNode runAction:repeatAction];
And still get the same result. The speed value that _hero receive is always different from the speed that _physicsNode receive.
Could anyone explain to me why this is happening and how to fix it?
I'm using cocos2d 3.3 if it helps.
I finally figured it out.
The _hero node had its positionType set to CCPositionTypeNormalized (because I was trying to center him on the screen) while the _physicNode has its positionType as CCPositionTypePoints. Any change to the node's position (including movement actions) are based on the node's positionType. The result is that when I move the _hero node by 2, it doesn't move 2 points but 2% of the parent node's width instead.
I fixed it by aligning the _hero on SpriteKit using CCPositionTypeNormalized, then switching it to CCPositionTypePoints at game start.

how to change the position of player using left and right button when the player is jumping?

Cocos2d offers two ways to let the player jump up, but by using jumpto() and jumpby(), people could not change the position of the sprite any more when it is jumping up.
How to write a method so that the sprite can jump like the "Super Mario"?
Some time ago I contributed some cocos2d code which made CCMove and CCJump actions stackable. See here. Starting from cocos2d 2.1, you can apply a CCJump actions concurrently with other movements.
However, if you want to deeply fine tune how the controls of your game feel, I'd avoid using CCActions altogether and I'd manage the sprite.position directly by processing player input.
you have to check for two condition for making your player to jump, same as in Super Mario.
Condition 1)
Only jump button is pressed at that time in CCJumpTo action you have to give the next position as the current position , height and no. jumps as one.
id jump = [CCJumpTo actionWithDuration:1 position:ccp(player.position.x, player.position.y)) height:20 jumps:1];
Condition 2)
When jump and forward button is pressed at that time in CCJumpTo action you have to give the next position as the current position.x + the distance you want to cover by jump,this will be static all the time , height and no. jumps as one.
id jump = [CCJumpTo actionWithDuration:1 position:ccp(player.position.x+20, player.position.y)) height:20 jumps:1];
And at the end you have to run jump action on player, hope you found this as solution for your question...!!