Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

alphasil

Movimento imagem com KeyListener

Mensagens Recomendadas

alphasil

Olá

Mais uma vez de volta com um problema, tenho 3 classes que representam um pequeno jogo.

O problema é que o movimento não me funciona, devo usar as setas direcionais para mover o objeto da esquerda para a direita e não me está a dar.

import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class main extends JFrame implements KeyListener{

   private static final long serialVersionUID = 1L;
   private jogador jg;
   private Image img;
   private Graphics graphics;
   //Fica static por causa do método atualizar
   public static boolean jogDireita =false;
   public static boolean jogEsquerda =false;

 public main()
 {

  setTitle("Trabalho Final GMC");
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setSize(600,400);
  setBackground(Color.WHITE);
  setResizable(true);
  //Adiciona "escuta de keys"
  addKeyListener(this);
  //Poe a janela como visivel
  setVisible(true);

  //Canhão
  jg= new jogador(300, 350 , 20, 20,"imagens/cannon.gif");

  //Bugs

 }

 public void paint(Graphics g)
 {
  img = createImage(getWidth(), getHeight());
  graphics =img.getGraphics();
  g.fillRect(0, 0, getWidth(), getHeight());
  paintComponent(graphics);
  g.drawImage(img, 0, 0, null);
  repaint();
 }

 public void paintComponent(Graphics g)
 {
  jg.desenho(g);
 }

 @Override
 public void keyPressed(KeyEvent e) {
  // TODO Auto-generated method stub

 }
 @Override
 public void keyReleased(KeyEvent e) {
  // TODO Auto-generated method stub

 }
 @Override
 public void keyTyped(KeyEvent e) {
  // TODO Auto-generated method stub

 }

 public boolean keyDown(Event evt, int key)
 {
  switch (key)
  {
  case Event.LEFT:  jg.esquerda();  break;
  case Event.RIGHT: jg.direita(); break;
  case Event.DOWN:  jg.disparar();   break;
  default:							    break;
  }
  return true;
 }
 public static void main(String args[])
 {
  new main();
 }
}

Classe objetos

import java.awt.Graphics;
import java.awt.Image;
//Abstract porque Não se pode criar uma instância desta classe
public abstract class objetos {

protected Image jog;
protected int posX;
protected int posY;
protected int altura;
protected int largura;
//Não cria uma instância, as mesmas estão nas subclasses
abstract void desenho(Graphics g);

//abstract void atualizar(final main principal, final int id);

abstract Image getImage(String jog);

//Retorno
public Image getJog() {
 return jog;
}

//Definição
public void setJog(Image jog) {
 this.jog = jog;
}
public int getPosX() {
 return posX;
}
public void setPosX(int posX) {
 this.posX = posX;
}
public int getPosY() {
 return posY;
}
public void setPosY(int posY) {
 this.posY = posY;
}
public int getAltura() {
 return altura;
}
public void setAltura(int altura) {
 this.altura = altura;
}
public int getLargura() {
 return largura;
}
public void setLargura(int largura) {
 this.largura = largura;
}
}

Por fim a minha classe jogador

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
//Classe do jogador, pede imagem e posições
public class jogador extends objetos
{
/**Cria a instância de jogadores
protected Image jog;
protected int posX;
protected int posY;
protected int altura;
protected int largura;
*/
public jogador(final int posX, final int posY, final int altura, final int largura, final String jog)
{
 this.jog= getImage(jog);
 this.posX= posX;
 this.posY= posY;
 this.altura=altura;
 this.largura=largura;
}
public void desenho(Graphics g)
{
 g.drawImage(jog, posX, posY, altura, largura, null);

}

@Override
Image getImage(String jog) {
 return Toolkit.getDefaultToolkit().getImage(jog);
}
public void esquerda()
{
 posX=300;
 posX--;
}
public void direita()
{
 posX=300;
 posX++;

}
public void disparar()
{
 // TODO Auto-generated method stub

}
}

Erros não tenho...deve ser um pequeno pormenor que me está a escapar mas não estou a ver.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

a imagem anda ... 1 pixel para cada lado de 300

a imagem começa com o valor de 300 (em x) e depois de carregares nunca tecla nunca terá outro valor que não seja 299 ou 301.


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

a cada evento do teclado:

public boolean keyDown(Event evt, int key)
{
 switch (key)
 {
   case Event.LEFT:  jg.esquerda();  break;
   case Event.RIGHT: jg.direita(); break;
   case Event.DOWN:  jg.disparar();   break;
   default: break;
 }
 return true;
}

no entanto, nas chamadas efectuadas tens o seguinte código:

public void esquerda()
{
 posX=300;
 posX--;
}
public void direita()
{
 posX=300;
 posX++;
}
public void disparar()
{
 // TODO Auto-generated method stub
}

que valor tem a variável jogador.posX depois de carregar uma vez na seta da direita ?

e na segunda ?

e na terceira ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

De volta

Agora funciona para o lado esquerdo mas para o lado direito não

void atualizar(final main principal, final int id)
{
 if (id==1)
 {
  if(main.movEsquerda)
  {
   if(!(posX<10))
   {
 posX--;
   }
   else if(main.movDireita)
   {
 if(!(posX>main.getPosX() -530))
 {
  posX++;
 }
   }
  }
 }

Tenho uma área de 600 por 400, devia dar..

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

aconselho-te sinceramente a estudar muito mais

1º - nem faço ideia que parte do código é esse

2º - não faço ideia porque raio tens esse código, não encaixa nada no modelo apresentado anteriormente

3º - se abrisss os olhos, verias onde está o problema

solução : LÊ, porque um problema destes é de quem aprendeu a programar à 2 semanas


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Epahhh

Não digo que não tens razão, mas sinceramente não estou a ver no código que me indicaste qual o problema.

A variavel inicia com 300 no ficheiro main,

jg= new jogador(300, 350 , 20, 20,"imagens/cannon.gif");

e ao clicar na tecla esquerda chama a função esquerda() da classe jogador que tem no seu interior isto:


public void esquerda()
{
posX--;
}

Essa parte que pus agora foi de outra forma que tentei, funciona, mas só para o lado esquerdo.

Obrigado na mesma

Editado por alphasil

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

void atualizar(final main principal, final int id)
{
 if (id==1)
 {
  if(main.movEsquerda)
  {
   /* TODO ESTE CÓDIGO SÓ É EXECUTADO SE "main.movEsquerda" FOR VERDADEIRO
   if(!(posX<10))
   {
    posX--;
   }
   else if(main.movDireita)
   {
    if(!(posX>main.getPosX() -530))
    {
     posX++;
    }
   }
   */
  }
 }

código (minimamente) indentado para nada ...

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Fogo

Um estupor de um parêntese neste código, agora já dá, já se movimente de um lado para o outro.

Já agora HHH, que está mal no outro código se faz favor?

Obrigado pela paciência

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Este :P

a cada evento do teclado:

public boolean keyDown(Event evt, int key)
{
 switch (key)
 {
case Event.LEFT:  jg.esquerda();  break;
case Event.RIGHT: jg.direita(); break;
case Event.DOWN:  jg.disparar();   break;
default: break;
 }
 return true;
}

no entanto, nas chamadas efectuadas tens o seguinte código:

public void esquerda()
{
 posX=300;
 posX--;
}
public void direita()
{
 posX=300;
 posX++;
}
public void disparar()
{
 // TODO Auto-generated method stub
}

que valor tem a variável jogador.posX depois de carregar uma vez na seta da direita ?

e na segunda ?

e na terceira ?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Mas eu pus assim e não mexia nada...

Mas enfim, já está uma parte.

Uma pergunta....desculpa a maçada, tenho uma classe "alvos" que é herdeira da classe "objetos".

Como vou ter de instanciar vários objetos (12 - alvos) no écrã, posso meter isso num hashmap ou hashtable, a segunda é sincrozinada e não permite null, que achas??

Obrigado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Mas eu pus assim e não mexia nada...

mexia .... 1 pixel

o evento keydown é executado somente uma vez quando precionas a tecla.

Uma pergunta....desculpa a maçada, tenho uma classe "alvos" que é herdeira da classe "objetos".

Como vou ter de instanciar vários objetos (12 - alvos) no écrã, posso meter isso num hashmap ou hashtable, a segunda é sincrozinada e não permite null, que achas??

vais ordenar o container ?

usa arraylist ...


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

ps :

só para te abrir a mente

se fosse eu a avaliar a gestão de movimento, numa escala de 0 a 20, só daria 12

não tens qualquer tipo de código de gestão de velocidade, além do problema pior, de que o código é dependente da velocidade de execução


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

ArrayList não dá, diz:

The method add(int, alvos) in the type ArrayList<alvos> is not applicable for the arguments (int, int, int, int, String)

Instancio assim o objeto alvos no main

bug= new alvos(50, 50 , 70, 70,"imagens/bug.gif");

Agora ter de fazer isso doze vezes assim..

bug= new alvos(50, 50 , 70, 70,"imagens/bug.gif");
  bug1=new alvos(145, 50 , 70, 70,"imagens/bug1.gif");
  bug4= new alvos(225, 50 , 70, 70,"imagens/bug.gif");
  bug5= new alvos(305, 50 , 70, 70,"imagens/bug1.gif");
  bug6= new alvos(385, 50 , 70, 70,"imagens/bug.gif");
  bug7=new alvos(480, 50 , 70, 70,"imagens/bug1.gif");

E ter de declarar 12 variáveis também....o prof não vai achar muita piada.

ps :

só para te abrir a mente

se fosse eu a avaliar a gestão de movimento, numa escala de 0 a 20, só daria 12

não tens qualquer tipo de código de gestão de velocidade, além do problema pior, de que o código é dependente da velocidade de execução

Mais uma dica, preciso de gerir a velocidade... :)

Para já o principal acha que era pôr isso a mexer, agora é meter os objetos e depois passo para isso.

Obrigado pelas dicas

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

The method add(int, alvos) in the type ArrayList<alvos> is not applicable for the arguments (int, int, int, int, String)

reparaste que não apresentaste o código que deu o erro ????

ArrayList<alvos> lista = new ArrayList<alvos>();
lista.add(new alvos(50, 50 , 70, 70,"imagens/bug.gif"));


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

És mesmo crânio nisso, és engenheiro informático??

e isso interessa ?

tenho mais consideração por muitos autodidactas que sabem o que fazem que muitos engenheiros que pensam que sabem o que fazem

e sim, sou engenheiro informático


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Logo vi, com a simplicidade que respondes às questões que o pessoal põe.

É preciso muito saber e experiência para fazer o que fazes, e a forma como ajudas o pessoal não tem palavras.

Já criei os objetos todos, agora para eles aparecem não me aceita

public void paintComponent(Graphics g)
{
 jg.desenho(g);
 bugs.desenho(g); //The method desenho(Graphics) is undefined for the type ArrayList<alvos>
 jg.atualizar(this, 1);
}

Deve ser por causa de ser do arrayList visto que a classe alvos também usa

public void desenho(Graphics g)
{
 g.drawImage(jog, posX, posY, altura, largura, null);

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

ArrayList é uma collection !!! é obvio que não existe esse método declarado !!!

http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html

ou derivas o ArrayList de forma a declarar essa função

public class BugList extends ArrayList<Bug>
{
 public void desenho(Graphics g)
 {
   // iterar todos os elementos no arraylist e chamar a função desenho a cada
 }
}

// agora sim o teu código funciona

ou terás de fazer a iteração na chamada paintComponent

public void paintComponent(Graphics g)
{
 jg.desenho(g);

 // iterar todos os elementos no arraylist e chamar a função desenho a cada

 jg.atualizar(this, 1);
}


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
alphasil

Já pus

public void paintComponent(Graphics g)
{
 jg.desenho(g);
 for(alvos bg: bugs)
 {
  bg.desenho(g);
 }
 jg.atualizar(this, 1);
}

Agora sim aparecem,

Próxima fase, velocidade como aconselhaste, e balas.

Obrigado por tudo.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

1º - tens de saber quanto tempo decorreu entre frames consecutivos

2º - tens de definir uma velocidade para o objecto (lembrate que estás em |R2)

3º - a actualização da nova posição do objecto depende da velocidade e do tempo decorrido


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.