Java编程经典小游戏设计-打砖块小游戏源码
[程序中使用的数据结构和符号说明]
hitbrick类
greenballthread控制小球路线
xup,yup,bouncing定义变量存储16位数值形式
x,y小球坐标
xdx,ydy坐标增量
max_x,max_y坐标最大值
renew初始化
label标签
rx,ry横板坐标
brick[]砖块
ball小球
hitbrick()定义小球横板及砖块位置坐标
keypressd(keyeent)定义小球启动键(按空格键启动)
keyreleased(keyevent)接收键盘事件侦听器接口)
keytyped(keyevent)键入空格键时调用keyevent
paint(graphics)对砖块填充颜色
move定义小球的运动轨迹和砖块的消失
main主函数
ballthread类
通过继承thread类使ball类线程化,并把小球的弹跳动作放进run()中执行
brick类
定义砖块坐标位置和砖块按钮
ball类
定义小球坐标位置
[程序设计流程]
程序中使用的部分方法解释
开始命令:空格键
privatejlabellabel;定义一个标签,label=newjlabel("按空格键开始");内容为空格键开始,addkeylistener(this);定义一个键盘监听器,
if (e.getkeycode() ==e.vk_space) { if(renew){ greenballthread=new ballthread(this); bouncing = true; greenballthread.start(); label.setvisible(false); } renew=false; }
重置并开始游戏
移动命令:方向键左键和右键
if(e.getkeycode()==e.vk_left){ rx=rx-20; if(bouncing){ if(rx<0){ rx=0; } } else{ if(rx<0){ rx=0; } else{ x=x-20; ball.ball_x=x; } } repaint(); }
同开始命令原理,如果键入左键,横版向左移动20个单位(rx为横板坐标),如果小球还在运动,当横板移到最左侧(rx=0),不能再向左移动,则横板靠在最左侧(rx=0),
if(e.getkeycode()==e.vk_right){ rx=rx+20; if(bouncing){ if(rx+80>300){ rx=220; } } else{ if(rx+80>300){ rx=220; } else{ x=x+20; ball.ball_x=x; } } repaint(); } }
向右移动同向左移动原理,因为定义界面横坐标最大值为300,横板长度80,故rx=220时碰最右侧
砖块设定:
brick[0]=new brick(0,60,50,20); brick[1]=new brick(50,60,50,20); brick[2]=new brick(100,60,50,20); …… brick[16]=new brick(200,160,50,20); brick[17]=new brick(250,160,50,20); ball=new ball(150,450,10,10);
public void paint(graphics g){ super.paint(g); ball.rect.setlocation(x,y); if(bouncing){ for(int i=0;i<=17;i++){ if(brick[i].visible==true){ switch(i){ case 0 :g.setcolor(color.blue); break; case 1 :g.setcolor(color.cyan); break; case 2 :g.setcolor(color.gray); break; …… case 17 :g.setcolor(color.yellow); break; } g.fill3drect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true); } } g.setcolor(color.red); g.filloval(x, y, 10, 10); g.setcolor(color.blue); g.fillrect(rx,ry,80,20);
brick[0]=newbrick(0,60,50,20);设置砖块坐标,ball=newball(150,450,10,10);和小球的坐标
if(brick[i].visible==true)判断砖块存在,用switch语句,逐个对砖块填充颜色,最后四行代码是分别对小球和横板颜色坐标的定义
小球的移动:
try{ thread.currentthread().sleep(25); } catch(interruptedexception exception){ system.err.println(exception.tostring()); }
定义小球的速度,若发生错误,则执行catch语句,打印错误
for(int i=0;i<=17;i++){ if(ball.rect.intersects(brick[i].rect)&&brick[i].visible){ brick[i].visible=false; yup=!yup;/ } }
当小球接触到砖块时,砖块不可见(消失)
if(x+5>rx&&x+5<rx+80&&y+10>=ry){ yup=false; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); }
判断小球坐标和横板坐标,当小球落在横板坐标之内,小球反弹,小球横坐标和纵坐标都以一个随机值改变后运动
if(xup==true){ x+=xdx; } else{ x-=xdx; } if(yup==true){ y+=ydy; } else{ y-=ydy; }
判断小球横坐标如果在增加,小球横坐标=小球原横坐标+小球横坐标增量,否则小球横坐标=小球原横坐标-小球横坐标增量;纵坐标同理
if(y<=0){ y=0; ball.ball_y=y; yup=true; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); } else if(y>=max_y-15){ ydy=(int)(math.random()*5+2); //yup=false; break; }
判断小球到画面顶部(定义顶部的纵坐标为0),小球向下反弹,原理同小球和横板接触的反弹规则,否则,判断小球纵坐标是否大于max_y-15(纵坐标最大值-15),反弹规则改变为横坐标不变,纵坐标随机改变
if(x<=0){ x=0; ball.ball_x=x; xup=true; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); } else if(x>=max_x-10){ x=max_x-10; ball.ball_x=x; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); xup=false; }
判断小球到画面最左侧(定义最左侧横坐标为0),向右侧反弹,反弹规则同小球和横板接触的反弹规则,或者小球到画面最右侧,向左反弹,反弹规则同上,(if(x>=max_x-10)判断小球是否到右边侧,小球的直径为10)
int i; for(i=0;i<=17&&brick[i].visible==false;i++){ } if(i==18){ break; }
如果所有砖块都不可见,则重新玩
renew=true; //初始化 bouncing=false; for(int i=0;i<=17;i++){ brick[i].visible=true; } xup=true; yup=false; xdx=1; ydy=1; x=150; y=450; rx=120; ry=460; //
重新开始,初始化,小球静止,所有砖块可见,小球在横坐标方向,可随横板移动而移动,纵坐标在未开时游戏前不能改变,定义小球横坐标和纵坐标增量都为1,小球初始位置坐标(150,450)横板初始位置坐标(120,460)
[源程序]
import java.awt.*; import javax.swing.*; import java.awt.event.*; import javax.swing.event.*; public class hitbrick extends jframe implements keylistener{ private ballthread greenballthread; //控制小球的线程 private boolean xup,yup,bouncing; private int x,y,xdx,ydy; //小球坐标,增量 private final int max_x=300,max_y=500; private boolean renew; private jlabel label; private int rx,ry; //横板坐标 private brick brick[]=new brick[18]; //砖块 private ball ball; //小球 public hitbrick(){ super("打砖块"); container pane=getcontentpane(); //设置空白面板容器 label=new jlabel("按空格键开始"); //标签 label.sethorizontalalignment(jlabel.center); //水平 label.setverticalalignment(jlabel.bottom); //垂直 pane.add(label); //向面板里添加标签 xup=true; //横坐标可以移动 yup=false; //纵坐标不可以移动 xdx=1; ydy=1; x=150; //小球坐标 y=450; rx=120; //横板坐标 ry=460; renew=true; bouncing=false; addkeylistener(this); //键盘监听器 brick[0]=new brick(0,60,50,20); //砖块坐标 brick[1]=new brick(50,60,50,20); brick[2]=new brick(100,60,50,20); brick[3]=new brick(150,60,50,20); brick[4]=new brick(200,60,50,20); brick[5]=new brick(250,60,50,20); brick[6]=new brick(0,90,50,20); brick[7]=new brick(50,110,50,20); brick[8]=new brick(100,130,50,20); brick[9]=new brick(150,130,50,20); brick[10]=new brick(200,110,50,20); brick[11]=new brick(250,90,50,20); brick[12]=new brick(0,160,50,20); brick[13]=new brick(50,160,50,20); brick[14]=new brick(100,160,50,20); brick[15]=new brick(150,160,50,20); brick[16]=new brick(200,160,50,20); brick[17]=new brick(250,160,50,20); ball=new ball(150,450,10,10); //球的坐标 setsize(max_x,max_y); //窗口大小 setresizable(false); setvisible( true ); //可视化 } public void keypressed(keyevent e) { if (e.getkeycode() ==e.vk_space) { if(renew){ greenballthread=new ballthread(this); bouncing = true; greenballthread.start(); label.setvisible(false); } renew=false; } if(e.getkeycode()==e.vk_left){ rx=rx-20; if(bouncing){ if(rx<0){ rx=0; } } else{ if(rx<0){ rx=0; } else{ x=x-20; ball.ball_x=x; } } repaint(); } if(e.getkeycode()==e.vk_right){ rx=rx+20; if(bouncing){ if(rx+80>300){ rx=220; } } else{ if(rx+80>300){ rx=220; } else{ x=x+20; ball.ball_x=x; } } repaint(); } } public void keyreleased (keyevent e) { } public void keytyped (keyevent e){ } public void paint(graphics g){ super.paint(g); ball.rect.setlocation(x,y); if(bouncing){ for (int i=0;i<=17;i++){ if(brick[i].visible==true){ switch(i){ case 0 :g.setcolor(color.blue); break; case 1 :g.setcolor(color.cyan); break; case 2 :g.setcolor(color.gray); break; case 3 :g.setcolor(color.green); break; case 4 :g.setcolor(color.magenta); break; case 5 :g.setcolor(color.yellow); break; case 6 :g.setcolor(color.white); break; case 7 :g.setcolor(color.black); break; case 8 :g.setcolor(color.orange); break; case 9 :g.setcolor(color.pink); break; case 10 :g.setcolor(color.darkgray); break; case 11 :g.setcolor(color.red); break; case 12 :g.setcolor(color.blue); break; case 13 :g.setcolor(color.cyan); break; case 14 :g.setcolor(color.gray); break; case 15 :g.setcolor(color.green); break; case 16 :g.setcolor(color.magenta); break; case 17 :g.setcolor(color.yellow); break; } g.fill3drect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true); } } g.setcolor(color.red); g.filloval(x, y, 10, 10); g.setcolor(color.blue); g.fillrect(rx,ry,80,20); } else{ for (int i=0;i<=17;i++){ switch(i){ case 0 :g.setcolor(color.blue); break; case 1 :g.setcolor(color.cyan); break; case 2 :g.setcolor(color.gray); break; case 3 :g.setcolor(color.green); break; case 4 :g.setcolor(color.magenta); break; case 5 :g.setcolor(color.yellow); break; case 6 :g.setcolor(color.white); break; case 7 :g.setcolor(color.black); break; case 8 :g.setcolor(color.orange); break; case 9 :g.setcolor(color.pink); break; case 10 :g.setcolor(color.darkgray); break; case 11 :g.setcolor(color.red); break; case 12 :g.setcolor(color.blue); break; case 13 :g.setcolor(color.cyan); break; case 14 :g.setcolor(color.gray); break; case 15 :g.setcolor(color.green); break; case 16 :g.setcolor(color.magenta); break; case 17 :g.setcolor(color.yellow); break; } g.fill3drect(brick[i].brick_x,brick[i].brick_y,brick[i].brick_width,brick[i].brick_height,true); } g.setcolor(color.red); g.filloval(x, y, 10, 10); g.setcolor(color.blue); g.fillrect(rx, ry, 80, 20); } } public void move(){ while(true){ try{ thread.currentthread().sleep(25); } catch(interruptedexception exception){ system.err.println(exception.tostring()); } for (int i=0;i<=17;i++){ if(ball.rect.intersects(brick[i].rect)&&brick[i].visible){ brick[i].visible=false; yup=!yup; //打到球不可见 } } if(x+5>rx&&x+5<rx+80&&y+10>=ry){ yup=false; xdx=(int)(math.random()*5+2); //小球坐标增量 ydy=(int)(math.random()*5+2); } if(xup==true){ x+=xdx; //小球左右移动坐标改变 } else{ x-=xdx; } if(yup==true){ y+=ydy; } else{ y-=ydy; } if(y<=0){ y=0; ball.ball_y=y; yup=true; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); } else if(y>=max_y-15){ ydy=(int)(math.random()*5+2); //yup=false; break; } if(x<=0){ x=0; ball.ball_x=x; xup=true; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); } else if(x>=max_x-10){ x=max_x-10; ball.ball_x=x; xdx=(int)(math.random()*5+2); ydy=(int)(math.random()*5+2); xup=false; } ball.rect.setlocation(ball.ball_x,ball.ball_y); repaint(); int i; //如果所有砖块都不可见 for (i=0;i<=17&&brick[i].visible==false;i++){ //则重新玩 } if(i==18){ break; } // } renew=true; //初始化 bouncing=false; for (int i=0;i<=17;i++){ brick[i].visible=true; } xup=true; yup=false; xdx=1; ydy=1; x=150; y=450; rx=120; ry=460; // repaint(); repaint(); label.setvisible(true); } public static void main(string[] args) { hitbrick mar=new hitbrick(); } } class ballthread extends thread{ private hitbrick m; ballthread(hitbrick a){ //super(); m=a; } public void run(){ m.move(); m.repaint(); } } class brick{ rectangle rect=null; //长方形对象,砖块按钮的位置和宽高 int brick_x,brick_y; //按扭的左上角坐标 int brick_width,brick_height; //按扭的宽和高 boolean visible; public brick(int x,int y,int w,int h) { brick_x=x; brick_y=y; brick_width=w; brick_height=h; visible=true; rect=new rectangle(x,y,w,h); //创建长方形对象---砖块按钮的位置和宽高。 } } class ball{ rectangle rect=null; int ball_x,ball_y; int ball_width,ball_height; public ball(int x,int y,int w,int h){ ball_x=x; ball_y=y; ball_width=w; ball_height=h; rect=new rectangle(x,y,w,h); } }
运行结果:
空格键开始,方向键控制左右,死亡重新开始。
虽然系统的基本功能都已实现,但还是存在系统不稳定等多个bug尚待解决。在做系统的过程中遇到了很多问题,有的是知识存储不足,有的是考虑不够周全,所以学习之路永无止境。作为一个程序编程人员,要保持清醒的头脑,以现实为依据,让自己的每一行代码都能实现自己的意义。
总结
以上就是本文关于java编程经典小游戏设计-打砖块小游戏源码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:javaweb项目中dll文件动态加载方法解析(详细步骤)、等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!