A Link to the Past Entrance Randomizer Tracker Idea - Pygame help

Hello All,

I had an idea to get my feet wet with an independent project.

A small explanation: As most may know there is something called game speedruns, and one of the games run is " The Legend of Zelda: A Link to the Past". A subgroup of these speedruns is called “Randomizers”. These are community-modified games that allow randomizing nearly anything, from enemy health to item locations.
One of the things that can be randomized are the entrances of structures. So you enter in one location but get transported to the interior of another structure.
Example on youtube

In the video you can see one of the more crazy variations of the randomizer, where entrance and exits are decoupled.
For now I want to focus on the variety where only the entrances are random, if you exit out again it would put you where you went in.

That long explanation out of the way:

What I am trying to code is a python programm that imports the game overworld map as an image, and allows the user to click somwhere to mark an entrance, then click on another location to mark the exit and a line should be drawn between those two locations.
I want to draw a rectangle at the clicked locations to mark where they are and use it as together with a collision check to not save the same location twice.

what I got so far is:

import pygame

pygame.init()

clock = pygame.time.Clock()
clock.tick(20)

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

screen = pygame.display.set_mode((500, 500))
running = True

connections_list = []


def get_instance_name(position):
"""
generates a name string for a clicked positon 
to be used for instantiating Connection()
"""
  position_x, position_y = position
  instance_name = str(position_x) + str(position_y)
  return instance_name


class Marker(pygame.sprite.Sprite):
"""
used to draw the marker at a given position
"""
  def __init__(self, position):
    pygame.sprite.Sprite.__init__(self)
    x, y = position

    self.image = pygame.Surface((50, 50))
    self.image.fill(RED)
    self.image.set_alpha(200)

    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y

  def check_click(self, mouse):
    if self.rect.collidepoint(mouse):
      self.image.set_alpha(200)


class Connection:
  """
  used as a container for an entrance/exit-pair, 
  self.set_entrance_or_exit(position) is used to assign clicked coordinates
  """
  def __init__(self, full=False):
    self.entrance = None
    self.exit = None
    self.full = full

  def set_entrance_or_exit(self, position):
    if self.entrance is None:
      self.entrance = position
    if self.exit is None:
      self.exit = position
      self.full = True

  def get_entrance(self):
    if self.entrance is None:
      return
    else:
      return self.entrance

  def get_exit(self):
    if self.exit is None:
      return
    else:
      return self.exit

  def check_if_full(self):
    return self.full


running = True

while running:
  all_sprites = pygame.sprite.Group()
  if len(connections_list) != 0:
    for connection in connections_list:
      if not connection.check_if_full():
        position = connection.get_entrance
        marker_entrance = connection + '_entrance'
        marker_entrance = Marker(connection.get_entrance())
        all_sprites.add(marker_entrance)

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
    elif event.type == pygame.MOUSEBUTTONDOWN:
      # for s in all_sprites:
        # s.check_click(event.pos)
      var = get_instance_name(pygame.mouse.get_pos())
      var = Connection()
      connections_list.append(var)
      var.set_entrance_or_exit(pygame.mouse.get_pos())
      print(var.get_entrance())
      print(all_sprites)

  screen.fill(BLACK)
  all_sprites.update()
  all_sprites.draw(screen)
  pygame.display.update()


pygame.quit()

I my problem now is that nothing gets drawn when I click, and I don’t understand why. As no error is thrown after a click I am somewhat stuck. Also this way of drawing a rectangle feels complicated to me. I used the method from this post https://stackoverflow.com/a/41369270, but maybe there is an easier way to do this. Again, I am open to suggestions :slight_smile:

As a sidenote I am aware that pygame might not be the best library to achieve what I want. So I am open to suggestions using other python modules. Someone mentioned “pynput” to me, maybe combining it with pyQT would work. But for now I am just trying to get the most basic functions down: clicking somewhere, saving the position, drawing a rectangle, collision/hover detection.

I appreciate any suggestions!

PS: I know there might be programs that already do that, but I just want to use this as training for myself :slight_smile:

So, got the basic draw on clik functionality working.
Seems it came down to initializing the sprite group at the wrong place…

Link to Githup Repo with WIP Code

I will update this threat if any significant progress was made :slight_smile:

Edit: And I already got light up of added shapes on mousover working. Nice!

Well, that was painfull… 4 hours of brainstorming until I had an idea that worked… Made a brach for a completely new way to safe and connect 2 mouse positions. I am using a hash map that generates a new key every 2 leftclicks, so two points get saved to the same key. Now the next step is to check retrieval of point pairs and trying to change alpha of drawn shapes at these positions depending on mousover.