I am currently working on a demo, just to get to grips of how to make a game. It might turn into something in the future, but for now, it's just for learning.
My demo is, I guess, influenced by The Legend of Zelda. It has that top-down look that TLoZ has.
My sprite is a 32x32 pixel image, the demo runs at 60fps and I have already worked out how fast I want my sprite to animate using PyxelEdit. Each animation frame is being displayed every 170ms when my character walks. He moves 4 pixels every frame, so he is moving and animating at the speed I want him to.
The problem I have got is that I want my character to finish the animation loop when my key has been released and he won't. When I have released a movement key, he will sometimes stop on the wrong animation frame, like say his left or right foot is forward when I want him to be still. I'm just not sure how to do it. I've tried checking the animation count when the Event::KeyReleased event occurs and incrementing the animation count until it reaches a certain number so that it stops on say the number 1 so he's standing still, it just doesn't work.
I don't think this requires a look at my code, just need a general idea on how to go about making sure that when the a movement key is released, animate him until he is on frame 1 and move him a certain amount of pixels each time until he stops.
You could use a FSM so something along the lines of.
// Visual states of the character.
enum class State { WALKING, STANDING, ATTACK, };
State character_state = State::STANDING;
// Change on input (or other things like impact.)
if(input.up() || input.down() || input.left() || input.right)
character_state = State::WALKING;
else
character_state = State::STANDING;
// Render based on the current state.
switch(character_state)
{
case(State::WALKING):
render(cycle_walk_animation(frame_time));
break;
case(State::STANDING):
render(standing_still_frame());
break;
}
I've done this with 2D and 3D.
If I understand correctly, you need something like this:
// The game loop
while (game_running)
{
// ...
// Your code
// ...
// Advance the animation while moving, or if not, cycle through
// the animation frames until frame 1 is reached
if (keyPressed(somekey) || currentAnimationFrame != 1)
{
advanceAnimationFrame();
}
// ...
// Your code
// ...
}
Of course, this is not SFML code, but it should get the general idea across
Related
I'm a beginning CS student and would love for some help checking REALLY SIMPLY pseudo-code.
Here is the problem:
Write an algorithm for playing a robotic version of the "treasure hunt" game. The game involves robots receiving clues that guide them to other clues until they eventually reach a "treasure".
Clues are represented by colors of tiles and each clue just requires the robot to move one tile in a direction (left, right, forward). After making a move, the robot re-examines the color of the tile it is standing on to figure out the next move, etc.
The rules for the tile colors are:
White tile = next clue is the tile directly in front of the robot
Blue tile = next clue is the tile to the robot's left
Green tile = next clue is the tile to the robot's right
Black tile = robot moves back TWO tiles then re-examines clues based on its new heading
Yellow tile = treasure and game is over
The algorithm rules:
The robot can only move forward, turn left, or turn right
The robot is able to read the color of the tile it is standing on
Here is my pseudo-code:
//assign movements and actions to variables
whiteTile = step forward one space
blueTile = turn left and step forward one space
greenTile = turn right and step forward one space
blackTile = step backwards two spaces without changing directions
yellowTile = treasure found and game over
tileColor = check color of tile
//initiate while loop to run continously until robot reaches yellow tile
While tile under feet does not equal yellowTile
// initiates the movements of the robot to start if loop
Check color of tile
// this if loop should run continously as long as tileColor isn’t yellow
if tile color does not equal yellowTile
output(tileColor)
check color of tile
// once robot is on top of yellow tile, it exits the while loop and game is over
output “Game over, you win!”
I know this is a few weeks old but came across this now as I am new here as well.
I am not sure why you are declaring those variables in that way. I understand that those were the conditions/rules given but they would have to be translated into actual evaluations and actions.
So within a new function, output() since that's what you're using in the WHILE loop, you would actually have IF statements taking tileColor and executing the movements accordingly.
BEGIN output
IF tileColor = white THEN
CALL moveForward
ELSE IF tileColor = blue THEN
CALL moveLeft
..
.
.
Assuming there's another function for the movements.
And looking at the WHILE loop, isn't the IF redundant? The while loop is already checking the same condition of the tileColor not yellow. And the tileColor hasn't been checked before entering the WHILE loop.
//initialize first and check for case of robot spawning on yellow
tileColor = checkTileColor
WHILE NOT(tileColor = yellow)
CALL output(tileColor)
tileColor = checkTileColor
END WHILE
DISPLAY "You win"
This is assuming you would have different functions where output would take the tileColor and move accordingly. And also checkTileColor being another function that checks the actual tile colors and returns a value (color).
I'm not an expert as I'm a student as well but I have been looking around and this is something I thought I could actually answer.
Im using SFML 2.1 for graphics and my game structure follows SFML book quite closely (SceneGraph implementation etc)
My world consists mostly of characters (around 1-400, moving around) and tiles (3600, stationary) and I'll check for collisions everytime something moves
In worst case scenario with ~400 characters moving around and ~3600 tiles, I have 4000 possible entities with collision and 800 collision check calls (separate X and Y movement) each frame -> 3.2M collision checks in total.
Almost all my entities have size of 16x16 pixels and I've been looking into implementing either quadtree or simpler grid for collision detection, which should bring number of collision checks down quite a bit. By grid I mean http://conkerjo.wordpress.com/2009/06/13/spatial-hashing-implementation-for-fast-2d-collisions/
But I have no idea how I should implement simple grid for example. All help is welcome. There's propably even a lot better ways to bruteforce this.
Entity update step.
I do X/Y-axis movement separately. Because I want to slide against entities when colliding diagonally.
Move entity horizontally
Check and handle collisions
Move entity vertically
Check and handle collisions
Repeat 1-4 for all entities
.
void Entity::updateCurrent(sf::Time dt, CommandQueue& commands)
{
setPreviousPosition(getPosition());
move(sf::Vector2f(mVelocity.x, 0) * dt.asSeconds());
handleCollision();
setPreviousPosition(getPosition());
move(sf::Vector2f(0, mVelocity.y) * dt.asSeconds());
handleCollision();
}
I've had the following problem before when I tried to handle both X and Y movement at the same time:
I had no idea if I should reset X or Y position after collision.
Collision handling.
I'll handle collisions only when entities are moving (currently only character entities, later projectiles and some special tiles)
if entity is tile -> do nothing
if entity is character -> check collisions with characters and tiles and reset movement if collision happened
.
void Entity::handleCollision()
{
if (getCategory() & Category::Tile)
return;
if (getCategory() & Category::Character)
{
std::set<SceneNode::Pair> collisionPairs;
checkCollision(*mSceneGraph, collisionPairs);
for (SceneNode::Pair pair : collisionPairs)
{
if (matchesCategories(pair, Category::Character, Category::NonPassableCharacterOrTile))
{
resetPreviousPosition();
break;
}
}
}
}
I'll check collision simply by using SFML's intersects-function. This is propably good enough for this?
bool collision(const SceneNode& l, const SceneNode& r)
{
return l.getBoundingRect().intersects(r.getBoundingRect());
}
If I were to implement grid or quadtree for collision detection, when should I populate it, when update? Should I update it every time I move one entity, or should I try to come up with a way to move all entities at once, then build grid/quadtree and only after that try to handle all collisions.
So my questions are: (1) In this scenario how and when should I do collision handling? My current implementation works, but I think I do it too often and all examples I looked into grids/quadtrees assumed that I do first all movement and do collision detection and handling after.
and (2) When do I clear/populate/update my grid/quadtree. For example if I have 3600 tiles and 3 moving characters. Should I seek for entity each time one moves in the grid and try to move it to different grid cell / tree branch?
Edit:
What I'll propably try next unless anyone gives better advice
Updated update step.
Is this smart or in anyway reasonable way to do this?
Remove entity from grid/quadtree
Move entity horizontally
Add entity to grid/quadtree
Check and handle collisions
Remove entity from grid/quadtree
Move entity vertically
Add entity to grid/quadtree
Check and handle collisions
Repeat 1-8 for all entities
.
Entity::move()
{
grid.getCell(getPosition()).remove(this);
... move x
grid.getCell(getPosition()).add(this);
... if collision, reset x
grid.getCell(getPosition()).remove(this);
... move y
grid.getCell(getPosition()).add(this);
... if collision, reset y
}
Entity::checkCollision()
{
list<Entity*> possibleColliders;
possibleColliders = grid.getEntitiesInRectangle(x - s, y - s, x + s, y + s);
... now only check collision against possibleColliders
}
I think a quadtree would work quite well and since it will be standalone there's really no issue in adding it into your current system.
The important question you've ask is probably, when to populate and update the quadtree. I think this largely depends on your use case. Since you have around 400 characters that can change position for each frame, it probably wouldn't make a lot of difference if you try to move the nodes in the quadtree or if you fully rebuild the quadtree. Which is really more performant depends on your algorithm and datastructure, which would need some performance testing.
In this tutorial, they also suggest to rebuild the quadtree every frame iteration.
For the "how to fix collision handling" you'll need to provide more information/a separate SO question, since it's not that clear what the issue is.
I want to move a 2d circle in opengl automatically with constant speed on load and then control it with keyboard to move smoothly.
Right now i have the code to move the circle with keyboard, but it is moving only one unit for every keypress.
I want a smooth movement when keypress and automatic movement when on load.
Use glTranslatef to move your object, or alternatively you can just adjust its position x,y,z by a set amount in each update cycle when the keyboard keys are pressed.
E.g
const float MOVE_AMOUNT = 5.0;
public void Update()
{
if (Keyboard.IsKeyDown("a"))
circle.position.x -= MOVE_AMOUNT;
else if (Keyboard.IsKeyDown("d"))
circle.position.y += MOVE_AMOUNT;
}
NOTE: this is not valid C++ syntax, but it gives the overall logic of what you need to be doing, you should be able to figure it out from this. If you want a glTranslate example please let me know.
I have a CCSprite object of which I need to update the on screen (x,y) position as quickly as possible. It is an augmented reality app so the on screen position needs to appear fixed to a real world location.
Currently, during each update I check the heading and attitude of the device then move the sprite accordingly by determining the new x and y positions
[spriteObject setPosition:ccp(newX, newY)];
Each degree change in heading corresponds to 10 pixels in on screen position, so by setting the position this way the sprite jumps around in intervals of 10 pixels which looks stupid. I'd like to animate it smoothly, maybe by using
[spriteObject runAction:[CCMoveTo actionWithDuration:0.2f position:ccp(newX, newY)]];
but the problem here is that a new position update comes in while the sprite is animating and it sort of screws the whole thing up. Anyone know of a nice solution to this problem? Any help is much appreciated as I've tried numerous failed solutions to this point.
You can try to just animate your sprite movement to the point. I mean, you can several times during one second run animated position correction with duration of 1/numberOfUpdates in one second. Something like
- (void) onEnter
{
[super onEnter];
[self schedule:#selector(updatePositionAnimated) interval:0.2f];
}
- (void) updatePositionAnimated
{
[spriteObject runAction:[CCMoveTo actionWithDuration:0.2f position:ccp(newX, newY)]];
}
I suppose, you will have smooth enough animation in this case
I have recently been getting into OpenGL/SDL and playing around with objects in 2D/3D Space and as i'm sure most newbies to this area do, have a few queries, about the 'best' way to do something. I quote best, because i'm assuming there isn't a best way, it's personal preference.
So, I have an entity, a simple GL_QUAD, which I want to move around. I have keyboard events setup, i can get the keypress/release events, not a problem.
I have an entity class, which is my GL_QUAD, pseudo implementation....
class Entity
{
void SetVelocity(float x, float y);
}
I then have this event handler code...
if theEvent.Key = UPARROW AND theEvent.State = PRESSED
Entity.SetVelocity(0.0f, -1.0f);
else if theEvent.Key = UPARROW AND theEvent.State = RELEASED
Entity.SetVelocity(0.0f, 0.0f);
My question is, is this the best way to move my entity? This has led me to thinking that we could make it a little more complex, by having a method for adjusting the X/Y Velocity, seperately. As SetVelocity would forget me X velocity if i started moving left? So i could never travel diagonally.
For Example...
class Entity
{
void SetXVelocity(float x);
void SetYVelocity(float y);
}
if theEvent.Key = UPARROW AND theEvent.State = PRESSED
Entity.SetYVelocity(-1.0f);
else if theEvent.Key = UPARROW AND theEvent.State = RELEASED
Entity.SetYVelocity(0.0f);
if theEvent.Key = LEFTARROW AND theEvent.State = PRESSED
Entity.SetXVelocity(-1.0f);
else if theEvent.Key = LEFTARROW AND theEvent.State = RELEASED
Entity.SetXVelocity(0.0f);
This way, if I have an XVelocity and I then press the UPARROW, I will still have my XVelocity, as well as a new YVelocity, thus moving diagonally.
Is there a better way? Am I missing something very simple here?
I am using SDL 1.2, OpenGL, C++. Not sure if there is something in SDL/OpenGL which would help?
Thanks in advance for your answers.
The question is really general since it depends on how you want to model the movement of your objects in your world.
Usually every object has its velocity which is calculated basing on an acceleration and capped to a maximum. This means that a key press alters the acceleration of the object for the specified frame which is then calculated and applied to the current velocity of the object.
This is done through an update phase which goes through all the objects and calculates the velocity change according to the object acceleration. In this way you don't bother to modify the velocity itself but you let your engine to do its calculations depending on the state of every object..
acceleration is applied over a period of time, so in the example by #jack, you would apply an acceleration 10m/s^2 over a time period of one second.
you should also modify your application to make it time based, not frame based.
have a look at this basic game physics introduction, and I would also really have a look at the GameDev.net Physics Tutorials
I assume the way you want movement to work is that you want the player to move only when a key is held.
In short: your solution is fine.
Some potential gotchas to take consideration of: What happens if both left and right is pressed?
Well, what you describe here is a simple finite state machine. You have the different directions in which you can move (plus no movement at all) as the states, and the key-events as transitions. This can usually be implemented quite well using the state pattern, but this is often quite painful in C++ (lots of boilerplate code), and might be over the top for your scenario.
There are of course other ways to represent speed and direction of your entity, e.g. as a 2D-vector (where the length gives the speed). This would enable you to easily represent arbitrary directions and velocities.