sand-box-python/readme.md
Lucas Kalil 9f2ab8ef56
Update readme.md
ATUALIZADO README
2024-07-22 20:01:59 -03:00

137 lines
6.2 KiB
Markdown

# Sand box Python
Este projeto foi desenvolvido em pouco mais de 2 dias durante um fim de semana. A principal motivação para sua criação foi a nostalgia de um jogo de navegador da minha infância, o [Powder Game](https://dan-ball.jp/en/javagame/dust/). O objetivo foi criar algo semelhante ao jogo original, embora, no meu projeto, existam apenas 6 tipos diferentes de elementos, em contraste com a grande variedade do jogo original.
# Índice
1. [Sand Box Python](#sand-box-python)
2. [Dificuldades e Como As Contornei](#dificuldades-e-como-as-contornei)
1. [Problemas](#problemas)
2. [Solução Parcial](#solução-parcial)
3. [Solução Final](#solução-final)
3. [Como Executar e Instalar](#como-executar-e-instalar)
4. [Configurando Propriedades](#configurando-propriedades)
5. [Elementos](#elementos-e-comandos)
6. [Contribuições](#contribuições)
7. [Licença](#licença)
8. [Contato](#contato)
# Dificuldades e Como As Contornei
A ideia original era desenvolver o jogo em uma engine como Unity ou Unreal. No entanto, devido ao tempo limitado, optei por usar uma tecnologia com a qual já tinha familiaridade: Python.
## Problemas
O principal problema surgiu ao tentar iniciar o jogo com [Python](https://www.python.org/) puro, usando arrays nativos para uma tela de 500x500 pixels, resultando em um array com 250.000 itens. Percorrer cada item a cada quadro resultava em um desempenho muito ruim, com apenas 1 a 5 fps sem mencionar o uso de memória, que era gigantesco.
## Solução Parcial
Para melhorar a performance, substituí o array nativo por um array do [NumPy](https://numpy.org/), que oferece vantagens significativas em termos de desempenho e uso de memória. Cada pixel foi representado por 5 números `uint8`, o que resultou em uma melhoria modesta, alcançando 5 a 10 fps, mas ainda não o suficiente para uma jogabilidade aceitável.
### por que 5 numeros?
```python
class Types(Enum):
BG = (0, 0, 0, 0, 0)
SAND = (203, 189, 147, 1, 0)
WATER = (28, 163, 236, 2, 0)
STONE = (115, 112, 112, 3, 0)
VACUUM = (20, 20, 20, 4, 0)
CLONER = (108, 60, 12, 5, 0)
```
- Os três primeiros números representam a cor do pixel, permitindo leves variações dentro do mesmo elemento.
- O quarto valor é o ID do pixel, por exemplo, o ID da água é 2.
- O último valor é para dados adicionais, utilizado principalmente pelo elemento "cloner", mas pode ser usado para outros tipos de elementos, se necessário.
Dessa forma, cada pixel na minha tela é representado por 5 números uint8, totalizando 5 bytes por pixel. Para um array de 250.000 pixels, isso resulta em 1.250.000 bytes ou 1,25 MB, um valor baixo e eficiente.
#### python + numpy 320 x 320 exemplo AVG: 7 fps
![python and numpy example](https://github.com/LucasKalil-Programador/sand-box-python/blob/master/gifs/python+numpy.gif)
## Solução Final
Recentemente, descobri a possibilidade de compilar código em tempo de execução (JIT) usando [Numba](https://numba.pydata.org/). Embora o Numba tenha algumas limitações quanto aos tipos de dados que pode manipular, consegui adaptar o código para utilizá-lo. Isso resultou em um aumento drástico na performance, elevando a taxa de quadros para 150 a 200 fps, tornando o jogo jogável.
#### python + numpy + numba 1000 x 1000 exemplo AVG: 120 fps
![python and numpy example](https://github.com/LucasKalil-Programador/sand-box-python/blob/master/gifs/python+numpy+numba.gif)
# Como Executar e Instalar
```bash
# Clone o repositório
git clone https://github.com/LucasKalil-Programador/sand-box-python.git
# Acesse a pasta do projeto
cd sand-box-python
# Crie um novo ambiente virtual
python -m venv .venv
# Ative o ambiente virtual
# No Windows:
.venv\Scripts\activate
# No macOS/Linux:
source .venv/bin/activate
# Atualize o pip para a versão mais recente
python -m pip install --upgrade pip
# Instale as dependências do projeto
pip install .
# Execute o código
python main.py
```
# configurando propiedades
Para ajustar as configurações básicas do jogo, abra o arquivo [main.py](./main.py). No final do arquivo, você encontrará a instância da classe Game, onde é possível modificar as propriedades. Veja o exemplo abaixo:
```python
game = Game(size=(160, 160), fps=120, scale=4, font_size=30, test_mode=False)
game.run()
```
- `size`: Define o tamanho da tela como uma tupla (largura, altura).
- `scale`: Define o multiplicador do tamanho da janela. Por exemplo, com size=(160, 160) e scale=4, a janela será de 640x640 pixels (160 \* 4).
- `fps`: Define a taxa de quadros por segundo.
- `font_size`: Define o tamanho da fonte.
- `test_mode`: Ativa ou desativa o modo de teste. Quando ativado, um elemento aleatório é gerado em um local aleatório a cada quadro, o que é útil para testar a performance e a estabilidade.
# Elementos e Controle
- `Background` elemento padrao nao possui nenhum efeito especial
- `Sand` comportase como areia possui gravidade e afunda na agua
- `Water` simula um fluido portanto tende a se acomodar e escorrer em superficies
- `Stone` elemento estatico nao se move e impede a passagem de outros elemento
- `Vacuum` exclui elementos que entram em contato
- `Cloner` copia o primeiro elemento que o toca e gera mais desse elemento a cada quadro
## Controle
- Números de `1 a 6` controlam o elemento selecionado, seguindo a ordem anterior.
- Use o botão esquerdo do mouse para gerar (spawn) o novo elemento.
- Pressione a tecla `+` para aumentar o tamanho do spawn e `-` para diminuir.
- Segure `CTRL` + `+` ou `CTRL` + `-` para aumentar ou diminuir o tamanho do spawn em incrementos de 10.
### exemplo
![exemplo](https://github.com/LucasKalil-Programador/sand-box-python/blob/master/gifs/example1.gif)
# Contribuições
Infelizmente, este projeto está descontinuado. Caso você queira fazer alguma adição ou melhoria, sinta-se à vontade para fazer um fork e modificar o código para uso próprio.
## Licença
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](./LICENCE) para mais detalhes.
## Contato
Lucas - [lucas.prokalil2020@outlook.com](mailto:lucas.prokalil2020@outlook.com)
Repositório no GitHub: [sand-box-python](https://github.com/LucasKalil-Programador/sand-box-python)