我们在之前学的编程语言中,所有代码的执行顺序是串行的,也就是按顺序执行,这样就造成了一个问题,也许当你刚刚接触编程语言时候无关大碍,甚至在达到一定水平之后可以自己设计五子棋,贪食蛇,连连看等游戏,但是看着自己设计的界面以及游戏,有没有感觉缺少什么?对了,就是单调,不够动态,因为串行语句必须等上面的代码执行完了才会执行下面的语句,这样就无法支持同步性,当时造成我主要困扰的是想要完成儿童时代的经典游戏 坦克大战 时,忽然考虑到了一个很大的问题
用单线程实现不出来!!!!!因为子弹是一个线程,坦克是一个线程,敌人的坦克又是一个线程,当时有种崩溃的感觉,因为还不知道有多线程这个东西
因此再学了多线程以后(多线程是并行语句),立马就像做出目前脍炙人口的游戏
植物大战僵尸
简单部署界面,用到了缓冲图,实现不断刷新的功能
还加上了声音,以及判断阳光点击获取
一下是关键代码:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class main extends JFrame {
private ImageIcon background;
private JFrame jf;
private JPanel imagePanel;
private Game game;
static int x=0,y=0;
private Graphics g;
public static void main(String args[]){
//new main().initUi2();
new main().initUi1();
}
public void initUi1(){
JFrame jf=new JFrame();
background = new ImageIcon("image//menu.png");//
JLabel label = new JLabel(background);//
ImageIcon login=new ImageIcon("image//start_leave.png");
JButton jlogin=new JButton(login);
this.game=new Game();
jlogin.setPreferredSize(new Dimension(login.getIconWidth(),login.getIconHeight()));
ActionListener a=new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
game.initUI();
}
};
label.setBounds(0,0,background.getIconWidth(),background.getIconHeight());
imagePanel = (JPanel)this.getContentPane();
imagePanel.setOpaque(false);
imagePanel.setLayout(new FlowLayout());
imagePanel.add(jlogin);
this.getLayeredPane().setLayout(null);
this.getLayeredPane().add(label,new Integer(Integer.MIN_VALUE));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(background.getIconWidth(),background.getIconHeight());
this.setLayout(new BorderLayout());
jlogin.addActionListener(a);
this.add(jlogin,BorderLayout.SOUTH);
this.setVisible(true);
}
接下来是游戏界面
代码如下:
import java.awt.Color;
import sun.audio.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Game{
private JFrame jf;
private int [] a=new int[100];
private ArrayList<Ball> list=new ArrayList<Ball>();
public void initUI(){
jf = new JFrame();
jf.setSize(1600, 620);
jf.setDefaultCloseOperation(3);
AudioClip clip = null;
try {
clip = Applet.newAudioClip((new File("image/网1.wav")).toURI().toURL());
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
clip.play();
jf.setLayout(new FlowLayout());
ImageIcon p1=new ImageIcon("image//single_bullet_plant.png");
ImageIcon p2=new ImageIcon("image//2.png");
ImageIcon p3=new ImageIcon("image//3.png");
ImageIcon p4=new ImageIcon("image//4.png");
ImageIcon p5=new ImageIcon("image//5.png");
ImageIcon p6=new ImageIcon("image//6.png");
ImageIcon p7=new ImageIcon("image//7.png");
JButton start=new JButton("开始战斗");
start.setLocation(500,600);
start.setBounds(500, 500, 600, 600);
jf.setLayout(new FlowLayout());
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(start);
jf.setVisible(true);
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
draw(jf.getGraphics());
}
}
ImageIcon bjIcon = new ImageIcon("image/background1.jpg");
ImageIcon personIcon = new ImageIcon("image/person.gif");
ImageIcon p1=new ImageIcon("image//1.png");
ImageIcon p11=new ImageIcon("image//11.jpg");
ImageIcon p2=new ImageIcon("image//2.png");
ImageIcon p22=new ImageIcon("image//sun.gif");
ImageIcon p3=new ImageIcon("image//3.png");
ImageIcon p4=new ImageIcon("image//4.png");
ImageIcon p44=new ImageIcon("image//u9.jpg");
ImageIcon p5=new ImageIcon("image//5.png");
ImageIcon p6=new ImageIcon("image//6.png");
ImageIcon p66=new ImageIcon("image//111.jpg");
ImageIcon p7=new ImageIcon("image//7.png");
ImageIcon p77=new ImageIcon("image//u5.jpg");
ImageIcon chanzi1=new ImageIcon("image//shovel_bk.png");
ImageIcon chanzi=new ImageIcon("image//shovel.png");
ImageIcon a1=new ImageIcon("image//u1.jpg");
ImageIcon a2=new ImageIcon("image//u2.jpg");
ImageIcon a3=new ImageIcon("image//u3.jpg");
ImageIcon a5=new ImageIcon("image//u5.jpg");
ImageIcon a6=new ImageIcon("image//u6.jpg");
ImageIcon a7=new ImageIcon("image//u7.jpg");
ImageIcon a8=new ImageIcon("image//u8.jpg");
ImageIcon a9=new ImageIcon("image//u9.jpg");
ImageIcon a10=new ImageIcon("image//u10.jpg");
ImageIcon a11=new ImageIcon("image//u11.jpg");
ImageIcon a12=new ImageIcon("image//u12.jpg");
ImageIcon a13=new ImageIcon("image//u13.jpg");
ImageIcon a14=new ImageIcon("image//uwogua.jpg");
int x=0,y=0;
int lx,ly;
int lxx,lyy;
int px,py;
BufferedImage buffer = new BufferedImage(
1600,
620,
BufferedImage.TYPE_INT_RGB);
public void draw(Graphics g){
Graphics gg = buffer.getGraphics();
gg.setColor(Color.BLACK);
gg.fillRect(0, 0, jf.getWidth(), jf.getHeight());
gg.drawImage(bjIcon.getImage(), x, y, null);
gg.drawImage(bjIcon.getImage(), x+bjIcon.getIconWidth(), y, null);
//画随机植物
gg.drawImage(a1.getImage(), 400, 350, null);
gg.drawImage(p11.getImage(), 250, 280, null);
Wandou w=new Wandou();
if(true){
w.draw(gg,290,280);
try {
w.sleep(3);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//w.draw(gg,280,280);
}
//画阳光值增加
gg.setColor(Color.BLACK);
if(true){
new Sun().draw(gg,jf);
}
//gg.setColor(Color.RED);
//gg.drawString("50", 100, 100);
gg.drawImage(a2.getImage(), 500, 150, null);
gg.drawImage(a3.getImage(), 600, 200, null);
gg.drawImage(a6.getImage(), 700, 200, null);
gg.drawImage(a5.getImage(), 480, 330, null);
gg.drawImage(a7.getImage(), 1000, 400, null);
gg.drawImage(a8.getImage(), 800, 200, null);
gg.drawImage(a14.getImage(), 250, 150, null);
//gg.drawImage(a13.getImage(), 1000, 200, null);//画一个普通僵尸
Zombie z1=new Zombie();
if(true){
try {
z1.sleep(50);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
z1.draw(gg,1000,200);
}
gg.drawImage(a12.getImage(), 320, 70, null);
//画阳光值增加
g.drawString("50", 80, 30);
//画可以挑选植物
gg.drawImage(p1.getImage(), 400, 20, null);
gg.drawImage(p2.getImage(),460, 20, null);
gg.drawImage(p3.getImage(), 520, 20, null);
gg.drawImage(p4.getImage(), 580, 20, null);
gg.drawImage(p5.getImage(), 640, 20, null);
gg.drawImage(p6.getImage(), 700, 20, null);
gg.drawImage(p7.getImage(), 760, 20, null);
gg.drawImage(chanzi1.getImage(), 1000, 500, null);
//gg.drawImage(personIcon.getImage(), 1200, 300, null);
jf.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
//
System.out.println("32");
lx=e.getX();ly=e.getY();
}
});
jf.addMouseMotionListener(new MouseAdapter(){
public void mouseDragged(MouseEvent e) {
lxx=e.getX();lyy=e.getY();
}
public void mouseReleased(MouseEvent e) {
px=e.getX();
py=e.getY();
}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
});
if(lx<=460&&lx>=400){
gg.drawImage(p11.getImage(), lxx,lyy, null);
gg.drawImage(p11.getImage(), a[0],a[1], null);
}
//if(lx<=460&&lx>=400){
//new Plant().draw(jf, gg);
//}
if(lx<=520&&lx>=460){
gg.drawImage(p22.getImage(), lxx,lyy, null);
gg.drawImage(p22.getImage(), a[1],a[2], null);
}
// if(lx<=520&&lx>=460){
// new Plant().draw(jf, gg);
// }
if(lx<=580&&lx>=520){
gg.drawImage(p3.getImage(), lxx,lyy, null);
// gg.drawImage(p3.getImage(), px,py, null);
}
if(lx<=640&&lx>=580){
gg.drawImage(p44.getImage(), lxx,lyy, null);
}
if(lx<=700&&lx>=640){
gg.drawImage(p5.getImage(), lxx,lyy, null);
}
if(lx<=760&&lx>=700){
gg.drawImage(p66.getImage(), lxx,lyy, null);
}
if(lx<=820&&lx>=760){
gg.drawImage(p77.getImage(), lxx,lyy, null);
}
if(lx<=1200&&lx>=820){
gg.drawImage(chanzi.getImage(), lxx,lyy, null);
}
//x-=5;
//if(x+bjIcon.getIconWidth() <= 0){
//x = 0;
//}
for(int i=0; i<list.size(); i++){
Ball ball = list.get(i);
ball.draw(gg);
}
g.drawImage(buffer, 0, 0, null);
}
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if("start".equals(cmd)){
Ball t = new Ball(jf, list);
t.start();
list.add(t);
}
if("pause".equals(cmd)){
for(int i=0; i<list.size(); i++){
Ball ball = list.get(i);
// ball.suspend();
ball.setPause(true);
}
}
if("resume".equals(cmd)){
for(int i=0; i<list.size(); i++){
Ball ball = list.get(i);
// ball.resume();
ball.setPause(false);
}
}
if("stop".equals(cmd)){
while(!list.isEmpty()){
Ball ball = list.remove(0);
ball.setStop(true);
}
}
}
};
public static void main(String[] args) {
new Game().initUI();
}
}
阳光:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Sun extends Thread{
public Random r=new Random();
private int x=800,y=30;
private static int vx,vy;
private static int i=50;
public void draw(final Graphics g,JFrame jf){
final ImageIcon sun=new ImageIcon("image/sun.png");
final ImageIcon sunback=new ImageIcon("image/SunBank.png");
g.drawImage(sun.getImage(),x,y+vy,null);
g.drawImage(sunback.getImage(),220,30,null);
vy+=1;
g.setColor(Color.RED);
g.drawString(i+"", 250, 110);
jf.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
if(Math.abs(e.getX()-x)<=100&&Math.abs(y+vy-e.getY())<=100){
if(x>250&&y>0){
System.out.println("32");
g.drawImage(sun.getImage(),220,30,null);
vy-=100;
vx-=100;
}
i+=50;
}
}
});
if(y+vy>600){
vy=5;
g.drawImage(sun.getImage(),x,y+vy,null);
vy+=1;
}
}
}
豌豆攻击线程代码:
import java.awt.Graphics;
import javax.swing.ImageIcon;
public class Wandou extends Thread{
private int wx=280,wy=280;
private static int vx=5;
public void draw(Graphics g,int wx,int wy){
//System.out.print("23232");
ImageIcon wandou=new ImageIcon("image//bullet_01.png");
g.drawImage(wandou.getImage(),wx+vx,wy,null);
vx+=5;
if(wx+vx>=800){
vx=5;
g.drawImage(wandou.getImage(),wx+vx,wy,null);
vx+=5;
}
}
}
僵尸前进代码:
import java.awt.Graphics;
import javax.swing.ImageIcon;
public class Zombie extends Thread{
private int zx=280,zy=280;
private static int vx=5;
public void draw(Graphics g,int zx,int zy){
ImageIcon a8=new ImageIcon("image//u8.jpg");
//System.out.print("23232");
ImageIcon a13=new ImageIcon("image//u13.jpg");
g.drawImage(a13.getImage(),zx-vx,zy,null);
vx+=1;
//if(zx-vx<=800){
// vx=5;
// g.drawImage(a8.getImage(),800-vx,200,null);
// vx+=1;
//}
}
}
之后就是计算算法,执行攻击功能的预判了