Definir Structs

14 Respostas   610 Visualizações

0 Membros e 1 Visitante estão vendo este tópico.

Lima

Tópico criado em: 17/01/2016 às 20:32

Olá pessoal, como defino estrutura em JS? Ou será que é objeto? Estou habituado ao C e agora não estou a conseguir definir e colocar o valor num array, exemplo:

Em C:


Código: [Selecionar]
typedef struct info {
   
int id, hp, mp;
   
}INFO;


Depois definia:

Código: [Selecionar]
INFO info[100];
E depois pa guardar um valor seria:

Código: [Selecionar]
info[0].hp = 450;
Como faço isto em JS?

Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 1: 18/01/2016 às 10:38

EDIT: Os códigos nos spoilers ficam "amassados" :v Clica no [Selecionar] e cola num notepad ou qualquer coisa só para ver eles melhor.

Olá Lima.

Como você vem do C, explicarei um pouco sobre a ideia de objetos dentro do spoiler e deixarei em outro ao fim os conceitos que eu enumerar com [n], para nível de conhecimento ;D

Spoiler
[close]

Enfim, acima só para introduzi-lo à orientação a objetos para não criar alguns maus-costumes já que você veio do C (não digo que C é ruim, mas é bom pensar um pouco mais OO quando estiver com OO - não excessivamente i.e. não criando classes para tudo).

Respondendo diretamente sua pergunta, JS trata objetos como funções. Então para estabelecer a definição da sua classe (classe != objeto, objeto é a instanciação de uma classe, e classe é o "esqueleto" - no seu exemplo, se fosse com classes, INFO era uma classe e info[] seria um array de objetos do tipo INFO), você cria essa função:

Código: [Selecionar]
// Acostume-se com os padrões: Classes possuem primeira letra maiúscula e as outras minúsculas
// Nomes compostos devem seguir o padrão de primeira letra de cada palavra ser maiúscula
//   =>  Ex: GameActor, SceneManager, TileMap.
// Seguindo o mesmo exemplo em Ruby no spoiler, enviar HP e MP iniciais por parâmetro:
function Info (hp, mp) {
  // Ao contrário das linguagens OO em geral, JS considera o escopo da classe como já sendo o construtor dela
  this.id = gen_info_id();
  this.hp = hp;
  this.mp = mp;

  // Definição de uma função membro acontece também no construtor:
  this.apply_damage = new function(amount) {
    this.hp -= amount;
    if this.hp < 0 {
      this.hp = 0;
    }
  }
}

// Instanciando uma nova Info:
var example = new Info(450, 80);
alert(example.hp); // => 450
example.apply_damage(30);
alert(example.hp); // => 420
example.apply_damage(500);
alert(example.hp); // => 0

Creio que possa utilizar o exemplo acima como base ;)

Quanto a ter arrays, em JS arrays são criadas dinamicamente, ou seja, se você disser my_array[99] = 20, ele já vai estender o my_array para possuir 100 valores (já que começa em 0, my_array[0] é o 1º índice e my_array[99] é o 100º índice). Existe uma forma de inicializar já com tamanho fixo, mas não recomendo muito confiar nela por ser ambígua, que seria no caso:

Código: [Selecionar]
var my_array = new Array(4);
Isso instancia my_array com 4 valores.
É bom que você tenha em mente o que você está fazendo, pois:

Código: [Selecionar]
var my_array = new Array('4');
Instancia my_array contendo o valor '4' (i.e. my_array.length retorna 1).

(OBS: an_array.length retorna o tamanho do array.)

SO que é preferível é que você nunca precisa inicializar o array com um tamanho fixo, e sim vá alocando conforme o tempo, i.e. toda vez que você tiver um novo herói (no seu caso, Info):

Código: [Selecionar]
my_array.push(new Info(100, 20));
Ou se precisar instanciar a Info antes de inserir no my_array:

Código: [Selecionar]
var info = new Info(100, 20);
// ...
// faz algo com `info`
// ...
my_array.push(info);

No mais é isso.

Definições que mencionei na parte de objetos:
Spoiler
[close]
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 2: 18/01/2016 às 15:51 - Última modificação por Lima em 18/01/2016 às 16:05

Bem, eu acho que fiquei a perceber mais ou menos, aquilo de somar constantes já me tinha apercebido porque criei uma variável e somei-lhe um valor e dava erro, enfim, estava a usar outra variável e não dá erro não percebo s:

Código: [Selecionar]
do
{
y = Math.floor(Math.random() * 4 + 1);
aux = 0;
for(x=1; x < 3; x++){
if(card[x] == y){
aux = aux + 1;
}
}
}while(aux != 0 && card[y] == '0');



Para criar arrays, estou usando isso, não sei se é correto!

Código: [Selecionar]
cardId= new Array();

Quanto ao HP MP e ID aproveitei o objeto dos inimigos e estou a trabalhar com ele!

Eu estou a fazer tudo por chamar script visto que não consigo criar uma função e depois chamá-la por script, poderá me ensinar a fazer isso?


Valeu mesmo cara!

Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 3: 18/01/2016 às 16:26 - Última modificação por Alucard_2 em 18/01/2016 às 16:30

Okay, só uma pontuação aqui: cuidado com a identação xD Identar é importante.

Enfim, estou tentando entender um pouco qual seria o objetivo do seu código.
Poderia dar uma explicada com palavras qual seria o objetivo?

Outro detalhe é que usas "cardID" para inicializar o Array, mas "card" dentro do for.
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 4: 18/01/2016 às 16:35

Na verdade eu inicio os dois xD

É um sistema de cartas tipo yu gi oh xD e então eu uso o cardId, onde vou armazenar o id que vai fazer ligação ao objeto dos inimigos e daí tiro hp, ataque, etc...

O card, verifica se a carta já saiu, ou seja, é um array que guarda os ids das cartas que já sairam!


Código: [Selecionar]
var i, x, y=1, aux;var card = new Array();$gameVariables.setValue(2, 0);for(i=1; i < 3; i++){do{y = Math.floor(Math.random() * 4 + 1);
aux = 0;
for(x=1; x < 3; x++){
if(card[x] == y){
aux = aux + 1;
}}}while(aux != 0 && card[y] == '0');
$gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
$gameVariables.setValue(2, $gameVariables.value(2) + 300);


card[i] = y;
}

Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 5: 18/01/2016 às 18:04

Welp, alguns detalhes:

Código: [Selecionar]
var card = new Array();Como você não está definindo o tamanho do array, é preferível que faça:
Código: [Selecionar]
var card = [];
Outro detalhe: Nada de dois códigos na mesma linha. Separe sempre. O mesmo vale para fechar chaves: Uma "fechada" de chaves por linha. O mesmo código formatado mais corretamente:

Código: [Selecionar]
var i, x, y=1, aux;
var card = new Array();
$gameVariables.setValue(2, 0);
for(i=1; i < 3; i++){
do{
  y = Math.floor(Math.random() * 4 + 1);
    aux = 0;
    for(x=1; x < 3; x++){
      if(card[x] == y){
      aux = aux + 1;
    }
    }
  } while(aux != 0 && card[y] == '0');
  $gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
  $gameVariables.setValue(2, $gameVariables.value(2) + 300);

  card[i] = y;
}

Lembre-se de que deixar dois códigos na mesma linha não vai aumentar/diminuir o número de instruções que seu programa irá executar ;)
E 1 linha por código ajuda bastante na legibilidade inclusive.

Outro detalhe: abriu chaves ({)? Idente (i.e. insira 2 espaços no início da linha).

Mas, enfim, ainda estou tentando entender alguns detalhes do seu script.
Por exemplo:

Código: [Selecionar]
for (i=1; i<3; i++) {
O for é executado por...? E por que o intervalo é de 1 a 3?

Minha sugestão, pegue este trecho:

Código: [Selecionar]
// Executa 2 vezes por...??
for (i = 1; i < 3; i++) {
  do {
    // `y` representa...??
    y = Math.floor(Math.random() * 4 + 1);
    // `aux` representa...??
    aux = 0;
    // Executo 2 vezes (1..3-1 = 1..2 = 2 vezes) porque...??
    for (x=1; x < 3; x++) {
      // Estou comparando se...??
      // No caso, `card[x]` representa ?? e y representa ??
      if (card[x] == y) {
      aux = aux + 1;
    }
    }
  // Precisa continuar acontecendo enquanto...??
  } while (aux != 0 && card[y] == '0');
  // ??
  $gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
  // ??
  $gameVariables.setValue(2, $gameVariables.value(2) + 300);

  // ??
  card[i] = y;
}

E complete os "??" com o que a linha seguinte representa no sistema, e.g. "Preciso gerar 3 cartas, portanto, um for de 0 a 3", "Comparo se a carta atual já está contida em `card`", etc...

Note que ainda estou lutando para entender o que cada passo do seu código representa.
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 6: 18/01/2016 às 18:14 - Última modificação por Lima em 18/01/2016 às 18:19

Tá tudo na mesma linha porque o chamar script só permite x linhas entende? xD Tem um máximo

Código: [Selecionar]
// Executa 2 vezes por...?? Na verdade em vez de ter 3 vai ter 6, vai executar 5 vezes para escolher 5 cartas que o jogador vai ter pa jogar
for (i = 1; i < 3; i++) {
  do {
    // `y` representa...?? Representa a carta que vai ser escolhida, em vez de 4 vai estar o total de cartas
    y = Math.floor(Math.random() * 4 + 1);
    // `aux` representa...?? aux uma variável para saber se entrou no if, se entrou ela vai aumentar seu valor, representa que o jogador já possui essa carta
    aux = 0;
    // Executo 2 vezes (1..3-1 = 1..2 = 2 vezes) porque...?? em vez de 3 será card.lenght
    for (x=1; x < 3; x++) {
      // Estou comparando se...?? Esta a comparar se a carta já está a ser mostrada
      // No caso, `card[x]` representa ?? e y representa ?? card[x] representa o id das cartas que já foram mostradas
      if (card[x] == y) {
      aux = aux + 1;
    }
    }
  // Precisa continuar acontecendo enquanto...?? na verdade é ou e não e, ele continua enquanto o aux for diferente de zero, tipo se passar no if quer dizer que essa carta já esta mostrada o == '0', deixo os arrays todos a 0, enquanto não possui carta
  } while (aux != 0 || card[y] == '0');
  // ?? Mostra a carta no jogo
  $gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
  // ?? Aumenta a distancia entre as cartas
  $gameVariables.setValue(2, $gameVariables.value(2) + 300);

  // ?? define que a carta ja foi mostrada, guarda para depois comparar em cima
  card[i] = y;
}

Bem acho que ficou meio confuso s:

Imagine que tem 4 cartas e quer mostrar 3 cartas, então ele executa esse codigo para as cartas não serem iguais xD


Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 7: 18/01/2016 às 18:42

Oh certo, fica muito mais claro agora.

Certo certo, então aí já é a "cena do duelo".
Você pode fazer isso de outra forma. E quanto ao limite de linhas desculpe, havia esquecido desse detalhe.

Arrays em JavaScript possuem um método "indexOf", eis a documentação do método:

Citar
The indexOf() method searches the array for the specified item, and returns its position.

The search will start at the specified position, or at the beginning if no start position is specified, and end the search at the end of the array.

Returns -1 if the item is not found.
(Retirado de: http://www.w3schools.com/jsref/jsref_indexof_array.asp)

Ou seja, se você chamar `array.indexOf(obj, 0)`, há duas possibilidades:
  • O índice de `obj` no array chamado `array`, caso exista;
  • Caso não `array` não contenha `obj`, o resultado é -1.


Perceba que isso facilita: agora é só comparar se o índice é maior do que -1 (porque se o índice é -1, então cards não possui y, e portanto já pode parar de randomizar, porém se for > -1, significa que y já está em cards e portanto precisa randomizar de novo):

Código: [Selecionar]
// Removi "i" da declaração: ela pode ser criada no escopo do for (já que só será utilizada dentro dele) ;)
// Também removi "aux", já que não será mais necessária.
var x, y=1;
var cards = [];
$gameVariables.setValue(2, 0);
for (var i = 1; i < 3; i++) {
  do {
    y = Math.floor(Math.random() * 4 + 1);
  } while (cards.indexOf(y, 0) > -1);
  // Adiciona y ao fim de cards
  cards.push(y);
  $gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
  $gameVariables.setValue(2, $gameVariables.value(2) + 300);
}

Com isso já se reduz boa parte do código.

RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 8: 18/01/2016 às 18:50

Essa do indexOf não sabia, obrigado xD

Não intendo como aí adiciona o y xD push?
Código: [Selecionar]
cards.push(y);
Não teria como eu criar uma função, sei la baralharcartas(){

aqui o código

}

e chamar por script? Para o código ficar bem formatado?

Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 9: 18/01/2016 às 18:54 - Última modificação por Alucard_2 em 18/01/2016 às 18:56

Sim e sim.

O push sempre adiciona ao fim do array.
Só exemplificando o uso do push:

Código: [Selecionar]
arr = []; // => []
arr.push(5); // => [5]
arr.push(10); // => [5, 10]
arr.push(-1); // => [5, 10, -1]
arr.push([1, 2, 3]); // => [5, 10, -1, [1, 2, 3]]
arr.push('Something'); // => [5, 10, -1, [1, 2, 3], 'Something']

Quanto a isso ser uma função:

Código: [Selecionar]
function riffle() {
  var x, y = 1;
  var cards = [];
  $gameVariables.setValue(2, 0);
  for (var i = 1; i < 3; i++) {
    do {
      y = Math.floor(Math.random() * 4 + 1);
    } while (cards.indexOf(y, 0) > -1);
    cards.push(y);
    $gameScreen.showPicture(i, cardName[y], 0, 0 + $gameVariables.value(2), 0, 70, 70, 255, 0);
    $gameVariables.setValue(2, $gameVariables.value(2) + 300);
    return cards; // < Não sei se externamente você vai precisar saber quais cartas foram "sacadas", então, se não for precisar saber, só exclua esta linha
  }
}

(Riffle = "Embaralhar cartas" em inglês)
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 10: 18/01/2016 às 18:59

Percebi o push, ty! ahah

Eu coloquei a função e chamei-a via script, o problema é que só mostra uma carta s: quando deviam ser 2

Chamei desta forma:
Código: [Selecionar]
riffle();

Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 11: 18/01/2016 às 19:14

Huum, isso pode ter a ver com o range dos for's.

Tente por o for para ser de 0 a 10 e ver o que acontece.

EDIT: E, claro, mude no random() * 4 para 11 ou 12.
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 12: 18/01/2016 às 19:20

Se eu colocar na consola irá aparecer 2, mas se colocar como plugin só aparece uma!

o for tem de começar a 1 visto que uso o objeto dos inimigos para armazenar os valores de ataque etc, e como o a posição 0 é nula, para coincidir o id da carta com o do monstro é mais fácil assim, se meter o random a 10 ou 11 ele irá escolher uma carta que não tem, ou seja, não irá aparecer carta.


Alucard_2

  • *
  • Posts: 102
  • Ouros: 75
  • Confesso que estou tendo um caso com o Nandik
Resposta 13: 18/01/2016 às 19:26

Podes então aumentar o número de monstros? (ou talvez só mudar de 3 para 6 no "i < 3" do for)
Acho um tanto quanto estranho. Inclusive nos testes que fiz aqui (comentei as variáveis do maker para testar aqui, já que não possuo o maker) ele gerava um array com 2 valores para cards.
RPG Maker Brasil.net Está de Volta!!! > http://www.rpgmakerbrasil.net/forum

Avatar by: Driko

http://i.imgur.com/cHNwiLZ.png

Lima

Resposta 14: 18/01/2016 às 19:29 - Última modificação por Lima em 18/01/2016 às 20:51

O i eu coloquei-o até 10! É estranho mesmo, funcionar na consola e como plugin não :o

EDIT: Na verdadee foi um erro meter o i para mais valores visto que não existe, o script ficava bloqueado e nunca atualizava, já está resolvido xD

Obrigado!