leonardoSaaads /
RustEm30Dias
O presente repositório é destinado ao aprendizado da linguagem de programação Rust. A meta estabelecida é ter uma noção prática, em 30 dias, da linguagem.
49/100 healthLoading repository data…
weldercsz / repository
Repositorio destinado a impelmentações baseadas na Linguagem Rust
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Jogo feito na disciplina TECVII- Universidade federal de Pelotas Baseado no exemplo encontrado na biblioteca ggezÇhttps://github.com/ggez/ggez
REFERENCIAS https://rust-br.github.i
https://github.com/ggez/ggez/blob/master/examples/04_snake.rs
https://github.com/deckarep/flappy-rust
https://www.youtube.com/watch?v=DnT_7M7L7vo&t=464s
https://www.youtube.com/watch?v=iR7Q_6quwSI&t=2172s
https://www.youtube.com/watch?v=AYfehnFklkA
https://www.youtube.com/watch?v=8DUENLiOfiQ&t=1868s
Não esquecer de usar a biblioteza GGEZ ggez
```
//fn main() -> GameResult {
// Primeiro, criamos uma estrutura `ggez::Conf` que define as configurações do nosso jogo.
let (ctx, event_loop) = ggez::ContextBuilder::new("Jogo da Cobrinha-=TECVII", "welder")
// Primeiro, criamos uma estrutura `ggez::Conf` que define as configurações do nosso jogo.
.window_setup(ggez::conf::WindowSetup::default().title("Jogo da Cobrinha!!!"))
// Em seguida, chamamos a função `ggez::ContextBuilder::new` para criar um `ContextBuilder`,
// que nos permitirá personalizar como queremos que o contexto seja criado.
.window_mode(
ggez::conf::WindowMode::default()
.dimensions(SCREEN_SIZE.0 as f32, SCREEN_SIZE.1 as f32),
)
// CASO DE ERRADO, VAI DAR RUIM!!!!!!
.build()
.expect("DEU RUIM!!!!!!");
// Em seguida, criamos uma instância do nosso `GameState` e a passamos para a função
// `ggez::event::run` para iniciar o loop principal do jogo.
let state = GameState::new()?;
event::run(ctx, event_loop, state)
}
```
```
// Primeiro, importaremos as crates de que precisamos para o nosso jogo;
// neste caso, apenas ggez e rand.
// Em seguida, precisamos realmente "usar" as partes do ggez que iremos
// precisar com frequência.
use ggez::event::KeyCode;
use ggez::{event, graphics, Context, GameResult};
// Vamos trazer algumas coisas do std para nos ajudar no futuro.
use std::collections::LinkedList;
use std::time::{Duration, Instant};
// E, finalmente, trazemos a trait Rng para o escopo para que possamos gerar
// alguns números aleatórios mais tarde.
use rand::Rng;
// de inicio devo fazer é configurar algumas constantes .
// Aqui defini o tamanho tabuleiro de jogo em termos de quantas células da grade ele ocupará.
//opetei fazer um tabuleiro de 30 x 20.
const GRID_SIZE: (i16, i16) = (30, 20);
// Agora definimos o tamanho em pixels de cada célula, que será de 32x32 pixels.
const GRID_CELL_SIZE: (i16, i16) = (32, 32);
// Em seguida,aqui o quão grande queremos que nossa janela seja, multiplicando
// os componentes do nosso tamanho de grade pelo tamanho de pixel correspondente.
const SCREEN_SIZE: (u32, u32) = (
GRID_SIZE.0 as u32 * GRID_CELL_SIZE.0 as u32,
GRID_SIZE.1 as u32 * GRID_CELL_SIZE.1 as u32,
);
// Quatidade das vezes queremos que nosso jogo seja atualizado por segundo.
// para que nossa cobra não se mova muito rápido na tela
// porque está se movendo uma célula inteira a cada quadro.
const UPDATES_PER_SECOND: f32 = 8.0;
// E obtemos os milissegundos de atraso correspondentes a essa taxa de atualização.
const MILLIS_PER_UPDATE: u64 = (1.0 / UPDATES_PER_SECOND * 1000.0) as u64;
// Estrutura que conterá a posição de uma entidade em nosso tabuleiro de jogo
// ou grade acima. Usamos inteiros com sinal porque queremos armazenar apenas números inteiros,
// e precisamos que sejam com sinal para que funcionem corretamente com nossa aritmética de módulo posteriormente.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
struct GridPosition {
x: i16,
y: i16,
}
// Esta é uma trait que fornece uma função de módulo que funciona para valores negativos
// em oposição ao operador de resto padrão (%) que não o faz. Vamos usá-lo
// para fazer com que nossa cobra se mova de um lado do tabuleiro para o outro
// quando sair da parte superior, inferior, esquerda ou direita da tela.
trait ModuloSigned {
fn modulo(&self, n: Self) -> Self;
}
// Aqui implementamos a trait `ModuloAssinado` para qualquer tipo T que implemente
// `Add` (o operador `+`) com um tipo de saída T e Rem (o operador `%`)
// que também tem um tipo de saída T, e que pode ser clonado. Estas são as limitações
// de que precisamos para implementar uma função de módulo que funcione para números negativos.
impl<T> ModuloSigned for T
where
T: std::ops::Add<Output = T> + std::ops::Rem<Output = T> + Clone,
{
fn modulo(&self, n: T) -> T {
// Devido às nossas limitações de trait, agora podemos aplicar esses operadores.
(self.clone() % n.clone() + n.clone()) % n
}
}
impl GridPosition {
// Criamos uma função auxiliar padrão para que possamos criar uma nova `PosicaoGrade`
// mais facilmente.
pub fn new(x: i16, y: i16) -> Self {
GridPosition { x, y }
}
// Assim como uma função auxiliar que nos dará uma `PosicaoGrade` aleatória de
// `(0, 0)` a `(max_x, max_y)`
pub fn random(max_x: i16, max_y: i16) -> Self {
let mut rng = rand::thread_rng();
// Podemos usar `.into()` para converter de `(i16, i16)` para uma `PosicaoGrade` já que
// implementamos `From<(i16, i16)>` para `PosicaoGrade` abaixo.
(rng.gen_range(0..max_x), rng.gen_range(0..max_y)).into()
}
// Faremos outra função auxiliar que leva uma posição de grade e retorna uma nova após
// fazer um movimento na direção de `dir`. Usamos nossa trait `ModuloAssinado` acima,
// que agora está implementada em `i16` porque ela atende aos requisitos da trait,
// para fazer o movimento automaticamente se deslocar dentro do nosso tamanho de grade
// se o movimento tivesse de outra forma nos movido para fora do tabuleiro para o topo,
// parte inferior, esquerda ou direita.
pub fn new_from_move(pos: GridPosition, dir: Direction) -> Self {
match dir {
Direction::Up => GridPosition::new(pos.x, (pos.y - 1).modulo(GRID_SIZE.1)),
Direction::Down => GridPosition::new(pos.x, (pos.y + 1).modulo(GRID_SIZE.1)),
Direction::Left => GridPosition::new((pos.x - 1).modulo(GRID_SIZE.0), pos.y),
Direction::Right => GridPosition::new((pos.x + 1).modulo(GRID_SIZE.0), pos.y),
}
}
}
// Implementamos a trait `From` aqui, que neste caso nos permite converter facilmente entre
// uma `PosicaoGrade` e um `ggez` `graphics::Rect` que preenche aquela célula da grade.
// Agora podemos simplesmente chamar `.into()` em uma `PosicaoGrade` quando queremos um
// `Rect` que represente aquela célula da grade.
impl From<GridPosition> for graphics::Rect {
fn from(pos: GridPosition) -> Self {
graphics::Rect::new_i32(
pos.x as i32 * GRID_CELL_SIZE.0 as i32,
pos.y as i32 * GRID_CELL_SIZE.1 as i32,
GRID_CELL_SIZE.0 as i32,
GRID_CELL_SIZE.1 as i32,
)
}
}
// E aqui implementamos `From` novamente para nos permitir converter facilmente entre
// `(i16, i16)` e uma `PosicaoGrade`.
impl From<(i16, i16)> for GridPosition {
fn from(pos: (i16, i16)) -> Self {
GridPosition { x: pos.0, y: pos.1 }
}
}
// Em seguida, criamos uma enumeração que representará todas as direções possíveis
// que nossa cobra pode se mover.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Direction {
Up,
Down,
Left,
Right,
}
impl Direction {
// Criamos uma função auxiliar que nos permitirá obter facilmente o inverso
// de uma `Direcao`, que podemos usar posteriormente para verificar se o jogador deve
// ser capaz de mover a cobra em uma determinada direção.
pub fn inverse(&self) -> Self {
match *self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::Left => Direction::Right,
Direction::Right => Direction::Left,
}
}
// Também criamos uma função auxiliar que nos permitirá converter entre um
// `ggez` `KeyCode` e a `Direcao` que ela representa. Claro,
// nem todo keycode representa uma direção, então retornamos `None` se esse
// for o caso.
pub fn from_keycode(key: KeyCode) -> Option<Direction> {
match key {
KeyCode::Up => Some(Direction::Up),
KeyCode::Down => Some(Direction::Down),
KeyCode::Left => Some(Direction::Left),
KeyCode::Right => Some(Direction::Right),
_ => None,
}
}
}
// Esta é principalmente uma abstração semântica sobre uma `PosicaoGrade` para representar
// um segmento da cobra. Pode ser útil, por exemplo, ter cada segmento conter sua própria
// cor ou algo semelhante. Este é um exercício deixado ao leitor ;)
#[derive(Clone, Copy, Debug)]
struct Segment {
pos: GridPosition,
}
impl Segment {
pub fn new(pos: GridPosition) -> Self {
Segment { pos }
}
}
// Esta é novamente uma abstração sobre uma `PosicaoGrade` que representa
// uma peça de comida que a cobra pode comer. Ela pode se desenhar.
struct Food {
pos: GridPosition,
}
impl Food {
pub fn new(pos: GridPosition) -> Self {
Food { pos }
}
// Aqui é a primeira vez que vemos como o desenho funciona com ggez.
// Temos uma função que recebe uma referência a um `mut ggez::Context`, que usamos
// com as funções auxiliares em `ggez::graphics` para desenhar. Também retornamos um
// `ggez::GameResult` para que possamos usar o operador `?` para propagar falhas.
fn draw(&self, ctx: &mut Context) -> GameResult {
//Primeiro, precisamos criar um MeshBuilder
let mesh = graphics::MeshBuilder::new()
// Chamamos rectangle para criar um quadrado
.rectangle(
// Em seguida, desenhamos um retângulo com o modo de desenho Fill, e convertemos o
graphics::DrawMode::fill(),
// desde que implementamos `From<PosicaoGrade>` para `Rect` anteriormente.
// A posição da Comida em um `ggez::Rect` usando `.into()`, que podemos fazer
self.pos.into(),
// Por fim, definimos a cor para desenhar, neste caso, toda comida será
// colorida de azul.
graphics::Color::new(0.0, 0.0, 1.0, 1.0),
)?
.build(ctx)?;
graphics::draw(ctx, &mesh, graphics::DrawParam::default())?;
Ok(())
}
}
// Aqui definimos uma enumeração dos possíveis elementos que a cobra pode ter "comido"
// durante uma atualização do jogo. Ela pode ter comido um pedaço de `Comida`, ou
// ela pode ter comido `ElaMesma` se a cabeça colidir com seu corpo.
#[derive(Clone, Copy, Debug)]
enum Ate {
Itself,
Food,
}
/// Agora fazemos uma struct que contém todas as informações necessárias para descrever o
// estado da própria Cobra.
struct Snake {
// Primeiro, temos a cabeça da cobra, que é um único `Segmento`.
head: Segment,
// Em seguida, temos a direção atual da cobra. Esta é
// a direção em que a cobra se moverá quando `update` for chamado.
dir: Direction,
// Depois temos o corpo, que escolhemos representar como uma `LinkedList`
// de `Segmento`s.
body: LinkedList<Segment>,
// Agora temos uma propriedade que representa o resultado da última atualização
// que foi executada. A cobra pode não ter comido nada (None), Comida (Some(Comeu::Comida)),
// ou ElaMesma (Some(Comeu::ElaMesma))
ate: Option<Ate>,
// Finalmente, armazenamos a direção em que a cobra estava se movendo da última
// vez que `update` foi chamado, que usaremos para determinar as direções válidas
// em que ela pode se mover na pr
Selected from shared topics, language and repository description—not editorial ratings.
leonardoSaaads /
O presente repositório é destinado ao aprendizado da linguagem de programação Rust. A meta estabelecida é ter uma noção prática, em 30 dias, da linguagem.
49/100 healthsaul-rocha /
Repositório destinado a conteúdo de aprendizado da linguagem RUST
37/100 healthchristian-freire /
Repositório destinado a servidor simples desenvolvido em Rust
27/100 healthribeirojer /
Repositório destinado a armazenar códigos enquanto aprendo a linguagem Rust.
27/100 healthlucasherlon /
Repositório destinado a compartilhar meu aprendizado com a linguagem Rust.
27/100 healthJefersonFernando /
Esse repositório é destinado a estudos com a linguagem Rust.
27/100 health