Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Forums

OverviewFelgo 1 Support › Urgent! After-Image at previous position when switching sprite sequence

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #5958

    Pi

    Hi,

     

    I am using a Timer in my Entity to apply liner when key is pressed for movement. This also switches the sprite sequence between ‘walking’ and ‘standing’

    It works fine but when key is released and the goalsprite is changed to standing from walking to standing, for a fraction of a second there is like an after-image at the position from where the character originally started walking. How can i get rid of this, it’s making the game look glitchy.

     

    Code:

    TwoAxisController {
    id: twoAxisController
    onInputActionPressed: keypress(actionName);
    inputActionsToKeyCode: {
    "up": Qt.Key_Up,
    "down": Qt.Key_Down,
    "left": Qt.Key_Left,
    "right": Qt.Key_Right,
    "fire": Qt.Key_Space
    }
    onXAxisChanged: {
    console.debug("xAxis changed to", xAxis)
    if(xAxis>0)
    __isLookingRight = true;
    else if(xAxis<0)
    __isLookingRight = false;
    }
    
    }
    
    Timer {
    id: updateTimer
    interval: 60
    running: true
    repeat: true
    onTriggered: {
    var xAxis = controller.xAxis;
    if(xAxis) {
    collider.body.linearVelocity.x = xAxis*rightValue;
    sprite.goalSprite="walking";
    }else{
    sprite.goalSprite="standing";
    }
    }
    }
    #5959

    Christian
    Felgo Team

    Hi Pi,

    can you try if the problem still exists when you are using the daily build version of Felgo? To enable it, go to your .pro file and write

    CONFIG += v-play_daily

    Then run qmake, clean and build your project again.

     

    If you problem still exists, you could try calling updateItemPositionAndRotationImmediately() on your entity.

    Cheers, Chris

    #5960

    Pi

    Hi Chris,

     

    Thanks for the quick reply.

    I tried both your suggestions but the problem still persists.

    The after-image comes exactly at the position from where character started walking. I’m using a spritesequencefromfile

     

    Any other ideas?

    #5961

    Christian
    Felgo Team

    Hi Pi,

    could you please post a complete example, which I can then use to reproduce your problem?

    As another workaround, you could try to use a second SpriteSequeneFromFile and switching its visibility on and off, based on the state your entity is in (walking or standing).

    Cheers, Chris

    #5976

    Pi

    Hi Chris,

    Can’t seem to fix this after-image issue

    Here is how you can reproduce the problem:

    (I can mail you my sprite sheets)

    Create a new project using V-play Game template

    Add entity in entities folder Mard.qml

    import QtQuick 1.1
    import Box2D 1.0
    import VPlay 1.0
    
    EntityBase {
        id: mard
        entityType: "mard"
    
        property int health: 100
        signal mardkapunch
    
        signal died
    
    
        property int score: 0
    
        property alias controller: twoAxisController
    
        property real rightValue: 45
    
        property bool __isRunning: false
        property bool __isStanding: true
        property bool __isPunching: false
        property bool __isFlinching: false
        property bool __isLookingRight: true
    
    
        BoxCollider {
    
            id: collider
            categories: Box.Category2
            collidesWith: Box.Category1 | Box.Category4 | Box.Category5
            bodyType: Body.Dynamic
            fixedRotation: true
    
            // balancing settings:
            linearDamping: 5.0
            // set friction between 0 and 1
            friction: 0.6
            // restitution is bounciness - dont bounce, because then the state would be changed too often
            restitution: 0
    
            density: 8
    
            sleepingAllowed: false
    
            anchors.centerIn: parent
            width: 75
            height: 92
            fixture.onBeginContact: {
                // play the collision sound when the box collides with anything, but not if the sound is already playing
                if(gameScene.collisionSoundsEnabled && !collisionSound.playing)
                    collisionSound.play();
    
                collisionParticleEffect.start();
    
                var component = other.parent.parent;
                var collidingType = component.owningEntity.entityType;
    
                if(collidingType === "metromen" && !__isPunching) {
                    health = health-10
                    updatesprite("flinch");
                }
                if(health < 1){
                    died();
                }
            }
    
        }
    
    
        TwoAxisController {
          id: twoAxisController
          onInputActionPressed: keypress(actionName);
          inputActionsToKeyCode: {
                         "up": Qt.Key_Up,
                         "down": Qt.Key_Down,
                         "left": Qt.Key_Left,
                         "right": Qt.Key_Right,
                         "fire": Qt.Key_Space
                         }
          onXAxisChanged: {
            console.debug("xAxis changed to", xAxis)
            if(xAxis>0)
              __isLookingRight = true;
            else if(xAxis<0)
              __isLookingRight = false;
          }
        }
    
    
    
        Timer {
          id: updateTimer
          interval: 60
          running: true
          repeat: true
          onTriggered: {
            // this must be done every frame, because the linearVelocity gets reduced because of the damping!
            var xAxis = controller.xAxis;
            if(xAxis) {
              collider.body.linearVelocity.x = xAxis*rightValue;
                updatesprite("walk")
    
            }else{
                collider.body.linearVelocity.x = 0
                updateItemPositionAndRotationImmediately();
                updatesprite("stand")
    
            }
    
          }
        }
    
    
        SpriteSequenceFromFile {
            id: sprite
           filename: "../img/mard-hd.json"
    
           Sprite {
               name:"standing"
               frameNames: [
                 "character_hero_rig20001.png"
               ]
               frameRate: 1
               mirrorX: !__isLookingRight
             }
    
           Sprite {
               name:"walking"
               frameNames: [
                 "character_hero_rig20001.png","character_hero_rig20002.png","character_hero_rig20003.png","character_hero_rig20004.png",
                 "character_hero_rig20005.png","character_hero_rig20006.png","character_hero_rig20007.png","character_hero_rig20008.png",
                 "character_hero_rig20009.png","character_hero_rig20010.png","character_hero_rig20011.png","character_hero_rig20012.png",
                 "character_hero_rig20013.png","character_hero_rig20014.png","character_hero_rig20015.png","character_hero_rig20016.png",
                 "character_hero_rig20017.png","character_hero_rig20018.png","character_hero_rig20019.png","character_hero_rig20020.png",
                 "character_hero_rig20021.png","character_hero_rig20022.png","character_hero_rig20023.png","character_hero_rig20024.png",
                 "character_hero_rig20025.png","character_hero_rig20026.png","character_hero_rig20027.png","character_hero_rig20028.png",
                 "character_hero_rig20029.png","character_hero_rig20030.png","character_hero_rig20031.png","character_hero_rig20032.png"
               ]
               frameRate: 26
               mirrorX: !__isLookingRight
             }
    
           Sprite {
               name:"hit"
               frameNames: [
                 "character_hero_rig20034.png","character_hero_rig20035.png","character_hero_rig20036.png","character_hero_rig20037.png",
                 "character_hero_rig20038.png","character_hero_rig20039.png","character_hero_rig20040.png","character_hero_rig20041.png",
                 "character_hero_rig20042.png","character_hero_rig20043.png","character_hero_rig20044.png","character_hero_rig20045.png",
                 "character_hero_rig20046.png","character_hero_rig20047.png","character_hero_rig20048.png","character_hero_rig20049.png"
               ]
               frameRate: 17
               mirrorX: !__isLookingRight
             }
    
    
        Sprite {
            name:"punching"
            frameNames: [
              "character_hero_rig20051.png","character_hero_rig20052.png","character_hero_rig20053.png","character_hero_rig20054.png",
              "character_hero_rig20055.png","character_hero_rig20056.png","character_hero_rig20057.png","character_hero_rig20058.png",
              "character_hero_rig20059.png","character_hero_rig20060.png","character_hero_rig20061.png","character_hero_rig20062.png",
              "character_hero_rig20063.png","character_hero_rig20064.png","character_hero_rig20001.png","character_hero_rig20001.png",
              "character_hero_rig20001.png","character_hero_rig20001.png","character_hero_rig20001.png","character_hero_rig20001.png",
              "character_hero_rig20001.png","character_hero_rig20001.png","character_hero_rig20001.png"
            ]
    
            frameRate: 30
            mirrorX: !__isLookingRight
            loop: false
            to: "standing"
          }
      }
    
        // gets played at a collision
        Sound {
            id: smack
            source: "../snd/yeh kha.wav"
        }
    
    
        // this particle effect is played when colliding with an obstacle
        Particle {
            id: collisionParticleEffect
            positionType: ParticleSystem.Free
            //fileName: "SmokeParticle.json"
        }
    
    
        function keypress(actionName)
        {
            if(actionName==="fire" && !__isFlinching && !__isPunching){
                mardkapunch();
                updatesprite("punch");
                smack.play();
            }
        }
    
        states: [
          State {
            name: "stand"
            PropertyChanges { target: sprite; goalSprite: standing }
          },
          State {
            name: "walk"
            PropertyChanges { target: sprite; goalSprite: walking }
          },
          State {
            name: "punch"
            PropertyChanges { target: sprite; goalSprite: walking }
          }
        ]
    
        Timer {
          id: changestate
          interval: 800
          running: false
          repeat: false
          onTriggered: {
              __isPunching = "false";
              __isFlinching = "false";
              __isStanding = "true";
              __isRunning = "false";
          }
        }
    
    
        Timer {
          id: smooth
          interval: 5
          running: true
          repeat: true
          onTriggered: {
              mard.updateItemPositionAndRotationImmediately();
    
          }
        }
    
        function updatesprite(state)
        {
            
            if(!__isPunching && !__isFlinching)
            {
                if(state==="stand")
                {
                    __isPunching = "false";
                    __isFlinching = "false";
                    __isStanding = "true";
                    __isRunning = "false";
    
                    sprite.goalSprite="standing";
    
                }
                else if(state==="punch")
                {
                    __isPunching = "true";
                    __isFlinching = "false";
                    __isStanding = "false";
                    __isRunning = "false";
    
                    sprite.goalSprite="punching";
                    changestate.start();
                }
                else if(state==="flinch")
                {
                    __isPunching = "false";
                    __isFlinching = "true";
                    __isStanding = "false";
                    __isRunning = "false";
    
                    sprite.goalSprite="hit";
                    changestate.start();
                }
                else if(state==="walk")
                {
                    __isPunching = "false";
                    __isFlinching = "false";
                    __isStanding = "false";
                    __isRunning = "true";
    
                    sprite.goalSprite="walking";
                }
            }
        }
    
    }
    

     

    VPlayGameTemplateScene.qml

    import QtQuick 1.1
    import VPlay 1.0
    import Box2D 1.0 // for using the MouseJoint
    
    Scene {
        id: scene
        property alias mard: level.mard
        width: 480
        height: 320
        
        // make these items available to the parent GameWindow as properties
        property alias level: level
        property alias hud: hud
        property alias entityContainer: level
        property alias player: level.player
        
        // this flag enables or disables particle effects for the boxes
        // it can be toggled from the menu
        property bool particlesEnabled: true
        property bool collisionSoundsEnabled: true
        
        // always put the scene on the bottom of the GameWindow, when the GameWindow has a different aspect ratio than the scene
        sceneAlignmentY: "bottom"
    
        BackgroundMusic {
            id: backgroundMusic
            source: "snd/bg_raggaman.wav"
            // the BackgroundMusic will automatically be played, because the autoPlay property is set to true by default
        }
        
        // Custom font loading of ttf fonts
        FontLoader {
            id: fontHUD
            source: "fonts/Anton.ttf"
        }
        
        // the MultiResolutionImage automatically selects the -sd, -hd or -hd2 image based on the resolution of the device
        MultiResolutionImage {
            id:levelBackground
            source: "img/background-sd.png" // it doesnt matter if -sd, -hd or -hd2 is chosen here, as it is modified automatically
            
            // use this if the image should be centered, which is the most common case
            anchors.centerIn: parent
        }
        SpriteBatchContainer {}
        Keys.forwardTo: mard.controller
        
        // contains the level loader
        Level {
            id: level
            anchors.fill: parent
        }
        
        
        // allows collision detection with pyhsics colliders (BoxColliders, CircleColliders and PolygonColliders)
        // it supports 2 modes:
        //  - for collision testing (set collisionTestingOnlyMode to true for each Body) when the positions get updated manually, e.g. by animations
        //  - for physics driven games like AngryBirds or this sample game, which is the default setting for a Body
        PhysicsWorld {
            id: physicsWorld
            // this puts it on top of all other items for the physics debug renderer
            z: 1
            // the logical world is smaller, not containing the hud!
            height: parent.height-hud.height
            
            // for physics-based games, this should be set to 60!
            updatesPerSecondForPhysics: 60
            // make objects fall faster by increasing gravity
            gravity.y: -9.81//*3
            
            // this should be increased so it looks good, by default it is set to 1 to save performance
            // when it is left at 1, the boxes sometimes "float" into each other
            velocityIterations: 5
            positionIterations: 5
        }
        
        HUD {
            id: hud
            height: 64
            // place it on the top right of the window, not on top of the logical scene
            anchors.top: scene.gameWindowAnchorItem.top
            anchors.right: scene.gameWindowAnchorItem.right
        }
        
        Text {
            x: 5
            // position it at the top of the window, not on top of the logical scene
            anchors.top: scene.gameWindowAnchorItem.top
            anchors.topMargin: 5
            
            text: "Created Boxes: " + player.createdEntities
            font.family: fontHUD.name
            font.pixelSize: 18
            color: "white"
        }
        
        IngameMenu {
            id: ingameMenu
            // in the default state, this is invisible
            visible: false
            anchors.centerIn: parent
        }
        
        // the default state will reset all PropertyChanges done below
        // so when switching back to state "", the ingameMenu will automatically become invisible!
        states: State {
            name: "ingameMenu"
            PropertyChanges { target: ingameMenu; visible: true}
        }
        
    }
    

     

    Level01.qml

    import QtQuick 1.1
    import "entities"
    
    Item {
        anchors.fill: parent
        property alias mard: mard
        
        // these entities will be created when the game launches
        Mard{
            id:mard
            x:50
            y:200
        }
    
    
     
        Wall {
            height: 30
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.bottom: parent.bottom
        }
        
        Wall {
            width: 20
            anchors.left: parent.left
            anchors.top: parent.top
            anchors.bottom: parent.bottom
        }
        
        Wall {
            width: 20
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
        }
        
    }
    

    Level.qml

    import QtQuick 1.1
    
    Item {
        // this is needed so an alias can be created from the GameWindow
        property alias player: player
    
         property alias mard: level.mard
        
        // the player object gets modified in the game
        QtObject {
            id: player
            property int createdEntities: 0
            
            onCreatedEntitiesChanged: {
                console.debug("created entities changed to:", createdEntities)
            }
        }
        
        // in here, different levels could be loaded
    
         Level01 {
          id: level
         }
        
    }
    

     

    #5978

    Alex
    Felgo Team

    Hi,

    we definitely need the sprite sheets, please send them to support@felgo.com .

    Best Regards,
    Alex

    #5982

    Pi

    Okay I have mailed you the sprite sheets for the same

    #6012

    Pi

    Hi,

    Any updates on this?

    I tried, as Chris suggested earlier, to use multiple SpriteSequeneFromFile and switch visibility but that didn’t help. Even tried Sprite Sequence(with a linear spritesheet) instead of SpriteSequeneFromFile, that didn’t work either.

    And it runs even worse on my other computer which doesn’t have the daily build.

    Any suggestions cause this is making the game look really glitchy!

    #6013

    Alex
    Felgo Team

    Hi,

    we found and fixed the bug in the engine, it will be available within the net daily build this week. You can remove updateItemPositionAndRotationImmediately() from your code then.

    Best Regards,
    Alex

Viewing 9 posts - 1 through 9 (of 9 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded