Jump to content
  • Advertisement

smokyturbo

Member
  • Content Count

    12
  • Joined

  • Last visited

Community Reputation

149 Neutral

About smokyturbo

  • Rank
    Member

Personal Information

  • Interests
    Art
    Design
    Programming
  1. Cheers for that, a very interesting read. I definitely think (a) state machine(s) are looking promising. I've started off with a simple one. I wasn't sure how things that happen outside of user input would work alongside a state machine, so for now I've just hooked the state machine into the event bus so it can receive events from other parts of the game code. So for example, when the collision system detects than the player has landed on a platform, it sends a "landed" event which the state machine picks up. The "falling" state responds to this event and transitions the player into either an idle or running state after it checks the current keys pressed. One thing I've noticed is that currently I have "LeftRunning" and "RightRunning" states, which obviously share nearly identical code, just with the directions reversed. I'm not sure yet whether to create a single "Running" state and parameter-ise it with a direction or not.
  2. Hi all, I'm having a bit of trouble working out how to handle transitioning from one player state to another using an ECS, particularly with respect to determine the next animation to play. For example, some of my current approach includes logic such as: -> input system processes key down (left) -> raises "intent event (left)" -> intent system sets player vel.x -> raises "started moving (left)" event -> animation system plays appropriate animation Now I have introduced jumping/falling, I'm not sure how to handle situations like the following: In the collision system: Player lands on ground, should we play the running animation or the idle animation? Depends on whether left/right input is held (which only the input system knows about). Or we could look at the player's x acceleration (but this doesn't necessarily mean left/right input is down, it could be due to some other force). Do I raise an event to tell the input system the player has landed which then checks the current input state? Do I need some sort of player state enum (within a state component?). Is there a corresponding state system, or is it up to all the other systems to update this as necessary? Then there's situations such as when the player finishes firing a gun, should we change to running or idle animation? What drives this change, the animation system when the "fire" animation finishes? All advice welcome as always, Thanks
  3. Good point, no point forcing things if they don't fit. I think I'll start by having something within the interaction component which performs the logic. Yeah this makes sense. I'm looking to update the keyboard code so that it sends "requests" for an actor, like, ReqInteraction, ReqAttack etc. This way when I come to work on the AI system, it can emit similar commands that the other systems can consume without knowing whether they came from the player or any other entity. Yeah that makes a lot of sense. I think that's what I was kind of heading towards with my second code example, but I wasn't quite sure. I'll definitely try this inverse-logic approach. I don't really know how to use scripts within games at the moment, so I think I'll code some classes instead for know and have my interaction component have a pointer to an instance, a bit like a hard coded example of your handle & script approach. Thanks both for the advice, it's really helped.
  4. Hi all, I'm having some trouble working out how to handle entities which can be interacted with by other entities (typically the player). A couple of examples I'm trying to implement first are: - Doors - Item containers (e.g. chest) InputSystem ----------- OnKeyDown(key) if key == "interact" interactableEntity = FindCollidingInteractable(player) // check all nearby entities in scene with an "Interactable" component? interactionComp = interactableEntity.Get<InteractionComponent>(); // What now? How can interactionComp hold all data for all possible interactions? If it's a door, we need to know if it's locked and what the required key is if so, as well as which room we teleport to once opened (Resident Evil style). If it's a chest, it might have similar "lock" requirements as the door, as well as an inventory (InventoryComponent?) of items to transfer to the player. I can image how this would work using interfaces & polymorphism: class InteractionHandler { void HandleInteraction(Entity instigator, Entity target); } class DoorInteractionHandler : InteractionHandler { void HandleInteraction(Entity instigator, Entity target) { if (requiredItem != null && instigator.Get<InventoryComponent>().HasItem(requiredItem)) { instigator.Get<InventoryComponent>().Remove(requiredItem); requiredItem = null; LoadStage(nextStage); } else { // Door is not locked. LoadStage(nextStage); } } string requiredItem; string nextStage; } Where the InteractionComponent could hold a pointer to an instance of InteractionHandler and just call HandleInteraction blindly. I understand however that components are not meant to contain any logic in a pure ECS, so how would we represent the interaction requirements on the entity? I thought that maybe I need more components, such as a LockComponent, DoorComponent etc, but then how would this fit in with the keyboard handling code and where would the logic for acting on these go? Very confused, so any advice appreciated. Thanks!
  5. Thanks for the ideas chaps, I'll see what I can come up with.
  6. Hi all,   I have adopted a simple FSM to represent my game states [SplashState, MenuState, GameplayState etc]. I would like to introduce some basic transitions when transitioning from one to another (fade in/out to start with). I'm having trouble envisioning how this might work. My first thought was to have a TransitionState, but something about this doesn't fit quite right with me - maybe because the transition doesn't really seem like a state in the same way that the menu and gameplay states are. Platforms such as iOS for example seem to have a distinction between different screens and screen transitions. Regardless I'm still not sure on the best way to keep track of the current state, the next state and the transition between them. I've posted my state machine code below to show what I have so far. Any input at all would be appreciated as always, cheers.     States interface: class State { public: virtual StateType type() = 0; virtual void load(Game* game) = 0; virtual void unload(Game* game) = 0; virtual void onKeyDown(SDL_Keycode key) = 0; virtual void onKeyUp(SDL_Keycode key) = 0; virtual void update(long deltaTime) = 0; virtual void interpolate(float alpha) = 0; virtual void draw(long deltaTime) = 0; }; Guts of the state machine: void StateManager::setState(StateType state) { mNextState = state; } void StateManager::sync(Game* game) { if (!mCurrentState || mCurrentState->type() != mNextState) { clearCurrentState(game); mCurrentState = mStateFactory->create(mNextState); mCurrentState->load(game); } } void StateManager::onKeyDown(SDL_Keycode key) { mCurrentState->onKeyDown(key); } void StateManager::onKeyUp(SDL_Keycode key) { mCurrentState->onKeyUp(key); } void StateManager::update(long deltaTime) { mCurrentState->update(deltaTime); } void StateManager::interpolate(float alpha) { mCurrentState->interpolate(alpha); } void StateManager::draw(long deltaTime) { mCurrentState->draw(deltaTime); } void StateManager::clearCurrentState(Game* game) { if (mCurrentState) { mCurrentState->unload(game); delete mCurrentState; mCurrentState = nullptr; } }
  7. Hi,   I'm trying to use an entity system for my game and I'm struggling to work out how collision detection/response should work. The game is a top down adventure game (think Zelda).   My entities are data only, whilst systems provide the logic for entities with the relevant components.   To start with I just want the player, some NPCs which wander about and some projectiles which the player can fire. I also have a tile map.   How could I deal with the various collision responses that are required?   When a player collides with an NPC, they should be translated apart so they no longer overlap. When a projectile collides with an NPC the NPC should take damage and when it hits a wall it should just vanish.   How can I best represent how each entity should behave when it collides with the other types of entities?   // Creating player Entity* entity = new Entity; entity->add(new PositionComponent) entity->add(new VelocityComponent) entity->add(new CollisionComponent) ... class CollisionComponent { // ??? }  
  8. Thanks for the advice chaps.     I've coded up a prototype in this vein and it definitely looks like the way to go. My sprites are now completely dumb, whilst all animations are managed by a dedicated animation system. This will allow me to do more complex things like chain animations together, cancel running animations etc, so cheers for that!
  9. Hi all, I'm attempting a game using a similar architecture found in the GCC book. I have a GameLogic class and View class. The logic contains the rules for updating the game universe whilst the view is a visual representation of the game world.   The logic notifies the view of any updates it may be interested in via an event manager.   One such event is the 'EventEntityCreate' which describes how the new entity should be displayed. Obviously sprites can either be a single, static frame or an animated sequence of frames. I'm not sure how best to embed this information in the event. I'm struggling to come up with an appropriate object that can represent this information. Maybe a static sprite and animated sprite are too different to be represented by a single object?   Dubiously named class attempts include "SpriteData", "SpriteFrames" etc. The data needed to describe an animation also includes fps, whether the animation loops or not etc, which don't make sense to be present for a static sprite. Any advice on how you would tackle this would be much appreciated.
  10. Thanks for your suggestions.   I've tried using Window's HPC and I think it's improved it a bit. How much stutter would you say is inherent to 2D games? I've tried out a few 2D PC games and I can see some minor stuttering in them too at times.   I'm not sure if I've made a genuine programming error or whether I'm just too sensitive to it! 
  11. Thanks for your reply!     It knocks out 80+fps when vsync is off so unfortunately I don't think that's the issue. The stutter is also reproducible with only a single background quad :(.
  12. Hi all, this is my first post as a member of this forum.   I'm playing around with SDL trying to get a smooth game loop implementation working. I've attempted the fixed timestep approach as described here: http://gafferongames.com/game-physics/fix-your-timestep/.   I'm having trouble with stuttering and I'm not sure how to proceed to work out what's wrong. The update function appears to be running at the correct rate and I have tried to interpolate the remaining time in the accumulator when rendering the scene. MingW SDL 2 Windows 7 64 Intel integrated graphics Stuttering occurs in both windowed and full screen and with vsync on and off (it's significantly worse with vsync off).  When moving around the screen using the arrow keys, the background can be seen to stutter regularly.   Any help with this would be much appreciated. Any examples of smooth game loops would also be appreciated.   #include <SDL.h> const int SCREEN_WIDTH = 600; const int SCREEN_HEIGHT = 480; const Uint32 TIMESTEP = 16; const int SPRITE_SIZE = 64; const double SPRITE_VELOCITY = 300 / 1000.0; double gPosX = 0.0; double gPosY = 0.0; double gPrevPosX = 0.0; double gPrevPosY = 0.0; double gVelocityX = 0.0; double gVelocityY = 0.0; SDL_Renderer* gRenderer = NULL; void handleInput() { const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL); gVelocityX = 0.0; gVelocityY = 0.0; bool leftKeyPressed = currentKeyStates[SDL_SCANCODE_LEFT]; bool rightKeyPressed = currentKeyStates[SDL_SCANCODE_RIGHT]; bool upKeyPressed = currentKeyStates[SDL_SCANCODE_UP]; bool downKeyPressed = currentKeyStates[SDL_SCANCODE_DOWN]; if(leftKeyPressed && !rightKeyPressed) { gVelocityX = - SPRITE_VELOCITY; } else if(!leftKeyPressed && rightKeyPressed) { gVelocityX = SPRITE_VELOCITY; } if(upKeyPressed && !downKeyPressed) { gVelocityY = - SPRITE_VELOCITY; } else if(!upKeyPressed && downKeyPressed) { gVelocityY = SPRITE_VELOCITY; } } void update(const Uint32 timestep) { gPrevPosX = gPosX; gPrevPosY = gPosY; gPosX += gVelocityX * timestep; gPosY += gVelocityY * timestep; } void render(SDL_Point& spritePos) { SDL_SetRenderDrawColor(gRenderer, 0x33, 0x33, 0x33, 0xFF); SDL_RenderClear(gRenderer); // Draw background SDL_SetRenderDrawColor(gRenderer, 0x00, 0x80, 0x80, 0xFF); bool iEven = true; bool jEven = true; for (int i=0; i<100; i++) { for (int j=0; j<100; j++) { if (iEven != jEven) { SDL_Rect fillRect = { i * SPRITE_SIZE - spritePos.x, j * SPRITE_SIZE - spritePos.y, SPRITE_SIZE, SPRITE_SIZE }; SDL_RenderFillRect(gRenderer, &fillRect); } jEven = !jEven; } iEven = !iEven; } // Draw pink square SDL_SetRenderDrawColor(gRenderer, 0xCC, 0xAA, 0xCC, 0xFF); SDL_Rect fillRect = { SCREEN_WIDTH / 2.0f - SPRITE_SIZE / 2.0f, SCREEN_HEIGHT / 2.0f - SPRITE_SIZE / 2.0f, SPRITE_SIZE, SPRITE_SIZE }; SDL_RenderFillRect(gRenderer, &fillRect); SDL_RenderPresent(gRenderer); } int main(int argc, char* args[]) { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("Game Loop", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, 0); gRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); bool quit = false; Uint32 accumulator = 0; Uint32 previousTime = 0; while (!quit) { SDL_Event e; while(SDL_PollEvent(&e)) { if(SDL_QUIT == e.type) { quit = true; } } Uint32 currentTime = SDL_GetTicks(); Uint32 elapsedTime = currentTime - previousTime; previousTime = currentTime; accumulator += elapsedTime; while (accumulator >= TIMESTEP) { accumulator -= TIMESTEP; handleInput(); update(TIMESTEP); } float alpha = (float) accumulator / TIMESTEP; SDL_Point spritePos = { gPosX * alpha + gPrevPosX * (1 - alpha), gPosY * alpha + gPrevPosY * (1 - alpha) }; render(spritePos); } SDL_DestroyRenderer(gRenderer); SDL_DestroyWindow(window); SDL_Quit(); }
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!