java实现熊猫闯关小游戏
游戏规则:熊猫在冰雪世界向前走。遇见怪兽时鼠标点击左键跳跃,若成功避开怪兽,则游戏继续,若与怪兽相撞,则游戏结束。
下面贴出实现效果图:
游戏开始后效果:
下面介绍实现思路:
首先需要图片素材。熊猫的走动,狼和怪兽,鸟的走动都是以多副图片不断循环播放实现的。
用两张连续的背景图片依次向左移动实现背景图片的移动,如果运行程序的话,可以发现,其实熊猫原地不动,即熊猫相对于窗口的位置并不改变,是通过背景图片左移来实现熊猫向前走的效果的。假设窗口宽是1280像素,那么第一张背景图片左边界从窗口0像素起,第二张背景图片从1280像素位置起,同时向左移动,而此时熊猫只要原位置不断循环图片就可以了。
狼和怪兽是相对于窗口移动的,运行游戏同样可以发现,狼从窗口右侧出现,从左侧消失,就能看出狼是确实移动的。怎么实现不断有狼跑向熊猫呢?通过改变狼的位置。狼从右侧窗口出现到从左侧窗口消失时,其实并没有“消失”,它只是改变了位置,又重新回到了起点,然后重新从窗口右侧跑向左侧。
考虑到个人美工能力。这里贴出实现熊猫等动物动作的连续图片。注意图片顺序。
下面给出游戏结构图解:
下面分别给出代码:
鸟:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Bird { int x; int y; Image[] bird; public Bird(){ x=1280; y=50; bird=new Image[3]; for(int i=0;i<bird.length;i++){ bird[i]=new ImageIcon("Images02/enemy4-sheet"+i+".png").getImage(); } } }
Gold(金币):
package day02; import java.awt.Image; import java.util.Random; import javax.swing.ImageIcon; public class Gold { int x; int y; int width; int height; Image gold; Random r; public Gold(){ //金币 width=34; height=34; r=new Random(); x=r.nextInt(1280); y=300; gold=new ImageIcon("Images02/coin-sheet0.png").getImage(); } public void move(){ x=x-3; if(x<-17){ x=1280; } } public boolean score(Pander pander){//得分 如何得到熊猫移动的y? if(pander.y+pander.height>300&&pander.y+pander.height<334){ //if(pander.y>500){ if(pander.x+pander.width>x&&pander.x<x+width){ return true; } } return false; } }
Monster:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Monster { int x; int y; int j; int width; Image[] monster; public Monster(){ x=2500; y=520; width=180; monster=new Image[8]; for(int i=0;i<monster.length;i++){ monster[i]=new ImageIcon("Images02/怪兽"+(i+1)+".png").getImage(); } } public void move(){ x=x-10;//改变速度 if(x<-130){ x=2500; //狼的是从1500处开始 , 与狼的位置时间错开 } } //定义判断碰撞方法 public boolean hit(Pander pander){ if(pander.y+pander.height>y){ if(pander.x+pander.width>x&&pander.x<x+width){ return true; } } return false; } }
Mypanel:
package day02; import java.awt.Graphics; import java.awt.Image; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.ImageIcon; import javax.swing.JPanel; public class MyPanel extends JPanel { // extends 继承 // 自己创建的Mypanel类继承了系统中JPanel的功能,可更改其中的功能 Snow[] xueHua; Image blackGround; Pander pander; Wolf lang; // 狼 Monster guaiShou; // 怪兽 Bird niao; // 鸟 Sign sg; Gold[] jinBi; Image startimg; Image overimg; // 游戏状态 int state = 0; public static final int START = 0; public static final int RUNNING = 1; public static final int GAMEOVER = 2; public MyPanel() { startimg = new ImageIcon("Images02/btnplay-sheet0.png").getImage(); // 开始按钮图片赋给startimg overimg = new ImageIcon("Images02/btnrestart-sheet0.png").getImage();// 循环按钮赋给overimg blackGround = new ImageIcon("Images02/背景.jpg").getImage();// 底层背景 pander = new Pander(); lang = new Wolf(); // 狼 guaiShou = new Monster(); niao = new Bird(); sg = new Sign(); // 上层图片背景 jinBi = new Gold[5]; { for (int i = 0; i < 5; i++) { jinBi[i] = new Gold(); } } xueHua = new Snow[30];// for中不是已经有new了么?此处为什么还要加 for (int i = 0; i < 30; i++) { xueHua[i] = new Snow(); } } // MyPanel int index = 0; int x = 0; public void paint(Graphics g) {// g为变量名 Graphics是数据类型 作为一个画图的工具 super.paint(g);// super相当于父类 用父类的画笔功能 if (x < -1280) { x = 0; } g.drawImage(blackGround, x + 0, 0, null);// 画第一张背景图 g.drawImage(blackGround, x + 1280, 0, null);// 画第二张背景图 g.drawImage(lang.wolf[index % 6], lang.x, lang.y, null); g.drawImage(niao.bird[index % 3], niao.x + x, niao.y, null); g.drawImage(guaiShou.monster[(index / 2) % 2], guaiShou.x, guaiShou.y, null); g.drawImage(pander.pimg[(index / 2) % 4], pander.x, pander.y, null);// 为什么放null? // %8取余,余数范围0-7 // index/2??? for (int i = 0; i < 30; i++) { // 画雪花 g.drawImage(xueHua[i].snow, xueHua[i].x, xueHua[i].y, this); } for (int i = 0; i < 5; i++) { // 画金币 g.drawImage(jinBi[i].gold, jinBi[i].x, jinBi[i].y, this); } index++; // 实现角色图片更换 x -= 3; // 这里实现背景图片左移 switch (state) { case START: g.drawImage(sg.sign, sg.x, sg.y, null); g.drawImage(startimg, 550, 525, null); break; case GAMEOVER: g.drawImage(sg.sign, sg.x, sg.y, null); g.drawImage(overimg, 550, 525, null); break; } } // paint() // 定义一个执行的方法 public void action() throws Exception { // 匿名内部类 需加; // 创建鼠标监听器 Listener:监听器 Adapter:适配器 // 监听器需要5种全列出 适配器只需列出需要的 MouseListener l = new MouseAdapter() { public void mousePressed(MouseEvent e) { switch (state) { case START: state = RUNNING; break; case RUNNING: // 熊猫跳 if (pander.y == 570) { // 鼠标在跳起过程中不能点击 pander.jump(); } break; case GAMEOVER: state = RUNNING; pander.y = 570; lang = new Wolf(); guaiShou = new Monster(); break; } // switch }// mousePressed }; // mouseListener this.addMouseListener(l); // 为当前面板添加鼠标监听 while (true) { switch (state) { case START: { break; } case RUNNING: // 熊猫进行移动 pander.pstep(); lang.move(); guaiShou.move(); for (int i = 0; i < 5; i++) { jinBi[i].move(); } // 熊猫下落边界 if (pander.y >= 570) { pander.y = 570; } for (int i = 0; i < 5; i++) { if (jinBi[i].score(pander)) {// 无法在数组类型中调用?? // 此处实现金币消失 jinBi[i].x = -900; // 让金币的位置移动到窗口外,达到金币消失的效果 jinBi[i].y = -900; System.out.println("得分" + i); } } // 判断碰撞 if (lang.hit(pander) || guaiShou.hit(pander)) { // System.out.println("撞到了狼!"); state = GAMEOVER; } break; case GAMEOVER: { break; } } for (int i = 0; i < 30; i++) { xueHua[i].move(); } repaint();// 重新画 ,刷新 Thread.sleep(50); } // 对应while } } // 金币只有在首次会出现,循环再次玩时没有金币出现????
Pander:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Pander { int x; int y; Image[] pimg;//锟斤拷锟斤拷没锟斤拷(锟斤拷锟叫伙拷锟藉功锟斤拷 锟斤拷锟斤拷 ) pimg锟斤拷锟斤拷 double g;//锟斤拷锟斤拷锟斤拷锟劫讹拷 double t; double v; double v0; double vs; double s; int width; int height; public Pander(){ //自由落体运动 g=2.2; //加速度 t=1.1; //时间 v=0; //实时速度 s=0; //位移 v0=0; //初速度 vs=40; width=60; height=98; x=300; y=570; pimg =new Image[4]; for(int i=0;i<pimg.length;i++){ pimg[i]=new ImageIcon("Images02/熊猫0"+i+".png").getImage(); } } public void pstep(){ s=v0*t-(g*t*t/2); v=v0-g*t; v0=v; y=(int)(y-s); } public void jump(){ v0=vs; System.out.println(vs); } }
Road:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Road { int x; int y; Image road; public void move() { //背景图片向右移动,熊猫角色原地改变图片 x = x + 2; if (x > 1280) { x = 0; } } public Road() { x = 0; y = 620; road = new ImageIcon("Images02/路.jpg").getImage(); } }
Sign:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Sign { int x; int y; Image sign; public Sign() { x = 118; y = 15; sign = new ImageIcon("Images02/冰雪大作战.jpg").getImage(); } }
Snow:
package day02; import java.awt.Image; import java.util.Random; import javax.swing.ImageIcon; //属性-本身具有的(声明变量) public class Snow { int x; int y; int xStep; int yStep; Image snow; Random r;// 随机 // 方法-能做什么 public void move() { y += yStep; x += xStep; xStep = xStep * -1;// 使雪左右移动 if (y > 620) {// 触底反弹 y = 0; } // } } // 构造方法-初始化属性使用的(给变量赋值) 不能在声明时给变量赋值么? public Snow() { r = new Random(); xStep = 1; yStep = 2; x = r.nextInt(1280); y = 0 -r.nextInt(720);// 从屏幕上端开始出现雪花 snow = new ImageIcon("Images02/snow-sheet0.png").getImage(); } }
Wolf:
package day02; import java.awt.Image; import javax.swing.ImageIcon; public class Wolf { int x; int y; Image[] wolf; int width; public Wolf() { x = 1500; y = 585; width = 93; wolf = new Image[6]; for (int i = 0; i < wolf.length; i++) { wolf[i] = new ImageIcon("Images02/狗" + (i + 1) + ".png").getImage(); } } public void move() { //窗口宽度是1280 , 让狼从1500出向左走,走出窗口时又回到1500处 x = x - 10; if (x < -45) { x = 1500; } } // 定义判断碰撞方法 public boolean hit(Pander pander) { if (pander.y + pander.height > y) { if (pander.x + pander.width > x && pander.x < x + width) { return true; } } return false; } }
World:
package day02; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; public class world { /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub JFrame f00 = new JFrame(); f00.setSize(1280, 720); f00.setTitle("熊猫大战冰雪世界"); f00.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); MyPanel p00 = new MyPanel(); f00.add(p00); f00.setVisible(true); int i = 0; p00.action(); } }
游戏到此就完成了。
这个游戏是我朋友所写,并非本人。特此声明。