4

I would like to know from you how I can make sure that the camera in pyglet (2D) always follows the player keeping it always in the middle of the screen. Also, I would like to know how I can make a linear zoom, with the mouse wheel, always holding the player in the middle of the screen. To be clear, if anyone knows Factorio, I would like the camera to behave the same way. Around I found only examples on how to do it by moving the mouse etc. Unfortunately, I have not found anything that interests me.

This is the script I'm currently using:

Main class (I do not report all the script, but the parts related to the camera):

def on_resize(self, width, height):
    self.camera.init_gl(width, height)

def on_mouse_scroll(self, x, y, dx, dy):
    self.camera.scroll(dy)

def _world(self):
    self.camera = camera(self)
    self.player = player(self, 0, 0)
    self.push_handlers(self.player.keyboard)

Camera script:

class camera(object):
    zoom_in_factor = 1.2
    zoom_out_factor = 1 / zoom_in_factor

    def __init__(self, game):
        self.game = game
        self.left = 0
        self.right = self.game.width
        self.bottom = 0
        self.top = self.game.height
        self.zoom_level = 1
        self.zoomed_width = self.game.width
        self.zoomed_height = self.game.height

    def init_gl(self, width, height):
        self.width = width
        self.height = height
        glViewport(0, 0, self.width, self.height)

    def draw(self):
        glPushMatrix()
        glOrtho(self.left, self.right, self.bottom, self.top, 1, -1)
        glTranslatef(-self.game.player.sprite.x + self.width / 2, -self.game.player.sprite.y + self.height / 2, 0)
        self.game.clear()
        if self.game.runGame:
            for sprite in self.game.mapDraw_3:
                self.game.mapDraw_3[sprite].draw()
        glPopMatrix()
        print(self.game.player.sprite.x, self.game.player.sprite.y)

    def scroll(self, dy):
        f = self.zoom_in_factor if dy > 0 else self.zoom_out_factor if dy < 0 else 1
        if .1 < self.zoom_level * f < 2:
            self.zoom_level *= f

            vx = self.game.player.sprite.x / self.width
            vy = self.game.player.sprite.y / self.height

            vx_in_world = self.left + vx * self.zoomed_width
            vy_in_world = self.bottom + vy * self.zoomed_height

            self.zoomed_width *= f
            self.zoomed_height *= f

            self.left = vx_in_world - vx * self.zoomed_width
            self.right = vx_in_world + (1 - vx) * self.zoomed_width
            self.bottom = vy_in_world - vy * self.zoomed_height
            self.top = vy_in_world + (1 - vy) * self.zoomed_height

This is what I get: enter image description here

This is what I would like to get (use Factorio as an example):

enter image description here

The script that I use at the moment I took it from here and modified for my need:

How to pan and zoom properly in 2D?

However, the script I am using, as you see, is based on something that has been created by someone else and I hate using something this way, because it does not belong to me. So I'm using it just to experiment and create my own camera class. That's why I asked for advice.

Other examples I watched:

https://www.programcreek.com/python/example/91285/pyglet.gl.glOrtho

https://groups.google.com/forum/#!topic/pyglet-users/g4dfSGPNCOk

https://www.tartley.com/2d-graphics-with-pyglet-and-opengl

There are other places I've watched, but I do not remember the links

To avoid repetition, yes, I looked on pyglet's guide, but at least that I am so stupid (I do not exclude it), I did not find anything that would help me to understand how to do it.

BlackFenix06
  • 577
  • 1
  • 6
  • 22
  • 1
    Keep questions and answers to questsions in the comment section, this reduces clutter in the question. Secondly, good update. Now there's some code we can help you figure out :) To answer you on `Without offense, I would like to know where in my question, you deduced that I did not try anything ` - I deducted that from the lack of `I have tried the following...` in your question. All I heard was `I want..` :) The question now contains a good example of your code, a super clear example of the desired solution and resources used. It helps everyone reading your code that here is actual code now! – Torxed Jun 19 '18 at 06:56
  • So I apologize if the transposition of my application through google translator has not respected what I wanted to imply. I modified the post so that there are not the things I wrote, written dictated by the fatigue of work and annoyance of your response. On that side, but I do not apologize, because I repeat it was quite annoying to read your answer, when there are many other questions on the site where no script is posted and anyway answers are given anyway. – BlackFenix06 Jun 19 '18 at 17:26
  • Especially for the fact that Pyglet is not that much supported by the Python community, so finding examples or videos relevant to your request is not always that simple. Moreover, Pyglet's guide is not always very clear on things. So it also becomes frustrating not to find what you are looking for, or help on the subject. – BlackFenix06 Jun 19 '18 at 17:26

1 Answers1

1

Well, I'm unsure of your first problem but I can help with the zoom.

def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
    zoom = 1.00
    if scroll_y > 0:
        zoom = 1.03
    elif scroll_x < 0:
        zoom = 0.97

    glOrtho(-zoom, zoom, -zoom, zoom, -1, 1)
asciidude
  • 272
  • 1
  • 3
  • 19
  • This is pretty self-explanatory, on mouse scroll it triggers a glOrtho event which should give a smooth but rough type of zoom. – asciidude May 08 '20 at 23:12