Gamedev In-depth Topics: Non-integer Movement

KidsCanCode · Beginner ·🛠️ AI Tools & Apps ·10y ago

Key Takeaways

The video discusses how to deal with rounding issues and ensure consistent movement when using non-integer speeds or positions in game development, specifically in Pygame.

Full Transcript

welcome back to a game dev in depth in this video we're gonna be talking about something that can be a huge source of confusion for beginner programmers it has to do with the idea of real numbers which are fractions or decimals versus integers or whole numbers a lot of times when we're calculating movement we might come up with a non integer number like 2.5 however there are a fixed number of pixels on the screen and you can't draw something that's a 2.5 pixels it has to be an integer this can cause a number of confusing and hard to solve problems in your movement or animation code okay to see some of those problems let's look first at our simple 8 way movement example we did and I'm gonna focus only on the X Direction for this example so when we press the right or the left key we're setting our velocity to 5 which is 5 pixels per frame and then we're telling the rectangle to add that amount you know to move that amount so we move 5 pixels to the right or 5 pixels to the left or we change the rectangles x-coordinate by 5 right and we move left and right well let's I'm gonna change these to 1 just to keep things very simple but let's say there was some reason you wanted the movement to the right to be faster than the left by a little bit let's say you wanted it to be 1.5 so now I should move faster to the right than to the left well turns out when I do it there's moving to the left there is moving to the right can you see a difference no in fact there is no difference what's happening is the rectangles in pygame are based on pixels and you can't have a fraction of a pixel so all of the properties of the rectangle must be integers or whole numbers so when this happens and we say take the X and add 1.5 to it Python changes this 1.5 which is a real number into a an integer and it does that not by rounding but by truncating so that 1.5 just becomes 1 so there's no difference between 1 and 1.9 for example anything it's going to be the same so that means you can only have whole number speeds right well not exactly but before I go into how we fix this I also want to show you another thing that is might be unexpected and definitely trips up a lot of students when they're starting out what if I was to put 1.5 here so I want to move to the left right I want to subtract 1.5 well you would think you would see the same problem but instead what we get is there's moving to the right there is moving to the left that it's twice as fast what's happening is this is actually getting converted to negative 2 what happens is when python converts a real number to an integer is it takes the number and does what's called a floor operation on it it rounds it down to the next lowest integer so the next lowest integer from 1.5 is one but the next lowest integer from 1.5 our negative 1 25 is negative 2 so that's why we moved faster to the left than the right we were basically saying do this so let's look at another example of this problem in our time step example that we did in a previous video we are trying to move our rectangle at 120 pixels per second so we take that hundred and 20 and we multiply it by whatever the duration of the frame is right and since we're going since we're right now going at 60 frames per second then if we pop up the calculator here then I'm going to put and 1/60 and there we go that's how many seconds long our frame is so that's not a nice clean integer is it so if we have a hundred and twenty we say we want to move 120 pixels times let's just put point on one seven for this illustration I get two point O four so I'm saying move to 0.04 pixels but we can't so that gets truncated 2.04 gets truncated to two and that's fine but what about if once 25 frames have gone by well if we multiply that by 25 then it's gonna say after 25 pixels we should have moved 51 pixels after 2 sorry after 25 frames we should have moved 51 pixels but instead if we only move to 2 times 25 of course is 50 so after 25 frames or so we've lost one pixel in movement so you'll see this crop up in all sorts of ways as your programs get more advanced and you want to do different kinds of movement you want to do collisions you want to do one thing moving towards something else this rounding issue can cause a lot of strange errors that are really hard to figure out if you don't know what you're doing so now let's talk about how we prevent this problem or avoid this problem so to illustrate this I've just made another copy of our little frame based movement example where we're trying to move 120 pixels per second but this is going to come out to a 2.04 or sum or something like that right a non-integer mil and the way that you prevent this rounding problem is you store your price sprites position or you track your spiced position separately from the rectangle so for example since we're moving in the X direction I'm gonna make a px variable this is position X and I'm gonna set it equal to 0 because we're gonna start on the left hand side of the screen and now instead of increasing my rectangles X by the velocity I'm going to increase px so now P X will become 2.04 and then 4.08 and so on and it doesn't get rounded and we'll take the will use the PX to determine whether we need to wrap around the screen and then once we've calculated what our px should be we set our rectangle to be equal to that to that position right now obviously if px is 4.5 or something then the rectangle will be put to 4 but as soon as this gets to the next it gets passed the next integer the rectangle will move there but we're still keeping the right count of how our position is changing and if you look at this it will be a lot smoother there's none of those little stutters that we saw before when it would have when it was rounding to the next pixel in fact we're not losing the every 25 frames we're not losing the 1 pixel and dropping from 51 to 50 where you're actually moving 51 pixels after 21 frames so that's it to avoid the rounding problems you just keep track of your sprites position in a separate variable that can stay being a real number do your calculations on it and then just draw your rectangle at the pixel that's closest to where it's supposed to be and then everything will will look fine of course in this example we only were moving horizontally so if you have vertical movement and then you also need to keep track of it V Y and a position Y so you have two variables for each thing if you have acceleration happening because of gravity or anything like that you have to have an acceleration X&Y so you can start to see the number of variables is starting to increase and there's a lot more to keep track out and have it separately keep track of VX and V Y and all those kind of things is another problem and in the next video we'll talk about how you can solve that problem and simplify the number of variables that you have to keep track of thanks for watching I hope this video was useful for you and helps you avoid some of those rounding integer vs. real problems that a lot of new programmers run into and wind up scratching their heads about as always if you enjoyed this lesson please press the like button below and if you haven't already subscribed please do so so you can find out about the next video as soon as it's released thanks and I'll see you next time you

Original Description

In this video we discuss how to deal with rounding issues and ensure consistent movement when using non-integer speeds or positions. "In-depth Topics" will explore and explain a little more deeply certain subjects that may be tricky for new programmers to understand, or that may not quite fit into the usual tutorial structure. Most will likely be math related, but they may also cover other topics that come up or are requested by viewers. Note: While the examples here will be using Python/Pygame, the actual material will apply more generally to all game development, regardless of what language you may be using. If you like these videos please consider supporting me on Patreon: https://www.patreon.com/kidscancode
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from KidsCanCode · KidsCanCode · 55 of 60

1 Learning to Code with Python: Lesson 1.1 - What is Programming?
Learning to Code with Python: Lesson 1.1 - What is Programming?
KidsCanCode
2 Learning to Code with Python: Lesson 1.2 - Drawing with Turtles
Learning to Code with Python: Lesson 1.2 - Drawing with Turtles
KidsCanCode
3 Learning to Code with Python: Lesson 1.3 - Variables
Learning to Code with Python: Lesson 1.3 - Variables
KidsCanCode
4 Learning to Code with Python: Lesson 1.4 - Loops (and more turtles!)
Learning to Code with Python: Lesson 1.4 - Loops (and more turtles!)
KidsCanCode
5 Learning to Code with Python: Lesson 1.5 - Saving and Running Programs
Learning to Code with Python: Lesson 1.5 - Saving and Running Programs
KidsCanCode
6 Learning to Code with Python: Lesson 1.6 - Functions
Learning to Code with Python: Lesson 1.6 - Functions
KidsCanCode
7 Learning to Code with Python: Lesson 1.7 - Input and Conditional Statements
Learning to Code with Python: Lesson 1.7 - Input and Conditional Statements
KidsCanCode
8 Learning to Code with Python: Lesson 1.8 - Number Guessing Game
Learning to Code with Python: Lesson 1.8 - Number Guessing Game
KidsCanCode
9 KidsCanCode - Patreon Intro Video
KidsCanCode - Patreon Intro Video
KidsCanCode
10 Learning to Code with Python: Lesson 1.9 - Rock Paper Scissors Game
Learning to Code with Python: Lesson 1.9 - Rock Paper Scissors Game
KidsCanCode
11 Learning to Code with Python: Lesson 1.10 - Secret Codes
Learning to Code with Python: Lesson 1.10 - Secret Codes
KidsCanCode
12 Learning to Code with Python: Lesson 2.1 Creating Computer Graphics
Learning to Code with Python: Lesson 2.1 Creating Computer Graphics
KidsCanCode
13 Learning to Code with Python: Lesson 2.2 Simple Animation
Learning to Code with Python: Lesson 2.2 Simple Animation
KidsCanCode
14 Learning to Code with Python: Lesson 2.3: Animating More Objects
Learning to Code with Python: Lesson 2.3: Animating More Objects
KidsCanCode
15 Learning to Code with Python: Lesson 2.4: More Fun with Animation
Learning to Code with Python: Lesson 2.4: More Fun with Animation
KidsCanCode
16 Extra: Setting up the Atom Editor for Python
Extra: Setting up the Atom Editor for Python
KidsCanCode
17 Game Development 1-1: Getting Started with Pygame
Game Development 1-1: Getting Started with Pygame
KidsCanCode
18 Game Development 1-2: Working with Sprites
Game Development 1-2: Working with Sprites
KidsCanCode
19 Game Development 1-3: More About Sprites
Game Development 1-3: More About Sprites
KidsCanCode
20 Pygame Shmup Part 1: Player Sprite and Controls
Pygame Shmup Part 1: Player Sprite and Controls
KidsCanCode
21 Pygame Shmup Part 2: Enemy Sprites
Pygame Shmup Part 2: Enemy Sprites
KidsCanCode
22 Pygame Shmup Part 3: Collisions (and Bullets!)
Pygame Shmup Part 3: Collisions (and Bullets!)
KidsCanCode
23 Pygame Shmup Part 4: Adding Graphics
Pygame Shmup Part 4: Adding Graphics
KidsCanCode
24 Pygame Shmup Part 5: Improved Collisions
Pygame Shmup Part 5: Improved Collisions
KidsCanCode
25 Pygame Shmup Part 6: Sprite Animation
Pygame Shmup Part 6: Sprite Animation
KidsCanCode
26 Pygame Shmup Part 7: Score (and Drawing Text)
Pygame Shmup Part 7: Score (and Drawing Text)
KidsCanCode
27 Pygame Shmup Part 8: Sound and Music
Pygame Shmup Part 8: Sound and Music
KidsCanCode
28 Pygame Shmup Part 9: Shields
Pygame Shmup Part 9: Shields
KidsCanCode
29 Pygame Shmup Part 10: Explosions
Pygame Shmup Part 10: Explosions
KidsCanCode
30 Pygame Shmup Part 11: Player Lives
Pygame Shmup Part 11: Player Lives
KidsCanCode
31 Pygame Shmup Part 12: Powerups
Pygame Shmup Part 12: Powerups
KidsCanCode
32 Pygame Shmup Part 13: Powerups (part 2)
Pygame Shmup Part 13: Powerups (part 2)
KidsCanCode
33 Pygame Shmup Part 14: Game Over Screen
Pygame Shmup Part 14: Game Over Screen
KidsCanCode
34 Pygame Platformer Part 1: Setting Up
Pygame Platformer Part 1: Setting Up
KidsCanCode
35 Pygame Platformer Part 2: Player Movement
Pygame Platformer Part 2: Player Movement
KidsCanCode
36 Pygame Platformer Part 3: Gravity and Platforms
Pygame Platformer Part 3: Gravity and Platforms
KidsCanCode
37 Pygame Platformer Part 4: Jumping
Pygame Platformer Part 4: Jumping
KidsCanCode
38 Pygame Platformer Part 5: Scrolling the Window
Pygame Platformer Part 5: Scrolling the Window
KidsCanCode
39 Pygame Platformer Part 6: Game Over
Pygame Platformer Part 6: Game Over
KidsCanCode
40 Pygame Platformer Part 7: Splash & End Screens
Pygame Platformer Part 7: Splash & End Screens
KidsCanCode
41 Pygame Platformer Part 8: Saving High Score
Pygame Platformer Part 8: Saving High Score
KidsCanCode
42 Pygame Platformer Part 9: Using Spritesheets
Pygame Platformer Part 9: Using Spritesheets
KidsCanCode
43 Pygame Platformer Part 10: Character Animation (part 1)
Pygame Platformer Part 10: Character Animation (part 1)
KidsCanCode
44 Pygame Platformer Part 11: Character Animation (part 2)
Pygame Platformer Part 11: Character Animation (part 2)
KidsCanCode
45 Pygame Platformer Part 12: Platform Graphics
Pygame Platformer Part 12: Platform Graphics
KidsCanCode
46 Pygame Platformer Part 13: Improved Jumping
Pygame Platformer Part 13: Improved Jumping
KidsCanCode
47 Pygame Platformer Part 14: Sound and Music
Pygame Platformer Part 14: Sound and Music
KidsCanCode
48 Pygame Platformer Part 15: Powerups
Pygame Platformer Part 15: Powerups
KidsCanCode
49 Pygame Platformer Part 16: Enemies
Pygame Platformer Part 16: Enemies
KidsCanCode
50 Pygame Platformer Part 17: Using Collision Masks
Pygame Platformer Part 17: Using Collision Masks
KidsCanCode
51 Pygame Platformer Part 18: Scrolling Background
Pygame Platformer Part 18: Scrolling Background
KidsCanCode
52 Pygame Platformer Part 19: Wrapping Up
Pygame Platformer Part 19: Wrapping Up
KidsCanCode
53 Gamedev In-depth Topics: 4-way vs. 8-way Movement
Gamedev In-depth Topics: 4-way vs. 8-way Movement
KidsCanCode
54 Gamedev In-depth Topics: Time-based vs. Frame-based Movement
Gamedev In-depth Topics: Time-based vs. Frame-based Movement
KidsCanCode
▶ Gamedev In-depth Topics: Non-integer Movement
Gamedev In-depth Topics: Non-integer Movement
KidsCanCode
56 Tile-based game Part 1: Setting up
Tile-based game Part 1: Setting up
KidsCanCode
57 Tile-based game Part 2: Collisions and Tilemap
Tile-based game Part 2: Collisions and Tilemap
KidsCanCode
58 Tile-based game Part 3: Smooth Movement
Tile-based game Part 3: Smooth Movement
KidsCanCode
59 Tile-based game Part 4: Scrolling Map / Camera
Tile-based game Part 4: Scrolling Map / Camera
KidsCanCode
60 Tile-based game Part 5: Player Graphics
Tile-based game Part 5: Player Graphics
KidsCanCode

The video teaches how to handle non-integer movement in Pygame by storing the sprite's position separately from the rectangle and using a separate variable to track the position, thus avoiding rounding issues.

Key Takeaways
  1. Store the sprite's position in a separate variable
  2. Use the separate variable to track the position
  3. Calculate the position using the separate variable
  4. Draw the rectangle at the pixel closest to the calculated position
💡 Storing the sprite's position separately from the rectangle helps avoid rounding issues and ensures consistent movement.

Related Reads

📰
What Workflow Builders Learn When AI Draft Quality Improves but Publishing QA Still Breaks: Practical Notes for Builders
Learn how improved AI draft quality affects workflow builders and publishing QA, and what practical steps to take to ensure seamless content delivery
Dev.to AI
📰
Meshy AI 3D Generator Review 2026: 185 MB Per House, $193 to Ship It
Learn how Meshy AI 3D Generator works and its implications on data storage and shipping costs
Medium · AI
📰
5 Claude Tricks That Feel Almost Like Cheating
Boost productivity with Claude by using 5 tricks that simplify workflows and enhance efficiency
Medium · Data Science
📰
[Video] I Tested Grok 4.7 With One Simple Job: Turn My vi Task Files Into a Bash Agenda
Learn how to use Grok 4.7 to automate task management by converting vi task files into a Bash agenda
Dev.to AI
Up next
How to Get Your Brand Cited by ChatGPT, Claude and Gemini
Arvow
Watch →