Friday, March 22, 2024

Horizontal

 Codemy Pygame has added horizontal movement to Aspen Platform.

It is all done with 2d vectors, and we have position, velocity and acceleration.

Because everything is initiated at 0, movement is smooth...


                                               



The code:

import pygame
import self as self

#Define a 2d vector
vector = pygame.math.Vector2

#Initialize the game
pygame.init()

# Set display surface (divisible by 32 tile size)
WINDOW_WIDTH = 960 # 30 columns
WINDOW_HEIGHT = 640 # 20 rows
display_surface = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))
pygame.display.set_caption("Aspen Platformer - Codemy.com")

# Set FPS and clock
FPS = 60
clock = pygame.time.Clock()

# Tile Class
class Tile(pygame.sprite.Sprite):
# Read and Create tiles and put em on the screen
def __init__(self, x, y, image_integer, main_group, sub_group=""):
super().__init__()
# Load image and add to the tile subgroups
if image_integer == 1:
self.image = pygame.image.load('images/Brown.png')
elif image_integer == 2:
self.image = pygame.image.load('images/GReen.png')
sub_group.add(self)
elif image_integer == 3:
self.image = pygame.image.load('images/Blue.png')
sub_group.add(self)

# add every tile to main tile group
main_group.add(self)

# Get rect of images and position within the grid
self.rect = self.image.get_rect()
self.rect.topleft = (x,y)

# Apsen Player Class
class Aspen(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
# Define our aspen image
self.image = pygame.image.load("images/P.png")
# Get rect
self.rect = self.image.get_rect()
# Position aspen
self.rect.bottomleft = (x,y)

# Kinematic Vectors (x,y)
self.position = vector(x,y)
self.velocity = vector(0,0)
self.acceleration = vector(0,0)

# Kinematic Constants
self.HORIZONTAL_ACCELERATION = 2
self.HORIZONTAL_FRICTION = 0.20



def update(self):
# set initial acceleration to 0,0 to start
self.acceleration = vector(0)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.acceleration.x = -1 * self.HORIZONTAL_ACCELERATION
if keys[pygame.K_RIGHT]:
self.acceleration.x = self.HORIZONTAL_ACCELERATION

# Calculate new Kinematics
self.acceleration.x -= self.velocity.x * self.HORIZONTAL_FRICTION
self.velocity += self.acceleration
self.position += self.velocity + 0.5 * self.acceleration

# update rect
self.rect.bottomleft = self.position




# Define our sprite groups
main_tile_group = pygame.sprite.Group()
grass_tile_group = pygame.sprite.Group()
water_tile_group = pygame.sprite.Group()
aspen_group = pygame.sprite.Group()


# Create a tile map, nested python list: 0=no tile, 1=dirt, 2=grass, 3=water, 4=aspen
tile_map = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2],
[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2],
[1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,2,2,2,2,2],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,1,1,1,1,1]
]

# Create Tile objects from the tile map
# 2 for loops because tile map is nested. 20 i down
for i in range(len(tile_map)):
# loop thru the 30 elements in each list, j across
for j in range(len(tile_map[i])):
# Check for 0,1,2,3
if tile_map[i][j] == 1:
# dirt
Tile(j*32, i*32, 1, main_tile_group)
elif tile_map[i][j] == 2:
# grass
Tile(j*32, i*32, 2, main_tile_group, grass_tile_group)
elif tile_map[i][j] == 3:
# water
Tile(j*32, i*32, 3, main_tile_group, water_tile_group)
elif tile_map[i][j] == 4:
aspen = Aspen(j*32, i*32 + 32)
aspen_group.add(aspen)


# Add a background
bg_image = pygame.image.load('images/bg.png')
bg_image_rect = bg_image.get_rect()
bg_image_rect.topleft = (0,0)



# Game Loop
running = True
while running:
# Check to quit
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

# fill the display or blit an image
# display_surface.fill("black")
display_surface.blit(bg_image, bg_image_rect)

# Draw the Tiles
main_tile_group.draw(display_surface)

# Update and draw sprites
aspen_group.update()
aspen_group.draw(display_surface)


# Update Display
pygame.display.update()
clock.tick(FPS)

# End the game
pygame.quit()



This was news to me. Kinematics has the same Greek root as Cinematic, just the 

movement... From Bing/Chat:

You
Explain Kinematics to me.

Copilot

Kinematics is the branch of physics that describes the motion of objects without considering the forces that cause them to move. It focuses on the geometrically possible motion of bodies or systems of particles, providing a description of their spatial positions and how they change over time. In other words, kinematics helps us understand how things move, using tools like words, diagrams, graphs, mathematical equations, and numerical data123.

Here are some key terms related to kinematics:

  1. Scalars and Vectors: Scalars are quantities with only magnitude (e.g., distance), while vectors have both magnitude and direction (e.g., velocity).
  2. Distance and Displacement: Distance is the total length traveled by an object, while displacement is the straight-line distance from the initial to the final position.
  3. Speed and Velocity: Speed is the rate of change of distance, while velocity includes both speed and direction.
  4. Acceleration: Acceleration describes how quickly an object’s velocity changes.

Remember, kinematics provides the language and tools we use to describe and explain the motion of real-world objects. So, let’s dive into this fascinating field and explore the dynamics of movement! 🚀🌟


                                                                  *     *     *

I think there might be a homework assignment with this tutorial. That is getting a grasp

of why the update function defines position as:


 self.position += self.velocity + 0.5 * self.acceleration

I'll be working on this, today.


                                                           *     *     *

Asking Bard/Gemini for help:


                                                     


The explanation:


I'll explain how the update function works, particularly the kinematic equations within the Aspen class:

1. Key Input and Acceleration:

The function starts by checking for left or right key presses using pygame.key.get_pressed().

If a left key is pressed, the acceleration is set to a negative value (-1 * HORIZONTAL_ACCELERATION), causing the player to move left.

If a right key is pressed, the acceleration is set to a positive value (HORIZONTAL_ACCELERATION), moving the player right.

If neither key is pressed, the acceleration is initially set to 0.

2. Kinematic Equations:

Friction: The acceleration is adjusted to account for friction using self.acceleration.x -= self.velocity.x * self.HORIZONTAL_FRICTION. This slows down the player based on their current speed.

Velocity Update: The velocity is updated by adding the acceleration: self.velocity += self.acceleration. This changes the player's speed based on the acceleration being applied.

Position Update: The position is updated using the formula self.position += self.velocity + 0.5 * self.acceleration. This formula is based on the concept of "average acceleration" over a time step, ensuring smoother motion.

3. Rect Update:

After updating the position vector, the self.rect.bottomleft attribute is set to the new position. This ensures the player's sprite rectangle stays aligned with its actual position on the screen, allowing for proper collision detection and visual representation.

Key Points:

The game uses a fixed time step (presumably 1/60th of a second, as the FPS is set to 60).

The kinematic equations are simplified versions of real-world physics, but they are effective for creating smooth, controllable 2D movement.

The HORIZONTAL_ACCELERATION and HORIZONTAL_FRICTION constants directly affect the player's movement feel and can be adjusted to fine-tune the gameplay experience.

No comments: