新手上路——西西弗斯小游戏

引言:

    作为一个java新手,在这里写下一些学习过程和经验。

    小游戏源自于一个神话故事,即西西弗斯的神话传说,神话就不讲了,游戏的主题内容就是很简单的不断推石头上山,然后石头不断滚落,再重复推上山的永无止境循环。

用到的知识:

    java.swing 关于窗口(JFrame),面板(JPanel),按钮(JButton),组件(JComponent)。

    绘图(Graphics,Graphics2D)。

    线程的新建,线程锁。

    文件的读取与写入。

新建窗口:

使用java.swing.*。

具体步骤:

一:声明并实例化框架对象,设置默认关闭方式,设置是否可见:

MainFrame frame=new MainFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

 在设置默认关闭方式里面用的是JFrame.EXIT_ON_CLOSE,即关闭后退出程序

 setVisible的含义则在于让窗口显示出来,可以在这之前进行对窗口的设置。

二:新建窗口类,并进行基础属性的设置:

public class MainFrame extends JFrame{
public MainFrame(){
		this.setTitle("Sisyphus");
		this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
		this.setLocationByPlatform(true);
		
	}
final int WINDOW_WIDTH=500;
final int WINDOW_HEIGHT=300;
}

我在这里新建了一个继承于JFrame的MainFrame,然后利用构造函数进行窗口初始化的操作:

this.setTitle("Sisyphus"); 设置窗口标题为Sisyphus。

this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); 设置窗口大小(宽,高)。

this.setLocationByPlatform(true); 由平台设置出现位置。

三:面板及组件,按钮的添加,动作事件。

public class MainFrame extends JFrame{
	
	DrawComponent draw=new DrawComponent();
	public MainFrame(){
		this.setTitle("Sisyphus");
		this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
		this.setLocationByPlatform(true);
		
		this.add(draw);
		
		JPanel panel=new JPanel();
        JButton Gravity =new JButton("GRAVITY");
		JButton button=new JButton("PUSH");
		JButton ranklist=new JButton("RANK");
        GAction gaction=new GAction();
		StartAction start =new StartAction();
		RankAction rankaction=new RankAction();
		button.addActionListener(start);
		ranklist.addActionListener(rankaction);
        panel.add(Gravity);
		panel.add(button);
		panel.add(ranklist);
		this.add(panel,BorderLayout.SOUTH);
		
	}
final int WINDOW_WIDTH=500;
final int WINDOW_HEIGHT=300;
}

在这里我把一个用于绘图的组件添加到了构造函数之外为整个类使用。

分别实例化了一个面板,两个按钮,两个动作时间。

PUSH按钮是执行向上推的动作的,RANK按钮则是用作记录,排名

然后把动作事件添加到了按钮上 button.addActionListener(start);

把按钮添加到面板上 panel.add(button);

this.add(panel,BorderLayout.SOUTH);把面板添加到窗口的下面。可以用BorderLayout.去设置位置。不然两个组件之间会覆盖。

说一下面板(JPanel):

面板里的东西是按照顺序排列的,而且会尽量显示在中间。

四:动作事件

private class StartAction implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			
			
			R.center_x=R.center_x+5;
			draw.repaint();
			if(-0.4*R.center_x+150<0) {
				R.center_x=50;
				R.top_count++;
				R.nextRandColor();
				if(R.top_count%2==0) {
					R.level++;
				}
				draw.repaint();
			}
			R.DELAY=R.Delay-R.level*2;
		}
		
	}
	
	private class RankAction implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			RanklistFrame ranklist=new RanklistFrame();
			ranklist.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
			ranklist.setVisible(true);
		}
		
	}
private class GAction implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			Runnable r=new Gravity(draw);
			Thread t=new Thread(r);
			t.start();
		}
		
	}

在解释动作事件之前先解释一下R类:

我写了一个名字叫做R的类来存放一些变量方便更改。

点Gravity会产生重力,具体是新建一个线程,每过一定时间令小球的某个坐标变化。

点Rank会弹出窗口显示ranklist。

点push会推动石头。

五:绘图

public class DrawComponent extends JComponent {
    Random rand=new Random();
	public void  paintComponent(Graphics g) {
		Graphics2D g2=(Graphics2D)g;
		
		
		
		//直线
		g2.draw(new Line2D.Double(0, 200, 500, 0));  
		
		//圆
		Ellipse2D circle=new Ellipse2D.Double();
		circle.setFrameFromCenter(R.center_x,-0.4*R.center_x+150,R.center_x+R.center_r,-0.4*R.center_x+150+R.center_r);
		g2.setColor(R.c);
		g2.fill(circle);
		g2.setColor(Color.BLACK);
		
		//计数	
		g.drawString("登顶次数:"+R.top_count, 400, 200);
		g.drawString("等级:"+R.level, 400, 180);
	}
}

java里有相应的类去存储相关图形的属性

直线:Line2D

圆:Ellipse2D

矩形:Rectangle2D

六:对文件的操作

public class FileIO {
	String filename;
	public FileIO(File file) {
		if(!file.exists()) {
			try {
			file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		filename=file.getName();
	}
	
	public String fileExtract(String result) {
		try(FileReader reader=new FileReader(filename);
			BufferedReader br =new BufferedReader(reader))
		{
			String temp;
			StringBuffer buf=new StringBuffer();
			while((temp=br.readLine())!=null) {
				buf.append(temp);
				buf.append("\r\n");
				result=buf.toString();
			}
			
		}catch(IOException e) {e.printStackTrace();}		
		return result;
	}
	
	
}

判断文件是否存在,若不存在则创建

记得读写文件时try或者抛出异常

七:重力(多线程)

public class Gravity implements Runnable {
	public Gravity(JComponent com) {
		con=com;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		gLock.lock();
		try {
			while(R.center_x>0) {
				R.center_x=R.center_x-R.ax;
				con.repaint();
				Thread.sleep(R.DELAY);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			gLock.unlock();
		}
		
	}
private Lock gLock=new ReentrantLock();
private JComponent con;
}

为了防止多线程同时改变一个变量造成问题,加了一个锁。

八:Ranklist的框架

public class RanklistFrame extends JFrame {
	RankListComponent rank =new RankListComponent();
public RanklistFrame() {
	this.setTitle("Rank");
	this.setAlwaysOnTop(true);
	this.setSize(300, 200);
	this.setLocationByPlatform(true);
	
	this.add(rank,BorderLayout.CENTER);
	
	JButton add=new JButton("add");
	JButton delete =new JButton("delete");
	JButton deleteall=new JButton("deleteall");
	JPanel panel =new JPanel();
	panel.add(add);
	panel.add(delete);
	panel.add(deleteall);
	addAction addaction =new addAction();
	deleteallAction deleteallaction=new deleteallAction();
	deleteAction deleteaction=new deleteAction();
	deleteall.addActionListener(deleteallaction);
	delete.addActionListener(deleteaction);
	add.addActionListener(addaction);
	this.add(panel, BorderLayout.SOUTH);
}

private class addAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		File file =new File("ranklist.txt");
		if(!file.exists()) {
			try {
				file.createNewFile();
				}catch (IOException e1) {e1.printStackTrace();}}
		
		try {
			FileWriter writer =new FileWriter("ranklist.txt",true);
			String temp="等级:"+R.level+" "+"登顶次数:"+R.top_count+"\r\n";
			
			writer.write(temp);
			writer.close();
			rank.repaint();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();}
	}
	
}

private class deleteallAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		File file =new File("ranklist.txt");
		try {
			if(!file.exists()) {
				file.createNewFile();
			}
			FileWriter writer =new FileWriter(file);
			writer.close();
			rank.repaint();
		}catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();}
	}
	
}

private class deleteAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		File file=new File("ranklist.txt");
		try {
			FileIO fileio=new FileIO(file);
			String result="";
			result=fileio.fileExtract(result);
			String[] unit=result.split("\r\n");
			FileWriter writer=new FileWriter(file);
			if(unit.length>=2)
			for(int i=0;i<unit.length-1;i++) {
				writer.write(unit[i]+"\r\n");
				
			}
			writer.close();
			rank.repaint();
		}catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();}
	}
	
}
}

九:RanklistComponent

public class RankListComponent extends JComponent {
	String[] unit;
	String result;
	public void paintComponent(Graphics g) {
		
		File file =new File("ranklist.txt");
		FileIO fileio=new FileIO(file);
		result="";
		result=fileio.fileExtract(result);
		unit=result.split("\r\n");
		int y=10;
		for(String test:unit) {
			g.drawString(test, 80, y);
			y=y+15;
		}
		

	}
	
}

这里初始化result的时候这样写不会导致后续出现异常。

十:全部代码

Sisyphus.java

import java.awt.EventQueue;
import java.io.IOException;

import javax.swing.JFrame;

public class Sisyphus {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				MainFrame frame=new MainFrame();
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setVisible(true);
				
				
			}
		});
	}

}

MainFrame.java


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;

import javax.swing.*;

public class MainFrame extends JFrame{
	/**
	 * 
	 */
	private static final long serialVersionUID = 2L;
	Timer timer = new Timer();
	final int WINDOW_WIDTH=500;
	final int WINDOW_HEIGHT=300;
	DrawComponent draw=new DrawComponent();
	public MainFrame(){
		this.setTitle("Sisyphus");
		this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
		this.setLocationByPlatform(true);
		
		this.add(draw);
		
		JPanel panel=new JPanel();
		JButton Gravity =new JButton("GRAVITY");
		JButton button=new JButton("PUSH");
		JButton ranklist=new JButton("RANK");
		StartAction start =new StartAction();
		RankAction rankaction=new RankAction();
		GAction gaction=new GAction();
		Gravity.addActionListener(gaction);
		button.addActionListener(start);
		ranklist.addActionListener(rankaction);
		panel.add(Gravity);
		panel.add(button);
		panel.add(ranklist);
		this.add(panel,BorderLayout.SOUTH);
		
	}
	
	
	private class StartAction implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			
			
			R.center_x=R.center_x+5;
			draw.repaint();
			if(-0.4*R.center_x+150<0) {
				R.center_x=50;
				R.top_count++;
				R.nextRandColor();
				if(R.top_count%2==0) {
					R.level++;
				}
				draw.repaint();
			}
			R.DELAY=R.Delay-R.level*2;
		}
		
	}
	
	private class RankAction implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			RanklistFrame ranklist=new RanklistFrame();
			ranklist.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
			ranklist.setVisible(true);
		}
		
	}
	
	private class GAction implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			Runnable r=new Gravity(draw);
			Thread t=new Thread(r);
			t.start();
		}
		
	}
	
}

RanklistFrame.java

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.*;

public class RanklistFrame extends JFrame {
/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	RankListComponent rank =new RankListComponent();
public RanklistFrame() {
	this.setTitle("Rank");
	this.setAlwaysOnTop(true);
	this.setSize(300, 200);
	this.setLocationByPlatform(true);
	
	this.add(rank,BorderLayout.CENTER);
	
	JButton add=new JButton("add");
	JButton delete =new JButton("delete");
	JButton deleteall=new JButton("deleteall");
	JPanel panel =new JPanel();
	panel.add(add);
	panel.add(delete);
	panel.add(deleteall);
	addAction addaction =new addAction();
	deleteallAction deleteallaction=new deleteallAction();
	deleteAction deleteaction=new deleteAction();
	deleteall.addActionListener(deleteallaction);
	delete.addActionListener(deleteaction);
	add.addActionListener(addaction);
	this.add(panel, BorderLayout.SOUTH);
}

private class addAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		File file =new File("ranklist.txt");
		if(!file.exists()) {
			try {
				file.createNewFile();
				}catch (IOException e1) {e1.printStackTrace();}}
		
		try {
			FileWriter writer =new FileWriter("ranklist.txt",true);
			String temp="等级:"+R.level+" "+"登顶次数:"+R.top_count+"\r\n";
			
			writer.write(temp);
			writer.close();
			rank.repaint();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();}
	}
	
}

private class deleteallAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		File file =new File("ranklist.txt");
		try {
			if(!file.exists()) {
				file.createNewFile();
			}
			FileWriter writer =new FileWriter(file);
			writer.close();
			rank.repaint();
		}catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();}
	}
	
}

private class deleteAction implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		File file=new File("ranklist.txt");
		try {
			FileIO fileio=new FileIO(file);
			String result="";
			result=fileio.fileExtract(result);
			String[] unit=result.split("\r\n");
			FileWriter writer=new FileWriter(file);
			if(unit.length>=2)
			for(int i=0;i<unit.length-1;i++) {
				writer.write(unit[i]+"\r\n");
				
			}
			writer.close();
			rank.repaint();
		}catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();}
	}
	
}
}

RanklistComponent.java


import java.awt.*;
import java.io.*;

import javax.swing.JComponent;

public class RankListComponent extends JComponent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String[] unit;
	String result;
	public void paintComponent(Graphics g) {
		
		File file =new File("ranklist.txt");
		FileIO fileio=new FileIO(file);
		result="";
		result=fileio.fileExtract(result);
		unit=result.split("\r\n");
		int y=10;
		for(String test:unit) {
			g.drawString(test, 80, y);
			y=y+15;
		}
		

	}
	
}

DrawComponent.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.Random;

import javax.swing.*;

public class DrawComponent extends JComponent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
    Random rand=new Random();
	public void  paintComponent(Graphics g) {
		Graphics2D g2=(Graphics2D)g;
		
		
		
		//直线
		g2.draw(new Line2D.Double(0, 200, 500, 0));  
		
		//圆
		Ellipse2D circle=new Ellipse2D.Double();
		circle.setFrameFromCenter(R.center_x,-0.4*R.center_x+150,R.center_x+R.center_r,-0.4*R.center_x+150+R.center_r);
		g2.setColor(R.c);
		g2.fill(circle);
		g2.setColor(Color.BLACK);
		
		//计数	
		g.drawString("登顶次数:"+R.top_count, 400, 200);
		g.drawString("等级:"+R.level, 400, 180);
	}
}

FileIO.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class FileIO {
	String filename;
	public FileIO(File file) {
		if(!file.exists()) {
			try {
			file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		filename=file.getName();
	}
	
	public String fileExtract(String result) {
		try(FileReader reader=new FileReader(filename);
			BufferedReader br =new BufferedReader(reader))
		{
			String temp;
			StringBuffer buf=new StringBuffer();
			while((temp=br.readLine())!=null) {
				buf.append(temp);
				buf.append("\r\n");
				result=buf.toString();
			}
			
		}catch(IOException e) {e.printStackTrace();}		
		return result;
	}
	
	
}

Gravity.java

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.swing.JComponent;

public class Gravity implements Runnable {
	public Gravity(JComponent com) {
		con=com;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		gLock.lock();
		try {
			while(R.center_x>0) {
				R.center_x=R.center_x-R.ax;
				con.repaint();
				Thread.sleep(R.DELAY);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			gLock.unlock();
		}
		
	}
private Lock gLock=new ReentrantLock();
private JComponent con;
}

R.java

import java.awt.Color;
import java.util.Random;

public class R {
static Random rand=new Random();
public static Color c;
public static Color back;
public static double center_x=50;
public static double center_r=250/Math.sqrt(29);
public static int top_count=0;
public static int level=0;
public static int count=0;
public static double ax=0.5;
public static int DELAY=40;
public static final int Delay=40;

public static void nextRandColor() {
c=new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));

}
}

本人纯小白,望海涵,欢迎提出建议和意见。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值