Meta unveils it’s AITemplate GPU framework
Meta is announcing their new AITemplate framework for GPUs.
Read more ▶
The post Meta unveils it’s AITemplate GPU framework appeared first on SemiAccurate.
Meta is announcing their new AITemplate framework for GPUs.
Read more ▶
The post Meta unveils it’s AITemplate GPU framework appeared first on SemiAccurate.
I am new to game development, I previously created games using tiledmap editor and pygame, but manually creating map was real pain, so i begun to look how can i procedurally generate map, after banging head for few week and googling i finally created a map. However, I'm facing an issue where some paths on the map end up isolated from each other. I'm looking for suggestions or algorithms to connect these isolated parts of the map, ensuring that there is always a continuous path from any point to any other point on the map. The code works on looking at adjacent neighbour but in the end most of the time it cause isolation of part of map by closing path.
from random import random
from pprint import pprint, pformat
WALL = 1
EMPTY = 0
POSSIBLE_WALL_PERCENT = 0.4
ADJACENT_WALL_THRESHOLD = 5
range_X = 1
range_Y = 1
class Map:
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self.grid = [[EMPTY for _ in range(width)] for _ in range(height)]
self.random_wall_fill()
self.place_walls()
def random_wall_fill(self):
for row in range(self.height):
for col in range(self.width):
if random() < POSSIBLE_WALL_PERCENT:
self.grid[row][col] = WALL
def get_adjacent_wall(self, x: int, y: int, range_x: int, range_y: int):
wall_count: int = 0
start_x, end_x = x - range_x, x + range_x
start_y, end_y = y - range_y, y + range_y
for i_y in range(start_y, end_y + 1):
for i_x in range(start_x, end_x + 1):
if (i_x != x or i_y != y) and self.is_wall(i_x, i_y):
wall_count += 1
return wall_count
def place_walls(self):
for y in range(self.height):
for x in range(self.width):
if self.grid[y][x] == EMPTY:
if self.place_wall_logic(x, y):
self.grid[y][x] = WALL
def place_wall_logic(self, x, y):
num_walls = self.get_adjacent_wall(x, y, range_X, range_Y)
if num_walls >= ADJACENT_WALL_THRESHOLD:
return True
else:
return False
def is_wall(self, x: int, y: int):
if self.out_of_bound(x, y):
return True
elif self.grid[y][x] == WALL:
return True
return False
def out_of_bound(self, x: int, y: int):
if x < 0 or x >= len(self.grid[0]):
return True
elif y < 0 or y >= len(self.grid):
return True
return False
def display_map(self):
for row in self.grid:
for cell in row:
if cell == WALL:
print("0", end=" ")
else:
print(".", end=" ")
print()
def __repr__(self):
return pformat(self.grid)
level_map = Map(30, 30)
level_map.display_map()
I've created a Camera
class that takes a source surface and draws it to a destination surface using the camera's parameters (position, zoom, size, etc.).
The class works well, but the framerate drops significantly when zooming into the surface.
I've tried 2 things:
I've added convert_alpha()
to the textures, but that doesn't seem to help
I've tried using surface.subsurface()
to get the portion of the source surface to draw. This does speed things up a bit, but this breaks the camera's behaviour (zooming in is jerky, the source surface isn't centred in the camera when zoomed out).
The Camera
class is here: https://github.com/rik-cross/pygamepal/blob/main/src/pygamepal/camera.py
def draw(self, surface, destSurface):
# draw border
pygame.draw.rect(destSurface, self.borderColor,
(self.position[0] - self.borderThickness, self.position[1] - self.borderThickness,
self.size[0] + self.borderThickness * 2, self.size[1] + self.borderThickness * 2), self.borderThickness, border_radius = 1)
# ensure that the surface is clipped to the camera dimensions
destSurface.set_clip((self.position[0], self.position[1], self.size[0], self.size[1]))
# fill the surface to the background color
destSurface.fill(self.backgroundColor)
# blit the (zoomed) surface to the destination, and set the target as the center
x = 0 - (self.size[0] / 2 - self._currentTarget[0] * self._currentZoom)
y = 0 - (self.size[1] / 2 - self._currentTarget[1] * self._currentZoom)
# add screen shake
x += self._shakeCurrent[0]
y += self._shakeCurrent[1]
# draw the surface to the destination using the correct position, size, center and zoom
destSurface.blit(pygame.transform.scale(surface, (surface.get_width() * self._currentZoom, surface.get_height() * self._currentZoom)),
self.position,
(x, y,
self.size[0], self.size[1]))
# reset surface clipping
destSurface.set_clip()
The example with poor performance is here: https://github.com/rik-cross/pygamepal/blob/main/examples/fullExample.py (walk towards the trees to see the framerate drop).
class GameScene(pygamepal.Scene):
def zoomCamera(self, this, other, zoom):
self.camera.zoom = zoom
def setChestState(self, this, other, state):
self.chest.spriteImage.pause = False
self.chest.spriteImage.state = state
def init(self):
#
# add textures
#
self.map = pygame.image.load(os.path.join('images', 'map.png'))
self.map = self.map.convert_alpha()
#
# add sprites
#
# player
self.player = Player()
self.addSprite(self.player)
# trees
self.addSprite(
pygamepal.Sprite(
imageName = os.path.join('images', 'tree.png'),
position = (40, 50),
collider = pygamepal.Collider(offset = (6, 25), size = (12, 5))
)
)
self.addSprite(
pygamepal.Sprite(
imageName = os.path.join('images', 'tree.png'),
position = (70, 40),
collider = pygamepal.Collider(offset = (6, 25), size = (12, 5))
)
)
self.addSprite(
pygamepal.Sprite(
imageName = os.path.join('images', 'tree.png'),
position = (20, 10),
collider = pygamepal.Collider(offset = (6, 25), size = (12, 5))
)
)
# chest
# load a texture
chestSpritesheet = pygame.image.load(os.path.join('images','chest_spritesheet.png'))
# split texture into a 2D list of sub-textures
splitTextures = pygamepal.splitTexture(chestSpritesheet, 48, 48)
self.chest = pygamepal.Sprite(position = (175, 175), size = (16, 14))
self.chest.collider = pygamepal.Collider(offset = (0, 8), size = (16, 6))
self.chest.spriteImage = pygamepal.SpriteImage()
self.chest.spriteImage.addTextures(splitTextures[0][0], splitTextures[0][1], splitTextures[0][2], splitTextures[0][3], offset = (16, 18), state = 'open', animationDelay = 4, loop = False)
self.chest.spriteImage.addTextures(splitTextures[0][3], splitTextures[0][2], splitTextures[0][1], splitTextures[0][0], offset = (16, 18), state = 'close', animationDelay = 4, loop = False)
self.chest.spriteImage.pause = True
self.chest.trigger = pygamepal.Trigger(size = (26, 24), offset = (-5, -5),
onEnter = lambda this, other, state = 'open': self.setChestState(this, other, state),
onExit = lambda this, other, state = 'close': self.setChestState(this, other, state))
self.addSprite(self.chest)
#
# customise the scene
#
self.backgroundColor = 'black'
self.sortKey = self.sortByBottom
#
# customise the scene camera
#
self.camera.backgroundColor = 'black'
self.camera.setTarget(self.player.getCenter(), instant = True)
self.camera.lazyFollow = 0.9
self.camera.setZoom(4, instant = True)
self.camera.lazyZoom = 0.9
self.camera.clamp = True
self.camera.clampRect = (0, 0, 256, 256)
#
# add triggers for the camera
#
self.forestTrigger = pygamepal.Trigger(position = (10, 20), size = (100, 70),
onEnter = lambda this, other, zoom = 6 : self.zoomCamera(this, other, zoom),
onExit = lambda this, other, zoom = 4 : self.zoomCamera(this, other, zoom))
self.addTrigger(self.forestTrigger)
#
# add map bounds colliders
#
# top
self.addCollider(pygamepal.Collider((0, 0), (256, 2)))
# bottom
self.addCollider(pygamepal.Collider((0, 254), (256, 2)))
# left
self.addCollider(pygamepal.Collider((0, 0), (2, 256)))
# right
self.addCollider(pygamepal.Collider((254, 0), (2, 256)))
def update(self):
# [ESC] to return to menu scene
if self.game.input.isKeyPressed(pygame.K_ESCAPE):
self.game.currentScene = menuScene
# camera tracks the player
self.camera.target = self.player.getCenter()
def draw(self):
self.sceneSurface.blit(self.map, (0, 0))
I thought I'd ask for help in case there's an easy fix!
Thanks!