900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Java编写网络打字游戏

Java编写网络打字游戏

时间:2019-07-24 19:07:12

相关推荐

Java编写网络打字游戏

《Java语言程序设计》–郭克华

网络打字游戏功能简介

这里将介绍一个网络对战的打字游戏。首先运行服务器,界面如图1所示。

图1

运行客户端,首先显示如图2所示的对话框。

图2

用户能够输入昵称,单击“确定”按钮,则连接到服务器。这里为了简单起见,服务器运行在本机,端口为9999。

连接成功,显示如图3.

图3

单击“确定”按钮,即可出现打字游戏界面。

实际上,多人可以加入打字对战。界面如图所示。

规则如下:

1.初始生命值为10分,字母随机落下。

2.用户按下键盘,如果输入的字符正确,则加1分,错误,减一分,然后重新落下新字母。

3.如果用户加1分,将其他所有用户分分数减一分。

4.字母掉到用户界面底部,用户减1分,重新出现新字母。

5.如果把生命值变为0分,则游戏退出,如图所示。

ps:此案例是很多网络对战游戏的基础,如网络打牌、网络赛车、网络五子棋等。

关键技术

1.如何组织界面

在这个项目中,服务器端界面比较简单。客户端也只有一个界面,但是最好将游戏的工作写在一个面板内,然后将面板加到一个JFrame中。

设计出来的类如下:

1.GamePanel:客户端游戏所在的面板。

2.GameFrame:客户端游戏面板所在的界面。

3.Server:服务器界面。

2.客户端如何掉下字母

可以通过画图技术在界面上画出字母。不过,在Java GUI中,还有一种更加简单的方法,那就是将面板设置为空布局之后,将字母放在一个JLabel中。

字母的掉下,实际上相当于调整JLabel的位置,代码如下:

...public class GamePanel extends JPanel {...//掉下的字母Labelprivate JLabel lbMoveChar=new JLabel();public GamePanel() { this.setLayout(null);...this.add(lbMoveChar);lbMoveChar.setFont(new Font("黑体",Font.BOLD,20));lbMoveChar.setForeground(Color.yellow);this.init();... }public void init() { //字母的属性设置...//出现随机字母String str=String.valueOf((char)('A'+rnd.nextInt(26)));lbMoveChar.setText(str);lbMoveChar.setBounds(rnd.nextInt(this.getWidth()),0,20,20);}...//Timer事件对应的行为:实现掉下一个字母@Overridepublic void actionPerformed(ActionEvent e) {...lbMoveChar.setLocation(lbMoveChar.getX(),lbMoveChar.getY()+10);}}

3.客户端如何实现加减分数

由于本项目输入网络通信应用,因此,分数的加减可以通过服务器转发。方法如下:

1.客户端输入正确,将自己加2分,然后讲一个字符串-1发给服务器。

2.服务器将-1发给所有在线客户端。

3.所有客户端(包括自己),获取-1之后,将相应的生命值减去1分。

代码如下:

package game;import java.awt.*;import java.awt.event.*;import java.io.*;import .Socket;import java.util.Random;import javax.swing.*;public class GamePanel extends JPanel implements ActionListener,KeyListener,Runnable {//生命值private int life=10;//按键按下的字母private char keyChar;//掉下的字母Labelprivate JLabel lbMoveChar=new JLabel();//当前生命值状态显示JLabelprivate JLabel lbLife=new JLabel();private Socket s=null;private Timer timer=new Timer(100,this);private Random rnd=new Random();private BufferedReader br=null;private PrintStream ps=null;...///线程读取网络信息@Overridepublic void run() {try {while(canRun) {String str=br.readLine(); //读int score=Integer.parseInt(str);life+=score;checkFail();}}catch (Exception ex) {canRun=false;javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出");System.exit(0);}}...//键盘操作事件对应的行为@Overridepublic void keyPressed(KeyEvent e) {keyChar=e.getKeyChar();String strChar=String.valueOf(keyChar).toUpperCase();try {if(strChar.equals(lbMoveChar.getText())) {//注意,这里加2分,然后发送-1给所有客户端//本客户端又会收到,结果为加1分life+=2;ps.println("-1");}else life--;checkFail();}catch (Exception ex) {ex.printStackTrace();javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出");System.exit(0);}}...}

4.客户端如何判断输了

判断输了很简单,只需判断生命值是否小于等于0即可:

public void checkFail() {init();if(life<=0) {timer.stop();javax.swing.JOptionPane.showMessageDialog(this,"生命值耗尽,游戏失败");System.exit(0);}}

代码编写

1.服务器端

首先是服务器类,代码如下:

package game;import java.awt.Color;import java.io.*;import .*;import java.util.ArrayList;import javax.swing.*;public class Server extends JFrame implements Runnable {private Socket s=null;private ServerSocket ss=null;//保存客户端的线程private ArrayList<ChatThread> clients=new ArrayList<ChatThread>();public Server() throws Exception {this.setTitle("服务器端");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setBackground(Color.yellow);this.setSize(200,100);this.setVisible(true);ss=new ServerSocket(9999);new Thread(this).start();}@Overridepublic void run() {try {while(true) {s=ss.accept();ChatThread ct=new ChatThread(s);clients.add(ct);ct.start();}}catch (Exception ex) {ex.printStackTrace();javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出!");System.exit(0);}}class ChatThread extends Thread { //为某个Socket负责接收信息private Socket s=null;private BufferedReader br=null;private PrintStream ps=null;private boolean canRun=true;public ChatThread(Socket s) throws Exception {this.s=s;br=new BufferedReader(new InputStreamReader(s.getInputStream()));ps=new PrintStream(s.getOutputStream());}@Overridepublic void run() {try {while(canRun) {String str=br.readLine(); //读取该Socket传来的信息sendMessage(str); //将str转发给所有客户端}}catch (Exception ex) {//此处可以解决客户异常下线问题canRun=false;clients.remove(this);}}}//将信息发给其他客户端public void sendMessage(String msg) {for(ChatThread ct: clients) ct.ps.println(msg);}public static void main(String[] args) throws Exception {new Server();}}

2.客户端

首先是游戏面板类,代码如下:

package game;import java.awt.*;import java.awt.event.*;import java.io.*;import .Socket;import java.util.Random;import javax.swing.*;public class GamePanel extends JPanel implements ActionListener,KeyListener,Runnable {//生命值private int life=10;//按键按下的字母private char keyChar;//掉下的字母Labelprivate JLabel lbMoveChar=new JLabel();//当前生命值状态显示JLabelprivate JLabel lbLife=new JLabel();private Socket s=null;private Timer timer=new Timer(100,this);private Random rnd=new Random();private BufferedReader br=null;private PrintStream ps=null;private boolean canRun=true;public GamePanel() { //构造器this.setLayout(null);this.setBackground(Color.DARK_GRAY);this.setSize(240,320);this.add(lbLife);lbLife.setFont(new Font("黑体",Font.BOLD,20));lbLife.setBackground(Color.yellow);lbLife.setForeground(Color.PINK);lbLife.setBounds(0,0,this.getWidth(),20);this.add(lbMoveChar);lbMoveChar.setFont(new Font("黑体",Font.BOLD,20));lbMoveChar.setForeground(Color.yellow);this.init();this.addKeyListener(this);try {s=new Socket("127.0.0.1",9999);JOptionPane.showMessageDialog(this,"连接成功");InputStream is=s.getInputStream();br=new BufferedReader(new InputStreamReader(is));OutputStream os=s.getOutputStream();ps=new PrintStream(os);new Thread(this).start();}catch (Exception ex) {javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出");System.exit(0);}timer.start();}public void init() { //字母的属性设置lbLife.setText("当前生命值:"+life);//出现随机字母String str=String.valueOf((char)('A'+rnd.nextInt(26)));lbMoveChar.setText(str);lbMoveChar.setBounds(rnd.nextInt(this.getWidth()),0,20,20);}@Overridepublic void run() {try {while(canRun) {String str=br.readLine(); //读int score=Integer.parseInt(str);life+=score;checkFail();}}catch (Exception ex) {canRun=false;javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出");System.exit(0);}}//Timer事件对应的行为:实现掉下一个字母@Overridepublic void actionPerformed(ActionEvent e) {if(lbMoveChar.getY()>=this.getHeight()) {life--;checkFail();}lbMoveChar.setLocation(lbMoveChar.getX(),lbMoveChar.getY()+10);}public void checkFail() {init();if(life<=0) {timer.stop();javax.swing.JOptionPane.showMessageDialog(this,"生命值耗尽,游戏失败");System.exit(0);}}//键盘操作事件对应的行为@Overridepublic void keyPressed(KeyEvent e) {keyChar=e.getKeyChar();String strChar=String.valueOf(keyChar).toUpperCase();try {if(strChar.equals(lbMoveChar.getText())) {//注意,这里加2分,然后发送-1给所有客户端//本客户端又会收到,结果为加1分life+=2;ps.println("-1");}else life--;checkFail();}catch (Exception ex) {ex.printStackTrace();javax.swing.JOptionPane.showMessageDialog(this,"游戏异常退出");System.exit(0);}}public void keyTyped(KeyEvent e) {}public void keyReleased(KeyEvent e) {}}

接下来是面板所在的界面类,代码如下:

package game;import javax.swing.JOptionPane;import javax.swing.JFrame;public class GameFrame extends JFrame {private GamePanel gp;public GameFrame() {//构造器this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);String nickName=JOptionPane.showInputDialog("输入昵称");this.setTitle(nickName);gp=new GamePanel();this.add(gp);//获取焦点gp.setFocusable(true);this.setSize(gp.getWidth(),gp.getHeight());this.setResizable(false);this.setVisible(true);}//主函数入口public static void main(String[] args) {new GameFrame();}}

运行该服务器,在运行客户端类,则可以进行网络对战游戏。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。