引言:
作为一个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));
}
}
本人纯小白,望海涵,欢迎提出建议和意见。