• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

TheOne

Ajuda em criação de Jogo

17 mensagens neste tópico

Boas pessoal, o meu último trabalho de semestre de POO - Programação Orientada por Objectos, é fazer o Snake...ora bem. Queria perguntar-vos como é que ponho um. jpg ou .gif no background de um JPanel. Queria saber isto para fazer a interface gráfica do jogo, nomeadamente nos menus e isso.

Obrigado pessoal  :biggrin:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois, parece que pesquisei mal xD, obrigado! Mas não consegui resolver o problema. Copiei o código e ajustei ao meu programa mas não aparece nenhuma imagem no JPanel que eu quero ter a imagem como background... :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Coloca o código para se poder ver. Não tens erros nenhuns?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bom, então aqui vai o código. Na sua totalidade.

package snake;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class SnakeV2 extends JFrame implements ActionListener{

private static final long serialVersionUID = 1L;
private JPanel menu, optionPanel, scorePanel, arena;
private JLabel score;
private JPanel[] window;
private JButton newGame, options, exit, hscores, back, lb1, lb2, lb3;
private int pontos;

public SnakeV2(){
	super("Snake");
	this.setSize(450, 400);
	initializeInterface();
	createMenus();
	pontos = 0;
	score = new JLabel("Score: " + pontos);
	arena = new JPanel();
	arena.setPreferredSize(new Dimension(350, 300));
	arena.setBackground(new Color(10, 100, 15));
	pack();
}

public void actionPerformed(ActionEvent e){
	char c = e.getActionCommand().charAt(0);
	switch(c){
		case 'S':
			System.exit(0);
			break;
		case 'O':
			changeScreen(menu, optionPanel);
			break;
		case 'V':
			changeScreen(optionPanel, menu);
			break;
		case 'I':
			changeScreen(menu, arena);
			break;
		case 'T':
			changeScreen(arena, menu);
			break;
	}
}

private void changeScreen(JPanel a, JPanel b){
	a.setVisible(false);
	this.remove(a);
	this.add(b, BorderLayout.CENTER);
	b.setVisible(true);
}

private void initializeInterface(){
	window = new JPanel[4];
	menu = new JPanel();
	JLabel m = new JLabel("Menu");
	m.setHorizontalAlignment(JLabel.CENTER);
	m.setForeground(Color.BLACK);
	newGame = new JButton("Iniciar Jogo");
	newGame.addActionListener(this);
	options = new JButton("Opções");
	options.addActionListener(this);
	hscores = new JButton("Pontuações");
	hscores.addActionListener(this);
	exit = new JButton("Sair");
	exit.addActionListener(this);
	menu.setLayout(new GridLayout(5, 1, 0, 0));
	for(int i = 0; i < 4; i++){
		window[i] = new JPanel();
		window[i].setBackground(new Color(60, 200, 50));
		if(i % 2 == 0) window[i].setPreferredSize(new Dimension(400, 50));
		else window[i].setPreferredSize(new Dimension(30, 300));
	}
	menu.add(m);
	menu.add(newGame);
	menu.add(options);
	menu.add(hscores);
	menu.add(exit);
	this.add(window[0], BorderLayout.NORTH);
	this.add(window[1], BorderLayout.WEST);
	this.add(window[2], BorderLayout.SOUTH);
	this.add(window[3], BorderLayout.EAST);
	this.add(menu, BorderLayout.CENTER);
}

private void createMenus(){
	optionPanel = new JPanel();
	optionPanel.setLayout(new BorderLayout());
	JPanel mid = new JPanel();
	mid.setLayout(new GridLayout(2, 4, 10, 30));
	mid.setOpaque(false);
	JButton[] menuItems = new JButton[8];
	mid.add(new JLabel("Velocidade: "));
	for(int i = 1; i < 4; i++){
		menuItems[i] = new JButton("" + i);
		menuItems[i].addActionListener(this);
		mid.add(menuItems[i]);
	}
	mid.add(new JLabel("Labirinto: "));
	lb1 = new JButton("Fácil");
	lb1.addActionListener(this);
	lb2 = new JButton("Médio");
	lb2.addActionListener(this);
	lb3 = new JButton("Difícil");
	lb3.addActionListener(this);
	mid.add(lb1);mid.add(lb2);mid.add(lb3);
	optionPanel.setBackground(new Color(100, 180, 250));
	optionPanel.add(new JLabel("Opções"), BorderLayout.NORTH);
	back = new JButton("Voltar");
	back.addActionListener(this);
	optionPanel.add(mid, BorderLayout.CENTER);
	optionPanel.add(back, BorderLayout.SOUTH);
}

public static void main(String[] args){
	SnakeV2 s = new SnakeV2();
	s.setVisible(true);
	s.setLocation(300, 150);
	s.setResizable(false);
	s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
 

Então o que eu queria fazer era colocar uma imagem no North, South, West e East da JFrame para ter um aspecto mais apelativo...

Obrigado pela ajuda :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em lado nenhum redefines o método paint dos JPanels que estás a tentar desenhar...

Lê melhor o tópico :P, não podes usar um JPanel normal, tens de criar uma classe tua, que estenda de JPanel, e redefinir o método de desenho para que, em vez de desenhar apenas a cor de fundo, desenhe também uma imagem.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hmm, estou a ver...vou tentar novamente! Mas depois em vez de criar um JPanel para colocar no devido lugar crio um "ImagePanel" por exemplo é?

Obrigado :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim, o problema é que um JPanel não pode ter uma imagem no fundo, não tem métodos para lá colocar a imagem.

A solução é criar uma subclasse que redefina o método de desenho e coloque essa imagem no fundo.

Se vires o tópico que indiquei e olhares para o código que lá está, é isso mesmo que se está a fazer, criar uma subclasse e indicar uma imagem que vá ser desenhada. No exemplo que coloquei estou a usar uma caminho absoluto para a imagem, terás de adaptar para ler as imagens de onde pretendes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já consegui! :P obrigado Knitter! Agora o problema é querer posicionar os componentes (botoes e labels) no ImagePanel...tenho estado a tentar com os LayoutManagers mas sem sucesso...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Esse problema já poderá ser mais complicado, dependendo de como tiveres feito o ImagePanel e de como pretendes dispor os componentes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já consegui fazer a interface gráfica toda hehe! Agora so falta fazer o proprio jogo em si, a cobra e isso. Quis adicionar um extra que n é pedido, um sistema de pontuações, que guarda num .txt. Está tudo operacional, excepto uma coisa...não me lembro como se escreve no final do ficheiro sem apagar tudo. Tipo o txt tem as pontuações e eu quero adicionar mais uma linha com a ultima pontuação obtida...tenho de ler as linhas todas e escrever novamente e dps no fim colocar a nova pontuaçao?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes usar a classe FileWritter, que permite escrever streams de caracteres. Tens um construtor que recebe dois parâmetros, o nome do ficheiro a abrir e um boolean a indicar se é para fazer append ou não.

Outra opção simples seria usares serialização.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas, estou agora a fazer a parte dos labirintos, contidos num ficheiro de texto. Tenho um método que faz load do labirinto para a Grid e para o labirinto criei uma classe Wall que estende de JComponent, defini o paintComponent e o construtor atribui uma cor às paredes do labirinto consoante a sua dificuldade.

O que se passe é que quando vou ler o ficheiro de texto, e o FileReader encontra o caracter correspondente a uma parede, quando vou criar um Wall nessa posição da Grid ele dá um erro qualquer que nem no Debug consegui entender, ele encontra o caracter, entra na classe Wall mas quando entra no construtor dá o erro no Debugger de Source not found....e na janela de variáveis aparece o seguinte:

this                     java.lang.NoSuchMethodException

arg0                   snake.Wall.coalesceEvents(java.awt.AWTEvent, java.awt.AWTEvent)

Como é que resolvo isto? Já dei não sei quantas voltas ao construtor da classe mas não consigo encontrar o que está a causar isto...

Já agora aqui vai o código do construtor da Wall e o metodo para carregar o labirinto:

public void loadLabyrinth(int labOp){
	try{
		FileReader fr = new FileReader(labPath);
		final int EOF = -1;
		int c, count = 1;
		while((c = fr.read()) != EOF){
			if(c == '#')
				arena.add(new Wall(labOp), count);
			if(c == '_')
				arena.add(null, count);
			count++;
		}
	}
	catch(Exception e){
		System.out.println("Erro ao carregar labirinto");
	}
}

import java.awt.*;
import javax.swing.JComponent;

public class Wall extends JComponent{

private static final long serialVersionUID = 1L;
private Color c;

public Wall(int n){
	if(n == 1)
		c = new Color(0, 0, 255);
	if(n == 2)
		c = new Color(255, 0, 0);
	else
		c = new Color(0, 0, 0);
	setOpaque(false);
}

Obrigado pessoal

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas pessoal, já tenho o jogo praticamente feito. Já tenho a cobra e os ratos, as tabelas de pontuação, o keylistener, interface grafica, já ta tudo. Só preciso que me dêem uma ultima dica! Tenho uma classe Actor, com 4 estados, 0 - chao, 1 - parede, 2 - cobra, 3 - rato, 4- bonus, cada um é pintado com uma cor diferente. Só não estou a conseguir é representar o Vector<Actor> que representa a cobra, nem estou a ver como vou fazer, e por isso so tenho a cabeça da cobra por enquanto, ela come os ratos e adiciona ao vector uma "vertebra" e soma os pontos...só não sei como vou "pintar" o resto da cobra, já experimentei iteradores mas sem sucesso, ou mal implementados...

Obrigado

Cumps ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vendo parte do código de como estás a apresentar a cobra seria mais fácil, sem isso, à primeira vista diria que o problema estará mesmo na forma como percorres o vector.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Este é o método para apresentar a cobra:

private void updateSnake(int left, int up, int right, int down){
	s = (Actor) arena.getComponent(currPos);
	s.setState(0);
	turn = currPos;
	if(left == 1)
		currPos = currPos - 1;
	if(up == 1)
		currPos = currPos - 30;
	if(right == 1)
		currPos = currPos + 1;
	if(down == 1)
		currPos = currPos + 30;
	s = (Actor) arena.getComponent(currPos);
	if(s.getState() == 1 || s.getState() == 2){
		closeGameSession();
	}
	if(s.getState() == 3){
		pontos = pontos + velocidade;
		snake.add(new Actor(2));
		generateRats();
	}
	if(s.getState() == 4){
		pontos = pontos + 10*((int) Math.random() + 1);
	}
	score.setText("Score: " + pontos);
	s.setState(2);
	repaint();
}

Os estados são:

0 - chão

1 - parede

2 - cobra

3 - rato

4 - bonus

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem, não vejo nada de especial no código.

Suponho que nesta linha:

snake.add(new Actor(2));

estejas a adicionar mais um segmento à cobra?

Poderá estar aí o problema, mas neste caso estou mesmo a atirar barro à parede :P

0

Partilhar esta mensagem


Link 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