簡體   English   中英

為什么我的 map 塊沒有被正確繪制?

[英]Why aren't my map chunks being drawn correctly?

我正在嘗試與我的兒子在 Kivy 和 Python 中制作一個非常簡單的游戲。我們正試圖讓我們的視口(相機)在玩家圍繞我們的 map 移動時以玩家為中心,這是自生成的。 我們得到了初始視圖,然后當玩家移動時,初始塊顯示在正確的位置,但根本沒有繪制新塊。

通過調試,我們可以知道我們正在創建塊,它們具有良好的值,並且我們的 draw_chunks function 知道獲取更多塊並繪制它們。 他們只是沒有被吸引。 我們認為我們繪制矩形的代碼可能是錯誤的,但適用於游戲的初始加載。 我們花了幾個小時試圖修復它。 我們已經用幾種不同的方式調整了視口 position 以及矩形代碼,但似乎沒有任何效果。 我希望有人能指出我們錯過了什么。 這可能是我們忽略的非常明顯或愚蠢的事情。 有人有什么想法嗎?

import kivy
import random

from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Ellipse, Line, Rectangle 
from kivy.uix.widget import Widget
from kivy.config import Config
from kivy.core.window import Window 
import enum

# Constants for the chunk size and map dimensions
CHUNK_SIZE = 48
TILE_SIZE = 16
MAP_WIDTH = 256
MAP_HEIGHT = 256

#**************************
#* Tile Int Enum Class *
#**************************
class TileEnum(enum.IntEnum):
    GRASS = 0
    DIRT = 1
    CONCRETE = 2
    ASPHALT = 3

# Class to represent the game map
class GameMap:
    def __init__(self, seed=None):
        self.seed = seed
        if seed is not None:
            random.seed(seed)
        self.chunks = {}
        self.first_chunk = False
    
    def generate_chunk(self, chunk_x, chunk_y):
        # Use the RNG to generate the terrain for this chunk
        terrain = []

        for x in range(0, CHUNK_SIZE):
            column = []
            for y in range(0, CHUNK_SIZE):
                column.append(random.randint(0, 3))
            terrain.append(column)
        
        return terrain
    
    def get_chunk(self, chunk_x, chunk_y):
        # Check if the chunk has already been generated
        if (chunk_x, chunk_y) in self.chunks:
            print("found it",chunk_x, chunk_y)
            return self.chunks[(chunk_x, chunk_y)]
        else:
            # Generate the chunk and store it in the chunk cache
            chunk = self.generate_chunk(chunk_x, chunk_y)
            self.chunks[(chunk_x, chunk_y)] = chunk
            print("made it",chunk_x,chunk_y)
            return chunk

# Class to represent the player
class Player:
    def __init__(self, pos=(0, 0)):
        self.x, self.y = pos
        self.speed = TILE_SIZE/2
    
    def move_left(self):
        self.x += self.speed
    
    def move_right(self):
        self.x -= self.speed
    
    def move_up(self):
        self.y -= self.speed
    
    def move_down(self):
        self.y += self.speed

class GameScreen(Widget):
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.viewport_size = (TILE_SIZE*CHUNK_SIZE, TILE_SIZE*CHUNK_SIZE)
        self.viewport_pos = (0, 0)
        self.size = self.viewport_size

        self.map = GameMap(seed=123)
        self.player = Player((self.viewport_size[0]/2, self.viewport_size[1]/2))

        self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
        self._keyboard.bind(on_key_down=self._on_keyboard_down)

    def draw_chunks(self):
        # Determine the chunks that are currently in view
        viewport_left = int(self.viewport_pos[0] // (CHUNK_SIZE * TILE_SIZE))
        viewport_top = int(self.viewport_pos[1] // (CHUNK_SIZE * TILE_SIZE))
        viewport_right = int((self.viewport_pos[0] + self.viewport_size[0]) // (CHUNK_SIZE * TILE_SIZE))
        viewport_bottom = int((self.viewport_pos[1] + self.viewport_size[1]) // (CHUNK_SIZE * TILE_SIZE))

        print(viewport_left, viewport_top, viewport_right, viewport_bottom)
     
        # Iterate over the visible chunks and draw them
        for x in range(viewport_left, viewport_right + 1):
            for y in range(viewport_top, viewport_bottom + 1):
                chunk = self.map.get_chunk(x, y)
                #print(chunk)
                for i in range(len(chunk)):
                    for j in range(len(chunk[i])):
                        if chunk[i][j] == TileEnum.GRASS:
                            # Draw a green square for grass
                            with self.canvas:
                                Color(0.25, 0.75, 0.25)
                        elif chunk[i][j] == TileEnum.DIRT:
                            # Draw a brown square for dirt
                            with self.canvas:
                                Color(0.75, 0.5, 0.25)
                        elif chunk[i][j] == TileEnum.CONCRETE:
                            # Draw a gray square for concrete
                            with self.canvas:
                                Color(0.5, 0.5, 0.75)
                        elif chunk[i][j] == TileEnum.ASPHALT:
                            # Draw a black square for asphalt
                            with self.canvas:
                                Color(0.25, 0.25, 0.5)
                        with self.canvas:
                            Rectangle(pos=(
                                (x * CHUNK_SIZE + i) * TILE_SIZE + self.viewport_pos[0],
                                (y * CHUNK_SIZE + j) * TILE_SIZE + self.viewport_pos[1]),
                                size=(TILE_SIZE, TILE_SIZE))
    
    def draw_player(self):
        # Draw a circle for the player
        with self.canvas:
            Color(0, 0.5, 0)
            Ellipse(pos=(self.viewport_size[0]/2 - (TILE_SIZE/2), self.viewport_size[0]/2 - (TILE_SIZE/2)), size=(TILE_SIZE, TILE_SIZE))
    
    def update(self, dt):
        # Update the viewport position to keep the player centered
        self.viewport_pos = (self.player.x - self.viewport_size[0]/2, self.player.y - self.viewport_size[1]/2)
        print(self.viewport_pos)

        # Redraw the chunks and player
        self.canvas.clear()
        self.draw_chunks()
        self.draw_player()
    
    def _keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        #print(keycode)
        if keycode[1] == 'left':
            self.player.move_left()
        elif keycode[1] == 'right':
            self.player.move_right()
        elif keycode[1] == 'up':
            self.player.move_up()
        elif keycode[1] == 'down':
            self.player.move_down()
        
# Main application class
class ProceduralGenerationGameApp(App):
    def build(self):
        
        self.title = "Procedural Generation Game"
        Config.set("graphics", "width", "768")
        Config.set("graphics", "height", "768")
        Config.set("graphics", "resizable", False)
        Config.set("graphics", "borderless", False)
        Config.set("graphics", "fullscreen", False)
        Config.set("graphics", "window_state", "normal")
        Config.set("graphics", "show_cursor", True)
        Config.write()

        window_width = Config.getint("graphics", "width")
        window_height = Config.getint("graphics", "height")

        # Create the game screen and schedule the update function to be called every frame
        game_screen = GameScreen()

        Window.size = (window_width, window_height)

        Clock.schedule_interval(game_screen.update, 1)# 1.0 / 60.0)
        
        return game_screen

if __name__ == "__main__":
    ProceduralGenerationGameApp().run()

我們更新了 Rectangle 代碼,並在他的移動函數中反轉了玩家的方向:

            with self.canvas:
                x_chunk_offset = (x * CHUNK_SIZE * TILE_SIZE)
                y_chunk_offset = (y * CHUNK_SIZE * TILE_SIZE)
                x_tile_offset = (i * TILE_SIZE)
                y_tile_offset = (j * TILE_SIZE)
                actual_x = x_chunk_offset + x_tile_offset - self.viewport_pos[0]
                actual_y = y_chunk_offset + y_tile_offset - self.viewport_pos[1]

                Rectangle(pos=(actual_x, actual_y), size=(TILE_SIZE, TILE_SIZE))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM