Java写人吃球
-
该代码的部分需求是继承上一次博客中的一些功能需求。
-
新功能是添加了一些对键盘的扫描、图片相碰会消失、球随机走动的一些算法以及如何在函数内部实现停止是保持停止前的动作。
-
要实现上面的一些功能需要了解键盘的监听器(KeyListener)、球如何消失的(Rectangle)。
-
如果不知道具体含意得可以百度、也可以下一个JDK API 。
-
Client中有个如何延迟随机方向的小难点,算法写在下面注释那边。
-
ball中球是相同的,可以用数组循环也可以用集合(建议用集合),我这里面是数组后续会发集合的用法。
-
persion中需要能够通过扫描键盘来判断方向,并能够判断出上一个按键松开时的方向,我会在注释那边写上,这边也是一个小难点。
Client文件主要是写的是框口的架构以及实现功能的调用
##Client.java
package ****;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Client extends Frame{
static int wid=1000,len=800;
public static final int FRAME_WIDTH=wid;
public static final int FRAME_LENGTH=len;
Toolkit tk=Toolkit.getDefaultToolkit();
Dimension srensize=tk.getScreenSize();
int screenwidth=srensize.width;
int screenhigth=srensize.height;
Image screenImage=null;
ball ball=null;
persion persion=null;
public Client(){
//初始化小球位置
ball=new ball();
persion=new persion(0,25);//(Direction,this)
this.setTitle("scdproject");
this.setBackground(Color.white);
this.setResizable(false);
this.setVisible(true);
this.setSize(FRAME_WIDTH,FRAME_LENGTH);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
this.setLocation(screenwidth/2-wid/2,screenhigth/2-len/2);
this.addKeyListener(new KeyMoniter());
new Thread(new PaintThread()).start();//调用线程
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Client();
}
public void update(Graphics g){
screenImage=this.createImage(FRAME_WIDTH,FRAME_LENGTH);
Graphics gps=screenImage.getGraphics();//画布
//重构
FramePaint(gps);
g.drawImage(screenImage, 0, 0, null);
}
private void FramePaint(Graphics g) {
// TODO Auto-generated method stub
//persion.Getscore;获取persion里的score
ball.draw(g);
if(persion.getScore()==100){
g.setColor(Color.RED);
g.setFont(new Font("",Font.BOLD,50));
g.drawString("通关!",420,370);
}
persion.draw(g);
persion.collidewithball(ball);
}
private class KeyMoniter extends KeyAdapter{//构造方法
public void keyPressed(KeyEvent e){
persion.keyPressed(e);
}
public void keyReleased(KeyEvent e){
persion.keyReleased(e);
}
}
private class PaintThread implements Runnable{
public void run(){
int[] n=new int[ball.z];
int m=(int)(Math.random()*50)+30;//50;
int k=m;
while(true){
if(m==k){//这边处理的是加长球的在随机方向上运行的次数,并且次数也是随机的。
for(int i=0;i<ball.z;i++){
int xy=(int)(Math.random()*4);//0123,左上右下
n[i]=xy;
}
}
for(int i=0;i<ball.z;i++){
if(n[i]==0){
ball.x[i]=ball.x[i]-1;
if(ball.x[i]<0){
ball.x[i]++;
}
}
else if(n[i]==1){
ball.y[i]=ball.y[i]-1;
if(ball.y[i]<25){
ball.y[i]++;
}
}
else if(n[i]==2){
ball.x[i]=ball.x[i]+1;
if(ball.x[i]>Client.FRAME_WIDTH-50){
ball.x[i]--;
}
}
else if(n[i]==3){
ball.y[i]=ball.y[i]+1;
if(ball.y[i]>Client.FRAME_LENGTH-50){
ball.y[i]--;
}
}
}
m--;
if(m==0){
m=(int)(Math.random()*50)+30;
k=m;
}
repaint();
try{
Thread.sleep(5);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
ball里面主要写球的随机分布,边界线的设置,还有矩形化图片的功能
##ball
package *****;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
public class ball {
public static final int WIDTH=50;
public static final int LENGTH=50;
static int z=10;
private static Toolkit tk=Toolkit.getDefaultToolkit();
private static Image[] images=new Image[z];
int[] x=new int[z];
int[] y=new int[z];
int up,dow,li,re;
static{
for(int i=0;i<z;i++){//images.length
images[i]=tk.getImage(ball.class.getResource("../../images/ball.png"));
}
}
public ball(){
//ball(int ,x,int y){this.x=x;this.y=y;}
for(int i=0;i<images.length;i++){//随机分布球的位置
x[i]=(int)(Math.random()*(1000-50));
y[i]=(int)(Math.random()*(800-50));
}
}
public void draw(Graphics g){
for(int i=0;i<images.length;i++){
g.drawImage(images[i], x[i], y[i],WIDTH,LENGTH ,null);
}
}
public Rectangle[] getRect(){//定义球的区域
Rectangle[] rects=new Rectangle[images.length];
for(int i=0;i<images.length;i++){
rects[i]=new Rectangle(x[i],y[i],WIDTH,LENGTH);
}
return rects;
}
}
persion里主要是实现的对键盘的扫描、以及对各个方向的图片进行判别。
##persion
package ****;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
public class persion {
public static final int WIDTH=50;
public static final int LENGTH=50;
private static Toolkit tk=Toolkit.getDefaultToolkit();
private static Image[] images=new Image[4];//null;
private char dir;
private char stemp;//中间变量
private boolean bL,bU,bR,bD = false;
int score=0,m=2;
static{
images[0]=tk.getImage(persion.class.getResource("../../images/left.png"));//0左
images[1]=tk.getImage(persion.class.getResource("../../images/up.png"));//1上
images[2]=tk.getImage(persion.class.getResource("../../images/right.png"));//2右
images[3]=tk.getImage(persion.class.getResource("../../images/down.png"));//3下
}
private int x;
private int y;
public persion(int x,int y){//添加新元素Direction,Client c
this.x=x;
this.y=y;//this.c=Client c;
}
public void draw(Graphics g){
g.drawImage(images[m], x, y,WIDTH,LENGTH ,null);//初始化为m=2
//调用move()函数
move();
if(dir=='L'){
g.drawImage(images[0], x, y,WIDTH ,LENGTH ,null);
}
else if(dir=='U'){
g.drawImage(images[1], x, y,WIDTH ,LENGTH ,null);
}
else if(dir=='R'){
g.drawImage(images[2], x, y,WIDTH ,LENGTH ,null);
}
else if(dir=='D'){
g.drawImage(images[3], x, y,WIDTH ,LENGTH ,null);
}
else if(dir=='S'){//判读olddirection/dir
;//不做响应
}
stemp=dir;//temp获取上一次响应的结果
switch(stemp){
case 'L':m=0;break;
case 'U':m=1;break;
case 'R':m=2;break;
case 'D':m=3;break;
}
g.setFont(new Font("",Font.BOLD,20));
g.drawString(""+score+"分", 945, 50);
}
public int getScore() {
return score;
}
private void move() {
// TODO Auto-generated method stub
switch(dir){//移动方向
case 'L':
x=x-2;
if(x<0) x+=2;break; //边界设置
case 'U':
y=y-2;
if(y<25) y+=2;break;
case 'R':
x=x+2;
if(x>950) x-=2;break;
case 'D':
y=y+2;
if(y>750) y-=2;break;
case 'S':
break;
}
}
public void keyPressed(KeyEvent e){//对键盘进行扫描
int key=e.getKeyCode();
switch(key){
case KeyEvent.VK_A:
bL=true;break;
case KeyEvent.VK_D:
bR=true;break;
case KeyEvent.VK_W:
bU=true;break;
case KeyEvent.VK_S:
bD=true;break;
}
//调用函数
dicideDirection();
}
private void dicideDirection() {//判定移动方向
// TODO Auto-generated method stub
if(bL&&!bR&&!bU&&!bD){
dir='L';//左
}
else if(!bL&&!bR&&bU&&!bD){
dir='U';//上
}
else if(!bL&&bR&&!bU&&!bD){
dir='R';//右
}
else if(!bL&&!bR&&!bU&&bD){
dir='D';//下
}
else if(!bL&&!bR&&!bU&&!bD){
dir='S';//停止
}
}
public void keyReleased(KeyEvent e){
int key=e.getKeyCode();
switch(key){
case KeyEvent.VK_A:
bL=false;break;
case KeyEvent.VK_D:
bR=false;break;
case KeyEvent.VK_W:
bU=false;break;
case KeyEvent.VK_S:
bD=false;break;
}
dicideDirection();
}
public Rectangle getRect(){
Rectangle rect=new Rectangle(x,y,WIDTH,LENGTH);
return rect;
}
public void collidewithball(ball ball){
Rectangle[] rects=ball.getRect();
for (int i = 0; i < rects.length; i++){
if(this.getRect().intersects(rects[i])){//进行比较
ball.x[i]=-1000000;
ball.y[i]=-1000000;
score+=10;
}
}
}
}
运行结果