Jump to content
soueu

Jogo de Tenis

Recommended Posts

soueu

Boas amigos,

Estou tentando desenvolver um jogo básico de ténis, para entender melhor como funciona o java.

O projeto chama-se jogotenis.

Classe JogoTenis:

package jogotenis;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class JogoTenis extends JPanel {

Bola ball = new Bola(this);
Raquete raquete = new Raquete(this);

public JogoTenis() {
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}

@Override
public void keyReleased(KeyEvent e) {
raquete.keyReleased(e);
}

@Override
public void keyPressed(KeyEvent e) {
raquete.keyPressed(e);
}
});
setFocusable(true);
}

private void move() {
ball.move();
raquete.move();
}

@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
raquete.paint(g2d);
}

public void FimDoJogo() {
JOptionPane.showMessageDialog(this, "Fim do Jogo", "Fim do Jogo", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}

public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Jogo De Tenis");
JogoTenis jogo = new JogoTenis();
frame.add(jogo);
frame.setSize(700, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

while (true) {
jogo.move();
jogo.repaint();
Thread.sleep(10);
}
}
}

Classe Raquete:

package jogotenis;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

public class Raquete {
private static final int Y = 330;
private static final int WIDTH = 60;
private static final int HEIGHT = 10;
int x = 0;
int xa = 0;
private JogoTenis jogo;

public Raquete(JogoTenis jogo) {
this.jogo = jogo;
}

public void move() {
if (x + xa > 0 && x + xa < jogo.getWidth() - WIDTH)
x = x + xa;
}

public void paint(Graphics2D g) {
g.fillRect(x, Y, WIDTH, HEIGHT);
}

public void keyReleased(KeyEvent e) {
xa = 0;
}

public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = -1;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = 1;
}

public Rectangle getBounds() {
return new Rectangle(x, Y, WIDTH, HEIGHT);
}

public int getTopY() {
return Y;
}
}

Classe Bola:

package jogotenis;

import java.awt.Graphics2D;
import java.awt.Rectangle;

public class Bola {
private static final int DIAMETER = 30;
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
private JogoTenis jogo;

public Bola(JogoTenis jogo) {
this.jogo= jogo;
}

void move() {
if (x + xa < 0)
xa = 1;
if (x + xa > jogo.getWidth() - DIAMETER)
xa = -1;
if (y + ya < 0)
ya = 1;
if (y + ya > jogo.getHeight() - DIAMETER)
jogo.FimDoJogo();
if (collision()){
ya = -1;
y = jogo.raquete.getTopY() - DIAMETER;
}
x = x + xa;
y = y + ya;
}

private boolean collision() {
return jogo.raquete.getBounds().intersects(getBounds());
}

public void paint(Graphics2D g) {
g.fillOval(x, y, DIAMETER, DIAMETER);
}

public Rectangle getBounds() {
return new Rectangle(x, y, DIAMETER, DIAMETER);
}
}

A parte mais básica está desenvolvida penso (Colisão entre os limites da janela, colisão da bola com a raquete e a deteção de quando a bola cai no chão), agora o que falta seria adicionar uma parede no meio do campo a dividi-lo (em que a bola quando colidir, também faz ricochete), e detectar em qual dos campos a bola cai. Alguma ajuda por favor?

Obrigado desde já!

Edited by soueu

Share this post


Link to post
Share on other sites
Ernest

Bom dia,

Tudo funciona perfeitamente, pena que no fim tenha que fechar o programa para começar outra vez.

Efetivamente, tudo funciona perfeitamente, mas falta talvez falar de THREADS e de Arquitectura Orientada Objectos

Apenas duas observações :

1- .... para entender melhor como funciona o java.

para onde foram os Threads Java ? linguagem Java <=> Threads + Classes + Objectos !

No tutorial Swing de SUN/ORACLE o código a seguir é obrigatório por causa de que Swing não é Thread Safe ...

por outro lado a raquete, bola e jogo funcionam no mesmo Thread do main(...) ?

public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
 public void run(){
				 createAndShowGUI();
}
});
}

2- Arquitetura e Concepção Orientada Objectos

--> Raquete(JogoTenis jogo)

--> Bola(JogoTenis jogo)

Uma Raquete é composta de um Jogo de Tenis ?

Uma Bola é composta de um Jogo de Tenis ?

Eu diria que um Jogo de Tênis é composto de Raquete(s) e de uma Bola.

Separar quanto mais possível a parte gráfica da parte algorítmica seria melhor talvez.

Tudo dependo do que é uma bola e uma raquete. Uma bola é um objeto gráfico ou um algoritmo e suas propriedades ou os dois ao mesmo tempo.

Quanto à parede (muro ?) no meio, talvez fale de uma rede de tênis ?

O que seria interessante talvez era de também dar uma raquete ao computador para ele poder jogar com um humano.

Cordialmente

Ernest Duarte

Edited by Ernest Duarte

Share this post


Link to post
Share on other sites
soueu

Boa tarde,

2- Arquitetura e Concepção Orientada Objectos

--> Raquete(JogoTenis jogo)

--> Bola(JogoTenis jogo)

Uma Raquete é composta de um Jogo de Tenis ?

Uma Bola é composta de um Jogo de Tenis ?

Eu diria que um Jogo de Tênis é composto de Raquete(s) e de uma Bola.

Hmm... na teoria funcionaria assim, mas na prática foi um pouco mais difícil seguir esse raciocínio...

Então qual seria a sua sugestão de código?

Quanto à parede (muro ?) no meio, talvez fale de uma rede de tênis ?

Exato, seria uma rede de tênis em que a bola faz ricochete quando colide.

O que seria interessante talvez era de também dar uma raquete ao computador para ele poder jogar com um humano.

Sim, já tinha pensado nisso também, mas primeiro queria-me focar no básico, ainda não tenho a certeza de como o fazer...

Share this post


Link to post
Share on other sites
Ernest

Bom dia,

Desculpe, não ter respondido antes, mas agora estou em vários projetos, como por exemplo um projeto Android para uma empresa e formação Cloud Computing para um centre de formação em Paris.

Por outro lado, estou preparando um Formackathon Internacional on-line em agosto para 6 pessoas selecionadas, destinado aos países da CPLP e na língua de Luís Vaz de Camões. Para saber mais o e-mail : portugalino (at) free.fr

Agora vou tentar responder a suas duvidas.

A utilização da colisão nas paredes no jogo de tênis, me parece ser o jogo do Squash mais do que o verdadeiro tênis :

http://www.funlabo.com/tennis/jeux-de-squash.htm

E verdade que de separar a parte gráfica e algorítmica (Design Pattern, MVC) não é fácil tendo em conta o facto de que neste caso estão muito interligados. E o MVC é um bocado complicado.

Mas talvez em vez de meter um terreno de tênis numa Raquete e numa Bola :

--> Raquete(JogoTenis jogo)

--> Bola(JogoTenis jogo)

Seria mais OOP, meter no terreno de tênis uma Raquete e uma Bola e em contacto com o terreno a Raquete e a Bola se metem a desenrolar a algorítmica de maneira independente e assíncrona. Tendo em conta o facto de que a Raquete é movida, controlada pelo utilizador (jogador) graças à gestão dos eventos (através dos métodos Event Handlers , CallBack), mas a Bola ela sega a sua própria historia depois da colisão, descrita pelas regras da algorítmica do jogo. Tudo isto de maneira assíncrona.

Aspectos assíncronas :

Para desenvolver este sistema é necessário levar em conta dois importantes aspectos assíncronas, em primeiro lugar a gestão dos eventos AWT/SWING e, em seguida, os Threads. Sabendo que a traz dos eventos AWT/SWING se esconde na realidade o event dispatching thread (EDT). Tendo em conta do que a maioria dos métodos de objetos AWT e Swing não são thread-safe.

Para mais informações sobre EDT : http://en.wikipedia.org/wiki/Event_dispatching_thread

Está descrito no tutorial ( http://docs.oracle.com/javase/tutorial/uiswing/ ) a utilização de SwingUtilities.invokeLater (....)

Concepção do sistema e POO (Programação Orientada a Objetos) :

Primeiro descreve cada uma das entidades (Entities) do sistema, o que é uma Raquete, uma Bola e um terreno do jogo de tênis (TerrenoJogoTenis).

A ideia da arquitetura do sistema é meter no terreno do jogo de tênis uma Raquete e uma Bola e não o contrario :

O terreno do jogo de tênis é como um recipiente (canvas, container) em que as dependências (Bola, Raquete) são injetadas na inicialização do sistema (inspirado nos conceitos do (Inversion of Control : IoC, DI, ... mas de maneira muito mais simples).

/**
*  Contrutor do terreno do jogo de tênis 
*/
public TerrenoJogoTenis( Raquete raquete, Bola bola) {

...........

}

Na classe Raquete e na classe da Bola meter unicamente os atributos (propriedades) dos objetos e as regras (algoritmos) de respectivamente cada um deles. Nada de paint() e nada de detecção de colisão na Bola. Uma Bole é sega e não vê colisão.

Na classe TerrenoJogoTenis desenrolar o algoritmo geral do jogo de tênis e vai desenhar os elementos (raquete e Bola) no terreno do jogo.

O terreno do jogo de tênis vê tudo o que nele se passa e interações dos seus elementos (Raquete, Bola, ...) e aplica as regras do jogo. por isso deve ser a ele de detectar as colisões e definir a regras do jogo.

Cordialmente

Ernest Duarte

Edited by Ernest Duarte

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.